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