static void _LNK_CONV PipeThread(void *p) { GPipe *pipe = (GPipe *)p; int rc; ULONG ulPostCount; ULONG used; PID pid; HPIPE hfPipe; RESULTCODES rc_code; rc = CreatePipeChild(pid, hfPipe, pipe->Command); if (rc != 0) { // fprintf(stderr, "Failed createpipe"); DosRequestMutexSem(pipe->Access, SEM_INDEFINITE_WAIT); pipe->reading = 0; DosPostEventSem(pipe->NewData); DosReleaseMutexSem(pipe->Access); return; } // fprintf(stderr, "Pipe: Begin: %d %s\n", pipe->id, Args); while (1) { // fprintf(stderr, "Waiting on pipe\n"); // fread(pipe->buffer, 1, pipe->buflen, fp); rc = DosRead(hfPipe, pipe->buffer, pipe->buflen, &used); if (rc < 0) used = 0; DosRequestMutexSem(pipe->Access, SEM_INDEFINITE_WAIT); // fprintf(stderr, "Waiting on mutex\n"); pipe->bufused = used; // fprintf(stderr, "Pipe: fread: %d %d\n", pipe->id, pipe->bufused); DosResetEventSem(pipe->ResumeRead, &ulPostCount); if (pipe->bufused == 0) break; if (pipe->notify) { DosPostEventSem(pipe->NewData); pipe->stopped = 0; } DosReleaseMutexSem(pipe->Access); if (pipe->DoTerm) break; // fprintf(stderr, "Waiting on sem\n"); DosWaitEventSem(pipe->ResumeRead, SEM_INDEFINITE_WAIT); // fprintf(stderr, "Read: Released mutex\n"); if (pipe->DoTerm) break; } DosClose(hfPipe); // fprintf(stderr, "Pipe: pClose: %d\n", pipe->id); rc = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &rc_code, &pid, pid); pipe->RetCode = rc_code.codeResult; // pclose(fp); pipe->reading = 0; DosPostEventSem(pipe->NewData); DosReleaseMutexSem(pipe->Access); // fprintf(stderr, "Read: Released mutex\n"); }
FILE* file_popen(const char *cmd, const char *mode) { const char* comspec; char* commandBuffer; char* stderr_to_stdout; int redirectStderr = 0; HANDLE child; HANDLE hIn = INVALID_HANDLE_VALUE, hOut = INVALID_HANDLE_VALUE, hErr = INVALID_HANDLE_VALUE; int rc; FILE* file; int isCmd; if (!mode || !*mode || (mode[0] != 'r' && mode[0] != 'w')) return NULL; comspec = getenv("COMSPEC"); if (!comspec) comspec = "cmd"; commandBuffer = (char*)malloc(strlen(comspec) + 4 + strlen(cmd) + 2 + 1); strcpy(commandBuffer, comspec); strcat(commandBuffer, " /c "); strlwr(commandBuffer); isCmd = strstr(commandBuffer, "cmd.exe") != NULL; if (isCmd) strcat(commandBuffer, "\""); strcat(commandBuffer, cmd); if (isCmd) strcat(commandBuffer, "\""); stderr_to_stdout = strstr(commandBuffer, "2>&1"); if (stderr_to_stdout) { stderr_to_stdout[0] = stderr_to_stdout[1] = stderr_to_stdout[2] = stderr_to_stdout[3] = ' '; redirectStderr = 1; } rc = CreatePipeChild(&child, &hIn, &hOut, &hErr, redirectStderr, commandBuffer); free(commandBuffer); if (rc == -1) { return NULL; } if (mode[0] == 'r') { file = _fdopen(_open_osfhandle((intptr_t)hOut, _O_RDONLY | _O_TEXT), "rt"); if (hIn != INVALID_HANDLE_VALUE) CloseHandle(hIn); if (hErr != INVALID_HANDLE_VALUE) CloseHandle(hErr); } else { file = _fdopen(_open_osfhandle((intptr_t)hIn, _O_WRONLY | _O_TEXT), "wt"); if (hOut != INVALID_HANDLE_VALUE) CloseHandle(hOut); if (hErr != INVALID_HANDLE_VALUE) CloseHandle(hErr); } setvbuf(file, NULL, _IONBF, 0); CloseHandle(child); return file; }