/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS C runtime library * FILE: lib/sdk/crt/stdio/popen.c * PURPOSE: Pipe Functions * PROGRAMMERS: Eric Kohl * Hartmut Birr * Also adapted from Wine team code by Andreas Maier. */ #include #include #ifdef _UNICODE #define sT "S" #else #define sT "s" #endif #define MK_STR(s) #s int msvcrt_alloc_fd(HANDLE hand, int flag); //FIXME: Remove unsigned split_oflags(unsigned oflags); //FIXME: Remove #ifndef _UNICODE struct popen_handle *popen_handles = NULL; DWORD popen_handles_size = 0; void msvcrt_free_popen_data(void) { free(popen_handles); } #endif /* * @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; if = ret; container->proc = ProcessInformation.hProcess; _munlock(_POPEN_LOCK); return ret; error: _munlock(_POPEN_LOCK); if (ProcessInformation.hProcess != 0) CloseHandle(ProcessInformation.hProcess); return NULL; } #ifndef _UNICODE /* * @implemented */ int CDECL _pclose(FILE* file) { HANDLE h; DWORD i; if (!MSVCRT_CHECK_PMT(file != NULL)) return -1; _mlock(_POPEN_LOCK); for(i=0; i