[CRT]
[reactos.git] / reactos / lib / sdk / crt / stdio / popen.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS C runtime library
4 * FILE: lib/sdk/crt/stdio/popen.c
5 * PURPOSE: Pipe Functions
6 * PROGRAMERS: Eric Kohl
7 Hartmut Birr
8 */
9
10 #include <precomp.h>
11 #include <tchar.h>
12
13 #ifdef _UNICODE
14 #define sT "S"
15 #else
16 #define sT "s"
17 #endif
18
19 #define MK_STR(s) #s
20
21 int alloc_fd(HANDLE hand, int flag); //FIXME: Remove
22 unsigned split_oflags(unsigned oflags); //FIXME: Remove
23
24 /*
25 * @implemented
26 */
27 FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */
28 {
29 _TCHAR *szCmdLine=NULL;
30 _TCHAR *szComSpec=NULL;
31 _TCHAR *s;
32 FILE *pf;
33 HANDLE hReadPipe, hWritePipe;
34 BOOL result;
35 STARTUPINFO StartupInfo;
36 PROCESS_INFORMATION ProcessInformation;
37 SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
38
39 TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md);
40
41 if (cm == NULL)
42 return( NULL );
43
44 szComSpec = _tgetenv(_T("COMSPEC"));
45 if (szComSpec == NULL)
46 {
47 szComSpec = _T("cmd.exe");
48 }
49
50 s = max(_tcsrchr(szComSpec, '\\'), _tcsrchr(szComSpec, '/'));
51 if (s == NULL)
52 s = szComSpec;
53 else
54 s++;
55
56 szCmdLine = malloc((_tcslen(s) + 4 + _tcslen(cm) + 1) * sizeof(_TCHAR));
57 if (szCmdLine == NULL)
58 {
59 return NULL;
60 }
61
62 _tcscpy(szCmdLine, s);
63 s = _tcsrchr(szCmdLine, '.');
64 if (s)
65 *s = 0;
66 _tcscat(szCmdLine, _T(" /C "));
67 _tcscat(szCmdLine, cm);
68
69 if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024))
70 {
71 free (szCmdLine);
72 return NULL;
73 }
74
75 memset(&StartupInfo, 0, sizeof(STARTUPINFO));
76 StartupInfo.cb = sizeof(STARTUPINFO);
77
78 if (*md == 'r' ) {
79 StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
80 StartupInfo.hStdOutput = hWritePipe;
81 StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
82 }
83 else if ( *md == 'w' ) {
84 StartupInfo.hStdInput = hReadPipe;
85 StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
86 StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
87 }
88
89 if (StartupInfo.dwFlags & STARTF_USESTDHANDLES)
90 StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
91
92 result = CreateProcess(szComSpec,
93 szCmdLine,
94 NULL,
95 NULL,
96 TRUE,
97 0,
98 NULL,
99 NULL,
100 &StartupInfo,
101 &ProcessInformation);
102 free (szCmdLine);
103
104 if (result == FALSE)
105 {
106 CloseHandle(hReadPipe);
107 CloseHandle(hWritePipe);
108 return NULL;
109 }
110
111 CloseHandle(ProcessInformation.hThread);
112 CloseHandle(ProcessInformation.hProcess);
113
114 if ( *md == 'r' )
115 {
116 pf = _tfdopen(alloc_fd(hReadPipe, split_oflags(_fmode)) , _T("r"));
117 CloseHandle(hWritePipe);
118 }
119 else
120 {
121 pf = _tfdopen( alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w"));
122 CloseHandle(hReadPipe);
123 }
124
125 return( pf );
126 }
127
128 #ifndef _UNICODE
129
130 /*
131 * @implemented
132 */
133 int _pclose (FILE *pp)
134 {
135 TRACE("_pclose(%x)",pp);
136
137 fclose(pp);
138 //if (!TerminateProcess(pp->_tmpfname ,0))
139 // return( -1 );
140 return( 0 );
141 }
142
143 #endif
144
145