Implement _popen and _pclose, and use debugstr_a to avoid a crash

tracing long command lines.
This commit is contained in:
Juan Lang 2004-12-14 15:13:54 +00:00 committed by Alexandre Julliard
parent 8c0ccdcb68
commit 7b44be79df
2 changed files with 101 additions and 4 deletions

View File

@ -575,6 +575,7 @@ MSVCRT_clock_t MSVCRT_clock(void);
double MSVCRT_difftime(MSVCRT_time_t time1, MSVCRT_time_t time2);
MSVCRT_time_t MSVCRT_time(MSVCRT_time_t*);
void * MSVCRT___p__daylight(void);
MSVCRT_FILE* MSVCRT__fdopen(int, const char *);
#ifndef __WINE_MSVCRT_TEST
int _write(int,const void*,unsigned int);
@ -599,6 +600,10 @@ MSVCRT_wchar_t*** __p__wenviron(void);
char* _strdate(char* date);
char* _strtime(char* date);
void _ftime(struct MSVCRT__timeb *buf);
int _close(int);
int _dup(int);
int _dup2(int, int);
int _pipe(int *, unsigned int, int);
#endif
/* FIXME: Functions that we forward to. They shouldn't be defined

View File

@ -449,7 +449,8 @@ int _spawnve(int flags, const char* name, const char* const* argv,
int ret = -1;
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)
{
@ -500,10 +501,102 @@ int _spawnvp(int flags, const char* name, const char* const* argv)
/*********************************************************************
* _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)
{
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;
}
@ -521,8 +614,7 @@ MSVCRT_FILE* MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wchar_t*
*/
int MSVCRT__pclose(MSVCRT_FILE* file)
{
FIXME("(file=%p): stub\n", file);
return 0;
return MSVCRT_fclose(file);
}
/*********************************************************************