/* * @implemented */ FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */ { _TCHAR *szCmdLine=NULL; _TCHAR *szComSpec=NULL; _TCHAR *s; FILE *ret; HANDLE hReadPipe, hWritePipe; BOOL result; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; struct popen_handle *container; DWORD i; TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md); if (cm == NULL) return NULL; szComSpec = _tgetenv(_T("COMSPEC")); if (szComSpec == NULL) { szComSpec = _T("cmd.exe"); } s = max(_tcsrchr(szComSpec, '\\'), _tcsrchr(szComSpec, '/')); if (s == NULL) s = szComSpec; else s++; szCmdLine = malloc((_tcslen(s) + 4 + _tcslen(cm) + 1) * sizeof(_TCHAR)); if (szCmdLine == NULL) { return NULL; } _tcscpy(szCmdLine, s); s = _tcsrchr(szCmdLine, '.'); if (s) *s = 0; _tcscat(szCmdLine, _T(" /C ")); _tcscat(szCmdLine, cm); if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024)) { free (szCmdLine); return NULL; } memset(&ProcessInformation, 0, sizeof(ProcessInformation)); memset(&StartupInfo, 0, sizeof(STARTUPINFO)); StartupInfo.cb = sizeof(STARTUPINFO); if (*md == 'r' ) { StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); StartupInfo.hStdOutput = hWritePipe; StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } else if ( *md == 'w' ) { StartupInfo.hStdInput = hReadPipe; StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } if (StartupInfo.dwFlags & STARTF_USESTDHANDLES) StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); result = CreateProcess(szComSpec, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInformation); free (szCmdLine); if (result == FALSE) { CloseHandle(hReadPipe); CloseHandle(hWritePipe); return NULL; } CloseHandle(ProcessInformation.hThread); _mlock(_POPEN_LOCK); for(i=0; i<popen_handles_size; i++) { if (!popen_handles[i].f) break; } if (i==popen_handles_size) { i = (popen_handles_size ? popen_handles_size*2 : 8); container = realloc(popen_handles, i*sizeof(*container)); if (!container) goto error; popen_handles = container; container = popen_handles+popen_handles_size; memset(container, 0, (i-popen_handles_size)*sizeof(*container)); popen_handles_size = i; } else container = popen_handles+i; if ( *md == 'r' ) { ret = _tfdopen(msvcrt_alloc_fd(hReadPipe, split_oflags(_fmode)) , _T("r")); CloseHandle(hWritePipe); } else { ret = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w")); CloseHandle(hReadPipe); } container->f = ret; container->proc = ProcessInformation.hProcess; _munlock(_POPEN_LOCK); return ret; error: _munlock(_POPEN_LOCK); if (ProcessInformation.hProcess != 0) CloseHandle(ProcessInformation.hProcess); return NULL; }
/* * @implemented */ FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */ { _TCHAR *szCmdLine=NULL; _TCHAR *szComSpec=NULL; _TCHAR *s; FILE *pf; HANDLE hReadPipe, hWritePipe; BOOL result; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md); if (cm == NULL) return( NULL ); szComSpec = _tgetenv(_T("COMSPEC")); if (szComSpec == NULL) { szComSpec = _T("cmd.exe"); } s = max(_tcsrchr(szComSpec, '\\'), _tcsrchr(szComSpec, '/')); if (s == NULL) s = szComSpec; else s++; szCmdLine = malloc((_tcslen(s) + 4 + _tcslen(cm) + 1) * sizeof(_TCHAR)); if (szCmdLine == NULL) { return NULL; } _tcscpy(szCmdLine, s); s = _tcsrchr(szCmdLine, '.'); if (s) *s = 0; _tcscat(szCmdLine, _T(" /C ")); _tcscat(szCmdLine, cm); if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024)) { free (szCmdLine); return NULL; } memset(&StartupInfo, 0, sizeof(STARTUPINFO)); StartupInfo.cb = sizeof(STARTUPINFO); if (*md == 'r' ) { StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); StartupInfo.hStdOutput = hWritePipe; StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } else if ( *md == 'w' ) { StartupInfo.hStdInput = hReadPipe; StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); StartupInfo.dwFlags |= STARTF_USESTDHANDLES; } if (StartupInfo.dwFlags & STARTF_USESTDHANDLES) StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); result = CreateProcess(szComSpec, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInformation); free (szCmdLine); if (result == FALSE) { CloseHandle(hReadPipe); CloseHandle(hWritePipe); return NULL; } CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); if ( *md == 'r' ) { pf = _tfdopen(msvcrt_alloc_fd(hReadPipe, split_oflags(_fmode)) , _T("r")); CloseHandle(hWritePipe); } else { pf = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w")); CloseHandle(hReadPipe); } return( pf ); }