ReactOS  0.4.14-dev-49-gfb4591c
popen.c
Go to the documentation of this file.
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  * PROGRAMMERS: Eric Kohl
7  * Hartmut Birr
8  * Also adapted from Wine team code by Andreas Maier.
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 msvcrt_alloc_fd(HANDLE hand, int flag); //FIXME: Remove
23 unsigned split_oflags(unsigned oflags); //FIXME: Remove
24 
25 #ifndef _UNICODE
28 
30 {
32 }
33 #endif
34 
35 /*
36  * @implemented
37  */
38 FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */
39 {
40  _TCHAR *szCmdLine=NULL;
41  _TCHAR *szComSpec=NULL;
42  _TCHAR *s;
43  FILE *ret;
44  HANDLE hReadPipe, hWritePipe;
45  BOOL result;
46  STARTUPINFO StartupInfo;
47  PROCESS_INFORMATION ProcessInformation;
49  struct popen_handle *container;
50  DWORD i;
51 
52  TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md);
53 
54  if (cm == NULL)
55  return NULL;
56 
57  szComSpec = _tgetenv(_T("COMSPEC"));
58  if (szComSpec == NULL)
59  {
60  szComSpec = _T("cmd.exe");
61  }
62 
63  s = max(_tcsrchr(szComSpec, '\\'), _tcsrchr(szComSpec, '/'));
64  if (s == NULL)
65  s = szComSpec;
66  else
67  s++;
68 
69  szCmdLine = malloc((_tcslen(s) + 4 + _tcslen(cm) + 1) * sizeof(_TCHAR));
70  if (szCmdLine == NULL)
71  {
72  return NULL;
73  }
74 
75  _tcscpy(szCmdLine, s);
76  s = _tcsrchr(szCmdLine, '.');
77  if (s)
78  *s = 0;
79  _tcscat(szCmdLine, _T(" /C "));
80  _tcscat(szCmdLine, cm);
81 
82  if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024))
83  {
84  free (szCmdLine);
85  return NULL;
86  }
87 
88  memset(&ProcessInformation, 0, sizeof(ProcessInformation));
89  memset(&StartupInfo, 0, sizeof(STARTUPINFO));
90  StartupInfo.cb = sizeof(STARTUPINFO);
91 
92  if (*md == 'r' ) {
94  StartupInfo.hStdOutput = hWritePipe;
95  StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
96  }
97  else if ( *md == 'w' ) {
98  StartupInfo.hStdInput = hReadPipe;
100  StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
101  }
102 
103  if (StartupInfo.dwFlags & STARTF_USESTDHANDLES)
104  StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
105 
106  result = CreateProcess(szComSpec,
107  szCmdLine,
108  NULL,
109  NULL,
110  TRUE,
111  0,
112  NULL,
113  NULL,
114  &StartupInfo,
115  &ProcessInformation);
116  free (szCmdLine);
117 
118  if (result == FALSE)
119  {
120  CloseHandle(hReadPipe);
121  CloseHandle(hWritePipe);
122  return NULL;
123  }
124 
125  CloseHandle(ProcessInformation.hThread);
126 
128  for(i=0; i<popen_handles_size; i++)
129  {
130  if (!popen_handles[i].f)
131  break;
132  }
133  if (i==popen_handles_size)
134  {
137  if (!container) goto error;
138 
143  }
144  else container = popen_handles+i;
145 
146  if ( *md == 'r' )
147  {
148  ret = _tfdopen(msvcrt_alloc_fd(hReadPipe, split_oflags(_fmode)) , _T("r"));
149  CloseHandle(hWritePipe);
150  }
151  else
152  {
153  ret = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w"));
154  CloseHandle(hReadPipe);
155  }
156 
157  container->f = ret;
158  container->proc = ProcessInformation.hProcess;
160 
161  return ret;
162 
163 error:
165  if (ProcessInformation.hProcess != 0)
166  CloseHandle(ProcessInformation.hProcess);
167  return NULL;
168 }
169 
170 #ifndef _UNICODE
171 
172 /*
173  * @implemented
174  */
176 {
177  HANDLE h;
178  DWORD i;
179 
180  if (!MSVCRT_CHECK_PMT(file != NULL)) return -1;
181 
183  for(i=0; i<popen_handles_size; i++)
184  {
185  if (popen_handles[i].f == file)
186  break;
187  }
188  if(i == popen_handles_size)
189  {
191  *_errno() = EBADF;
192  return -1;
193  }
194 
195  h = popen_handles[i].proc;
196  popen_handles[i].f = NULL;
198 
199  fclose(file);
201  {
203  CloseHandle(h);
204  return -1;
205  }
206 
207  CloseHandle(h);
208  return i;
209 }
210 
211 #endif
#define realloc
Definition: debug_ros.c:6
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define error(str)
Definition: mkdosfs.c:1605
#define _POPEN_LOCK
Definition: mtdll.h:53
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
#define free
Definition: debug_ros.c:5
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
DWORD dwFlags
Definition: winbase.h:807
Definition: arc.h:36
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
struct container container
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
#define _mlock(locknum)
Definition: mtdll.h:32
#define _tfdopen
Definition: tchar.h:692
#define STD_INPUT_HANDLE
Definition: winbase.h:264
char _TCHAR
Definition: tchar.h:1392
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
GLfloat f
Definition: glext.h:7540
#define _T(x)
Definition: vfdio.h:22
#define TRACE(s)
Definition: solgame.cpp:4
DWORD cb
Definition: winbase.h:796
#define STD_ERROR_HANDLE
Definition: winbase.h:266
void msvcrt_free_popen_data(void)
Definition: popen.c:29
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_FAILED
Definition: winbase.h:394
HANDLE hStdOutput
Definition: winbase.h:812
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:19
#define MK_STR(s)
Definition: popen.c:20
int ret
#define _munlock(locknum)
Definition: mtdll.h:33
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
GLdouble s
Definition: gl.h:2039
#define _tgetenv
Definition: tchar.h:680
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
#define CreateProcess
Definition: winbase.h:3575
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
void _dosmaperr(unsigned long oserrcode)
Definition: errno.c:81
DWORD popen_handles_size
Definition: popen.c:27
_CRTIMP int _fmode
Definition: txtmode.c:13
#define CDECL
Definition: compat.h:21
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3536
HANDLE hStdInput
Definition: winbase.h:811
FILE * _tpopen(const _TCHAR *cm, const _TCHAR *md)
Definition: popen.c:38
_TCHAR * _tcscat(_TCHAR *s, const _TCHAR *append)
Definition: tcscat.h:8
_TCHAR * _tcsrchr(const _TCHAR *s, _XINT c)
Definition: tcsrchr.h:4
unsigned split_oflags(unsigned oflags)
Definition: file.c:1671
struct popen_handle * popen_handles
Definition: popen.c:26
#define malloc
Definition: debug_ros.c:4
int CDECL _pclose(FILE *file)
Definition: popen.c:175
#define INFINITE
Definition: serial.h:102
#define md
Definition: compat-1.3.h:1989
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
HANDLE hStdError
Definition: winbase.h:813
#define sT
Definition: popen.c:17
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
int msvcrt_alloc_fd(HANDLE hand, int flag)
Definition: file.c:343
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
Definition: fci.c:126