Implement _popen and _pclose, and use debugstr_a to avoid a crash
tracing long command lines.
This commit is contained in:
parent
8c0ccdcb68
commit
7b44be79df
|
@ -575,6 +575,7 @@ MSVCRT_clock_t MSVCRT_clock(void);
|
||||||
double MSVCRT_difftime(MSVCRT_time_t time1, MSVCRT_time_t time2);
|
double MSVCRT_difftime(MSVCRT_time_t time1, MSVCRT_time_t time2);
|
||||||
MSVCRT_time_t MSVCRT_time(MSVCRT_time_t*);
|
MSVCRT_time_t MSVCRT_time(MSVCRT_time_t*);
|
||||||
void * MSVCRT___p__daylight(void);
|
void * MSVCRT___p__daylight(void);
|
||||||
|
MSVCRT_FILE* MSVCRT__fdopen(int, const char *);
|
||||||
|
|
||||||
#ifndef __WINE_MSVCRT_TEST
|
#ifndef __WINE_MSVCRT_TEST
|
||||||
int _write(int,const void*,unsigned int);
|
int _write(int,const void*,unsigned int);
|
||||||
|
@ -599,6 +600,10 @@ MSVCRT_wchar_t*** __p__wenviron(void);
|
||||||
char* _strdate(char* date);
|
char* _strdate(char* date);
|
||||||
char* _strtime(char* date);
|
char* _strtime(char* date);
|
||||||
void _ftime(struct MSVCRT__timeb *buf);
|
void _ftime(struct MSVCRT__timeb *buf);
|
||||||
|
int _close(int);
|
||||||
|
int _dup(int);
|
||||||
|
int _dup2(int, int);
|
||||||
|
int _pipe(int *, unsigned int, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME: Functions that we forward to. They shouldn't be defined
|
/* FIXME: Functions that we forward to. They shouldn't be defined
|
||||||
|
|
|
@ -449,7 +449,8 @@ int _spawnve(int flags, const char* name, const char* const* argv,
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
FIXME(":not translating name %s to locate program\n",fullname);
|
FIXME(":not translating name %s to locate program\n",fullname);
|
||||||
TRACE(":call (%s), params (%s), env (%s)\n",name,args,envs?"Custom":"Null");
|
TRACE(":call (%s), params (%s), env (%s)\n",debugstr_a(name),debugstr_a(args),
|
||||||
|
envs?"Custom":"Null");
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
|
@ -500,10 +501,102 @@ int _spawnvp(int flags, const char* name, const char* const* argv)
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _popen (MSVCRT.@)
|
* _popen (MSVCRT.@)
|
||||||
|
* FIXME: convert to _wpopen and call that from here instead? But it
|
||||||
|
* would have to convert the command back to ANSI to call msvcrt_spawn,
|
||||||
|
* less than ideal.
|
||||||
*/
|
*/
|
||||||
MSVCRT_FILE* MSVCRT__popen(const char* command, const char* mode)
|
MSVCRT_FILE* MSVCRT__popen(const char* command, const char* mode)
|
||||||
{
|
{
|
||||||
FIXME("(command=%s, mode=%s): stub\n", debugstr_a(command), debugstr_a(mode));
|
static const char wcmd[] = "wcmd", cmdFlag[] = " /C ", comSpec[] = "COMSPEC";
|
||||||
|
MSVCRT_FILE *ret;
|
||||||
|
BOOL readPipe = TRUE;
|
||||||
|
int textmode, fds[2], fdToDup, fdToOpen, fdStdHandle = -1, fdStdErr = -1;
|
||||||
|
const char *p;
|
||||||
|
char *cmdcopy;
|
||||||
|
DWORD comSpecLen;
|
||||||
|
|
||||||
|
TRACE("(command=%s, mode=%s)\n", debugstr_a(command), debugstr_a(mode));
|
||||||
|
|
||||||
|
if (!command || !mode)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
textmode = *__p__fmode() & (MSVCRT__O_BINARY | MSVCRT__O_TEXT);
|
||||||
|
for (p = mode; *p; p++)
|
||||||
|
{
|
||||||
|
switch (*p)
|
||||||
|
{
|
||||||
|
case 'W':
|
||||||
|
case 'w':
|
||||||
|
readPipe = FALSE;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
textmode |= MSVCRT__O_BINARY;
|
||||||
|
textmode &= ~MSVCRT__O_TEXT;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
case 't':
|
||||||
|
textmode |= MSVCRT__O_TEXT;
|
||||||
|
textmode &= ~MSVCRT__O_BINARY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
textmode |= MSVCRT__O_NOINHERIT;
|
||||||
|
if (_pipe(fds, 0, textmode) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fdToDup = readPipe ? 1 : 0;
|
||||||
|
fdToOpen = readPipe ? 0 : 1;
|
||||||
|
|
||||||
|
if ((fdStdHandle = _dup(fdToDup)) == -1)
|
||||||
|
goto error;
|
||||||
|
if (_dup2(fds[fdToDup], fdToDup) != 0)
|
||||||
|
goto error;
|
||||||
|
if (readPipe)
|
||||||
|
{
|
||||||
|
if ((fdStdErr = _dup(MSVCRT_STDERR_FILENO)) == -1)
|
||||||
|
goto error;
|
||||||
|
if (_dup2(fds[fdToDup], MSVCRT_STDERR_FILENO) != 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
_close(fds[fdToDup]);
|
||||||
|
|
||||||
|
comSpecLen = GetEnvironmentVariableA(comSpec, NULL, 0);
|
||||||
|
if (!comSpecLen)
|
||||||
|
comSpecLen = strlen(wcmd) + 1;
|
||||||
|
cmdcopy = (char *)HeapAlloc(GetProcessHeap(), 0, comSpecLen + strlen(cmdFlag)
|
||||||
|
+ strlen(command));
|
||||||
|
if (!GetEnvironmentVariableA(comSpec, cmdcopy, comSpecLen))
|
||||||
|
strcpy(cmdcopy, wcmd);
|
||||||
|
strcat(cmdcopy, cmdFlag);
|
||||||
|
strcat(cmdcopy, command);
|
||||||
|
if (msvcrt_spawn(MSVCRT__P_NOWAIT, NULL, cmdcopy, NULL) == -1)
|
||||||
|
{
|
||||||
|
_close(fds[fdToOpen]);
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = MSVCRT__fdopen(fds[fdToOpen], mode);
|
||||||
|
if (!ret)
|
||||||
|
_close(fds[fdToOpen]);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, cmdcopy);
|
||||||
|
_dup2(fdStdHandle, fdToDup);
|
||||||
|
_close(fdStdHandle);
|
||||||
|
if (readPipe)
|
||||||
|
{
|
||||||
|
_dup2(fdStdErr, MSVCRT_STDERR_FILENO);
|
||||||
|
_close(fdStdErr);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fdStdHandle != -1) _close(fdStdHandle);
|
||||||
|
if (fdStdErr != -1) _close(fdStdErr);
|
||||||
|
_close(fds[0]);
|
||||||
|
_close(fds[1]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,8 +614,7 @@ MSVCRT_FILE* MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wchar_t*
|
||||||
*/
|
*/
|
||||||
int MSVCRT__pclose(MSVCRT_FILE* file)
|
int MSVCRT__pclose(MSVCRT_FILE* file)
|
||||||
{
|
{
|
||||||
FIXME("(file=%p): stub\n", file);
|
return MSVCRT_fclose(file);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue