float* loadMatrix(const char* filename, size_t height, size_t width) { int fd = safeOpen(filename, O_RDONLY); size_t count = width * height; float* buf = (float*) malloc(sizeof(float)*count); ssize_t num = safeRead(fd, buf, count, "load matrix"); close(fd); return buf; }
void _fileCopy(FILE* fOut, FILE* fIn, u32 n, char filtering) { #ifndef DOS_16 #define BLOCK 64*1024 #else #define BLOCK 1*1024 #endif if (!IoBuF) { IoBuF = (char*) xmalloc(BLOCK); } while (n > BLOCK) { safeRead(IoBuF, fIn, BLOCK); if (filtering) filter(IoBuF, BLOCK); safeWrite(fOut, IoBuF, BLOCK); n -= BLOCK; } safeRead(IoBuF, fIn, n); if (filtering) filter(IoBuF, n); safeWrite(fOut, IoBuF, n); }
//note: allocates R, ri void loadRBC( matrix *R, rep **ri, char* filename ){ size_t i; unint nr, len, plen; FILE *fp = fopen(filename, "rb"); if( !fp ){ fprintf(stderr, "unable to open output file\n"); exit(1); } safeRead( &nr, sizeof(unint), 1, fp ); (*ri) = (rep*)calloc( CPAD(nr), sizeof(rep) ); for( i=0; i<nr; i++ ){ safeRead( &len, sizeof(unint), 1, fp ); plen = CPAD( len ); (*ri)[i].lr = (unint*)calloc( plen, sizeof(unint) ); (*ri)[i].dists = (real*)calloc( plen, sizeof(real) ); (*ri)[i].len = len; safeRead( (*ri)[i].lr, sizeof(unint), len, fp ); safeRead( (*ri)[i].dists, sizeof(real), len, fp ); safeRead( &((*ri)[i].start), sizeof(unint), 1, fp ); safeRead( &((*ri)[i].radius), sizeof(real), 1, fp ); } unint r,c; safeRead( &r, sizeof(unint), 1, fp ); safeRead( &c, sizeof(unint), 1, fp ); initMat( R, r, c ); R->mat = (real*)calloc( sizeOfMat(*R), sizeof(real) ); safeRead( R->mat, sizeof(real), sizeOfMat(*R), fp ); fclose(fp); }
int sendEmail(const int socketFd, const unsigned char *fromMail, const unsigned char *toMail, const unsigned char *textMail, const int textLen) { char readData[SMTP_MTU] = {0}; char writeData[SMTP_MTU] = {0}; /* Send: MAIL FROM */ memset(&writeData, 0, SMTP_MTU); sprintf(writeData, "MAIL FROM: <%s>\r\n", fromMail); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: MAIL FROM */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: RCPT TO */ memset(&writeData, 0, SMTP_MTU); sprintf(writeData, "RCPT TO: <%s>\r\n", toMail); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: RCPT TO */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: DATA */ memset(&writeData, 0, SMTP_MTU); safeWrite(socketFd, "DATA\r\n", strlen("DATA\r\n")); /* Recv: DATA */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: MAIL TEXT */ safeWrite(socketFd, textMail, textLen); /* Recv: MAIL TEXT */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: QUIT */ memset(&writeData, 0, SMTP_MTU); safeWrite(socketFd, "QUIT\r\n", strlen("QUIT\r\n")); /* Recv: QUIT */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); return 0; }
int authEmail(const int socketFd, const unsigned char *mailAddr, const unsigned char *mailPasswd) { int outSize = 0, stringLen; char readData[SMTP_MTU] = {0}; char writeData[SMTP_MTU] = {0}; char userName[MAX_EMAIL_LEN] = {0}; char userPasswd[MAX_EMAIL_LEN] = {0}; memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); /* Send: EHLO */ safeWrite(socketFd, "EHLO Here\r\n", strlen("EHLO Here\r\n")); /* Recv: EHLO */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: AUTH LOGIN */ safeWrite(socketFd, "AUTH LOGIN\r\n", strlen("AUTH LOGIN\r\n")); /* Recv: AUTH LOGIN */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: username */ memset(&userName, 0, MAX_EMAIL_LEN); memset(&writeData, 0, SMTP_MTU); stringCut((unsigned char*)mailAddr, NULL, "@", userName); outSize = BASE64_SIZE(strlen(userName)); base64_encode(writeData, outSize, userName, strlen(userName)); strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: username */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: passwd */ memset(&userPasswd, 0, MAX_EMAIL_LEN); strcpy(userPasswd, mailPasswd); memset(&writeData, 0, SMTP_MTU); outSize = BASE64_SIZE(strlen(userPasswd)); base64_encode(writeData, outSize, userPasswd, strlen(userPasswd)); strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: passwd */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); return 0; }
int sendEmail(const ACE_HANDLE socketFd, const unsigned char *fromMail, const unsigned char *toMail, const unsigned char *textMail, const int textLen) { char readData[SMTP_MTU] = {0}; char writeData[SMTP_MTU] = {0}; /* Send: MAIL FROM */ ACE_OS::memset(&writeData, 0, SMTP_MTU); ACE_OS::sprintf(writeData, "MAIL FROM: <%s>\r\n", fromMail); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: MAIL FROM */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: RCPT TO */ ACE_OS::memset(&writeData, 0, SMTP_MTU); ACE_OS::sprintf(writeData, "RCPT TO: <%s>\r\n", toMail); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: RCPT TO */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: DATA */ ACE_OS::memset(&writeData, 0, SMTP_MTU); char szDATA[50] = {'\0'}; ACE_OS::sprintf(szDATA, "DATA\r\n"); safeWrite(socketFd, szDATA, ACE_OS::strlen("DATA\r\n")); /* Recv: DATA */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: MAIL TEXT */ safeWrite(socketFd, (char* )textMail, textLen); /* Recv: MAIL TEXT */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: QUIT */ ACE_OS::memset(&writeData, 0, SMTP_MTU); char szQUIT[50] = {'\0'}; ACE_OS::sprintf(szQUIT, "QUIT\r\n"); safeWrite(socketFd, szQUIT, ACE_OS::strlen("QUIT\r\n")); /* Recv: QUIT */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); recvStatus(readData); return 0; }
int authEmail(const ACE_HANDLE socketFd, const unsigned char *mailAddr, const unsigned char *mailPasswd) { int outSize = 0; char readData[SMTP_MTU] = {0}; char writeData[SMTP_MTU] = {0}; char userName[MAX_EMAIL_LEN] = {0}; char userPasswd[MAX_EMAIL_LEN] = {0}; ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); /* Send: EHLO */ char szRELO[50] = {'\0'}; ACE_OS::sprintf(szRELO, "EHLO Here\r\n"); safeWrite(socketFd, szRELO, ACE_OS::strlen("EHLO Here\r\n")); /* Recv: EHLO */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: AUTH LOGIN */ char szLOGIN[50] = {'\0'}; ACE_OS::sprintf(szLOGIN, "AUTH LOGIN\r\n"); safeWrite(socketFd, szLOGIN, ACE_OS::strlen("AUTH LOGIN\r\n")); /* Recv: AUTH LOGIN */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: username */ ACE_OS::memset(&userName, 0, MAX_EMAIL_LEN); ACE_OS::memset(&writeData, 0, SMTP_MTU); stringCut((unsigned char*)mailAddr, NULL, (char* )"@", userName); outSize = BASE64_SIZE(strlen(userName)); base64_encode(writeData, outSize, (const unsigned char *)userName, strlen(userName)); ACE_OS::strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: username */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: passwd */ ACE_OS::memset(&userPasswd, 0, MAX_EMAIL_LEN); ACE_OS::strcpy((char* )userPasswd, (char* )mailPasswd); ACE_OS::memset(&writeData, 0, SMTP_MTU); outSize = BASE64_SIZE(strlen(userPasswd)); base64_encode(writeData, outSize, (const unsigned char *)userPasswd, strlen(userPasswd)); ACE_OS::strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: passwd */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); return 0; }
int main(int argc,char** argv) { char pm, operation=-1, found=1, pw1[128], pw2[128], ae1[15], ae2[15]; u32 i; PK0102 ce; PK0304 le; PK0506 ed; for (pm=1; pm < argc; pm++) { char opt; if (argv[pm][0] != '/') continue; if (argv[pm][1] == '?') { printf( "Encrypts or decrypts an archive following WinZip(R) 9 specifications.\n\n" \ "ZAES /D | /E:keysize [/2] archive.zip\n\n" \ " /D decrypts AES encrypted entries\n" \ " /E:keysize encrypts with 128, 192 or 256-bit keys (keysize 1, 2 or 3)\n" \ " /2 AE-2 format (sets CRC-32 to zero)\n"); return 1; } opt = toupper(argv[pm][1]); if (opt== 'E') { Mode = atol(&argv[pm][3]); operation = 0; filter = encrypt_authenticate; if (Mode < 1 || Mode > 3) Z_ERROR("Bad encryption mode specified!"); SaltSize = KS[Mode].Salt; KeySize = KS[Mode].Key; found++; continue; } if (opt== 'D') { operation = 1; filter = authenticate_decrypt; found++; continue; } if (opt== '2') { AE2 = 1; found++; printf("WARNING: according to AE-2 specifications, CRC-32 will be set to zero\n"\ "in encrypted entries. Reverting to original archive after decryption will\n"\ "be impossible with this utility!\n"); continue; } } argv+=found; argc-=found; if (operation == -1) Z_ERROR("You must specify /E or /D switch!\nTry ZAES /?"); if (argc < 1) Z_ERROR("You must give a ZIP archive to process!"); register_prng(&sprng_desc); register_cipher(&aes_desc); register_hash(&sha1_desc); //~ printf("DEBUG: sha1 id=%d, aes id=%d\n", find_hash("sha1"), find_cipher("aes")); if ( (ZIN=fopen(argv[0],"rb")) == 0 || (ZIN2=fopen(argv[0],"rb")) == 0 ) Z_ERROR("Can't open input ZIP archive"); if ( (ZOUT=topen(ae1)) == 0 || (ZTMP=topen(ae2)) == 0) Z_ERROR("Can't open temporary output files"); setvbuf(ZIN , 0, _IOFBF, BLOCK); setvbuf(ZOUT, 0, _IOFBF, BLOCK); /* assumiamo uno ZIP senza commento! */ fseek(ZIN2,-22,SEEK_END); safeRead(&ed, ZIN2, sizeof(PK0506)); if (ed.Sig != 0x06054B50) #ifdef HANDLE_COMMENT { fseek(ZIN2, -0xFFFF, SEEK_END); fread(p, 1, 4, ZIN2); #else Z_ERROR("End directory marker not found!"); #endif /* verifica un minimo di coerenza nella ENDDIR */ if (ed.Disk != 0) Z_ERROR("Can't process a spanned archive"); while(1) { printf("Enter password: "******"\rFor your safety, please use a password of 8 characters or more.\n"); continue; } if (operation) { printf("\n"); break; } printf("\rVerify password: "******"Passwords don't match!\n"); continue; } printf("\n"); break; } #define PUTN(x) { fileCopy(stdout, ZIN, x.NameLen); fseek(ZIN, -x.NameLen, SEEK_CUR); } fseek(ZIN2, ed.Offset, SEEK_SET); for (i=0; i < ed.Total; i++) { safeRead(&ce, ZIN2, sizeof(PK0102)); if (ce.Sig != 0x02014B50) Z_ERROR("Expected central directory marker not found"); /* Assume i dati corretti dalla LE */ fseek(ZIN, ce.Offset, SEEK_SET); safeRead(&le, ZIN, sizeof(PK0304)); if (le.Sig != 0x04034B50) Z_ERROR("Expected local entry marker not found"); if ( ((le.Flag & 1) && !operation) || /* doesn't encrypt already encrypted */ (!(le.Flag & 1) && operation) || /* doesn't decrypt already decrypted */ ((le.Flag & 1) && operation && le.CompMethod != 99) || /* doesn't decrypt not AES encrypted */ !le.CompSize ) { ce.Offset = ftell(ZOUT); safeWrite(ZOUT, &le, sizeof(PK0304)); printf(" copying: "); PUTN(le); fileCopy(ZOUT, ZIN, le.NameLen+le.ExtraLen+le.CompSize); printf("\n"); safeWrite(ZTMP, &ce, sizeof(PK0102)); fileCopy(ZTMP, ZIN2, ce.NameLen+ce.ExtraLen); continue; } if (!operation) { AE_EXTRA ae = {0x9901, 7, AE2+1, 0x4541, Mode, 0}; ae.CompMethod = ce.CompMethod; ce.CompMethod = 99; if (AE2) ce.Crc32 = 0; ce.Flag |= 1; ce.ExtraLen += 11; ce.CompSize += SaltSize + 12; /* variable salt, fixed password check and hmac */ ce.Offset = ftell(ZOUT); safeWrite(ZTMP, &ce, sizeof(PK0102)); fileCopy(ZTMP, ZIN2, ce.NameLen+ce.ExtraLen-11); safeWrite(ZTMP, &ae, 11); printf(" encrypting: "); PUTN(le); Encrypt(&le, &ae, pw1); printf("\n"); } else { ce.Offset = ftell(ZOUT); printf(" decrypting: "); PUTN(le); Decrypt(&le, pw1); /* Decrypts contents */ printf("\n"); ce.CompMethod = le.CompMethod; if (AE2) ce.Crc32 = 0; ce.Flag ^= 1; ce.ExtraLen -= 11; ce.CompSize = le.CompSize; safeWrite(ZTMP, &ce, sizeof(PK0102)); /* Copy the extra data (may be LE != CE) */ fileCopy(ZTMP, ZIN2, ce.NameLen); for(ce.ExtraLen+=11; ce.ExtraLen;) { u16 u[2]; safeRead(u, ZIN2, 4); ce.ExtraLen -= (4 + u[1]); if (u[0] == 0x9901) { fseek(ZIN2, u[1], SEEK_CUR); continue; } safeWrite(ZTMP, u, 4); fileCopy(ZTMP, ZIN2, u[1]); } } } ed.Offset = ftell(ZOUT); /* new central directory start */ ed.Size = ftell(ZTMP); /* new central directory size */ fseek(ZTMP, 0, SEEK_SET); fclose(ZIN); fclose(ZIN2); /* Copies central directory */ fileCopy(ZOUT, ZTMP, ed.Size); safeWrite(ZOUT, &ed, sizeof(PK0506)); fclose(ZTMP); fclose(ZOUT); remove(ae2); if (remove(argv[0])) { printf("Can't remove old archive; new one is in file '%s'\n", ae1); } else if (rename(ae1, argv[0])) { printf("Can't rename old archive; new one is in file '%s'\n", ae1); } memset(&BUF, 0, sizeof(BUF)); memset(&ctr, 0, sizeof(ctr)); memset(pw1, 0, 128); memset(pw2, 0, 128); return 0; }
void Decrypt(PK0304 *le, char *password) { char *salt, *key1, *key2, *check, digest[40]; u32 key_len, dig_len = 40, start, xlen; AE_EXTRA ae; start = ftell(ZIN); /* Searches for AE-1 header */ fseek(ZIN, le->NameLen, SEEK_CUR); for(xlen=le->ExtraLen; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } fseek(ZIN, ae.Size, SEEK_CUR); } if (ae.Sig != 0x9901) Z_ERROR("Fatal! Can't find AE extra header!"); if (ae.Strength < 1 || ae.Strength > 3) Z_ERROR("Bad encryption strength"); SaltSize = KS[ae.Strength].Salt; KeySize = KS[ae.Strength].Key; salt = BUF; key1 = salt+SaltSize; key2 = key1+KeySize; check = key2+KeySize; key_len = KeySize*2+2; /* Loads salt and password check value, and regenerates original crypto material */ fseek(ZIN, start+le->NameLen+le->ExtraLen, SEEK_SET); safeRead(salt, ZIN, SaltSize); safeRead(check+2, ZIN, 2); point1: if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK) Z_ERROR("Failed to derive encryption keys"); if (memcmp(check, check+2, 2)) { printf("\nCan't decrypt data: try another password.\nNew password: "******"\n"); goto point1; } if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK) Z_ERROR("Failed to setup AES CTR decoder"); #ifdef GLADMAN_HMAC hmac_sha1_begin(&hmac); hmac_sha1_key(key2, KeySize, &hmac); #else if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK) Z_ERROR("Failed to setup HMAC-SHA1"); #endif /* Adjusts local header */ le->Flag ^= 1; le->CompMethod = ae.CompMethod; le->ExtraLen -= 11; le->CompSize -= (SaltSize + 12); /* Writes local header and copies extra, except 0x9901 */ safeWrite(ZOUT, le, sizeof(PK0304)); fseek(ZIN, start, SEEK_SET); fileCopy(ZOUT, ZIN, le->NameLen); for(xlen=le->ExtraLen+11; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } safeWrite(ZOUT, &ae, 4); fileCopy(ZOUT, ZIN, ae.Size); } fseek(ZIN, SaltSize+2, SEEK_CUR); fileFilter(ZOUT, ZIN, le->CompSize); #ifdef GLADMAN_HMAC hmac_sha1_end(digest, dig_len, &hmac); #else if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK) Z_ERROR("Failed to computate HMAC"); #endif /* Retrieves and checks HMACs */ safeRead(digest+10, ZIN, 10); if (memcmp(digest, digest+10, 10)) printf(" authentication failed, contents were lost!"); ctr_done(&ctr); }
/* Python's implementation of Popen forks back to python before execing. * Forking a python proc is a very complex and volatile process. * * This is a simpler method of execing that doesn't go back to python after * forking. This allows for faster safer exec. * * return NULL on error and sets the python error accordingly. */ static PyObject * createProcess(PyObject *self, PyObject *args) { int cpid; int deathSignal = 0; int rv; int outfd[2] = {-1, -1}; int in1fd[2] = {-1, -1}; int in2fd[2] = {-1, -1}; int errnofd[2] = {-1, -1}; int childErrno = 0; PyObject* pyArgList; PyObject* pyEnvList; const char* cwd; int close_fds = 0; char** argv = NULL; char** envp = NULL; if (!PyArg_ParseTuple(args, "O!iiiiiiizOi:createProcess;", &PyList_Type, &pyArgList, &close_fds, &outfd[0], &outfd[1], &in1fd[0], &in1fd[1], &in2fd[0], &in2fd[1], &cwd, &pyEnvList, &deathSignal)) { return NULL; } argv = pyListToArray(pyArgList, 1); if (!argv) { goto fail; } if (PyList_Check(pyEnvList)) { envp = pyListToArray(pyEnvList, 0); if (!envp) { goto fail; } } if(pipe(errnofd) < 0) { PyErr_SetFromErrno(PyExc_OSError); goto fail; } try_fork: cpid = fork(); if (cpid < 0) { if (errno == EAGAIN || errno == EINTR ) { goto try_fork; } PyErr_SetFromErrno(PyExc_OSError); goto fail; } if (!cpid) { safeClose(0); safeClose(1); safeClose(2); dup2(outfd[0], 0); dup2(in1fd[1], 1); dup2(in2fd[1], 2); safeClose(outfd[0]); safeClose(outfd[1]); safeClose(in1fd[0]); safeClose(in1fd[1]); safeClose(in2fd[0]); safeClose(in2fd[1]); safeClose(errnofd[0]); if (deathSignal) { childErrno = prctl(PR_SET_PDEATHSIG, deathSignal); if (childErrno < 0) { childErrno = errno; } /* Check that parent did not already die between fork and us * setting the death signal */ if (write(errnofd[1], &childErrno, sizeof(int)) < sizeof(int)) { exit(-1); } if (childErrno != 0) { exit(-1); } } if (setCloseOnExec(errnofd[1]) < 0) { goto sendErrno; } if (close_fds) { closeFDs(errnofd[1]); } if (cwd) { if (chdir(cwd) < 0) { goto sendErrno; } setenv("PWD", cwd, 1); } exec: if (envp) { execvpe(argv[0], argv, envp); } else { execvp(argv[0], argv); } if (errno == EINTR || errno == EAGAIN ) { goto exec; } sendErrno: if (write(errnofd[1], &errno, sizeof(int)) < 0) { exit(errno); } exit(-1); } safeClose(errnofd[1]); errnofd[1] = -1; if (deathSignal) { /* death signal sync point */ rv = safeRead(errnofd[0], &childErrno, sizeof(int)); if (rv != sizeof(int)) { PyErr_SetFromErrno(PyExc_OSError); goto fail; } else if (childErrno != 0) { PyErr_SetString(PyExc_OSError, strerror(childErrno)); goto fail; } } /* error sync point */ rv = safeRead(errnofd[0], &childErrno, sizeof(int)); if (rv == sizeof(int)) { PyErr_SetString(PyExc_OSError, strerror(childErrno)); goto fail; } else if (rv < 0) { PyErr_SetFromErrno(PyExc_OSError); goto fail; } safeClose(errnofd[0]); errnofd[0] = -1; /* From this point errors shouldn't occur, if they do something is very * very very wrong */ freeStringArray(argv); if (envp) { freeStringArray(envp); } return Py_BuildValue("(iiii)", cpid, outfd[1], in1fd[0], in2fd[0]); fail: if (argv) { freeStringArray(argv); } if (envp) { freeStringArray(envp); } if (errnofd[0] >= 0) { safeClose(errnofd[0]); } if (errnofd[1] >= 0) { safeClose(errnofd[1]); } return NULL; }