Added PR_ProcessAttrSetCurrentDirectory to allow setting the current
working directory of the new process. PR_SetStdioRedirect is renamed PR_ProcessAttrSetStdioRedirect. The old name is retained but moved to obsolete/probslet.h. This work is contributed by Ben Laurie <ben@algroup.co.ul>. Files changed: prproces.h, probslet.h, primpl.h, uxproces.c, ntmisc.c, prinit.c, and parent.c.
This commit is contained in:
Родитель
1ef8a73a3b
Коммит
b6f93822e7
|
@ -25,6 +25,7 @@
|
|||
#define PROBSLET_H
|
||||
|
||||
#include "prio.h"
|
||||
#include "prproces.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
|
@ -218,6 +219,12 @@ PR_EXTERN(PRStatus) PR_GetHostName(char *name, PRUint32 namelen);
|
|||
*/
|
||||
PR_EXTERN(const char *) PR_GetErrorString(void);
|
||||
|
||||
PR_EXTERN(void) PR_SetStdioRedirect(
|
||||
PRProcessAttr *attr,
|
||||
PRSpecialFD stdioFd,
|
||||
PRFileDesc *redirectFd
|
||||
);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* defined(PROBSLET_H) */
|
||||
|
|
|
@ -1371,6 +1371,7 @@ struct PRProcessAttr {
|
|||
PRFileDesc *stdinFd;
|
||||
PRFileDesc *stdoutFd;
|
||||
PRFileDesc *stderrFd;
|
||||
char *currentDirectory;
|
||||
};
|
||||
|
||||
struct PRProcess {
|
||||
|
|
|
@ -37,12 +37,17 @@ PR_EXTERN(void) PR_ResetProcessAttr(PRProcessAttr *attr);
|
|||
|
||||
PR_EXTERN(void) PR_DestroyProcessAttr(PRProcessAttr *attr);
|
||||
|
||||
PR_EXTERN(void) PR_SetStdioRedirect(
|
||||
PR_EXTERN(void) PR_ProcessAttrSetStdioRedirect(
|
||||
PRProcessAttr *attr,
|
||||
PRSpecialFD stdioFd,
|
||||
PRFileDesc *redirectFd
|
||||
);
|
||||
|
||||
PR_EXTERN(PRStatus) PR_ProcessAttrSetCurrentDirectory(
|
||||
PRProcessAttr *attr,
|
||||
const char *dir
|
||||
);
|
||||
|
||||
/*
|
||||
** Create a new process
|
||||
**
|
||||
|
|
|
@ -169,6 +169,11 @@ ForkAndExec(
|
|||
}
|
||||
close(attr->stderrFd->secret->md.osfd);
|
||||
}
|
||||
if (attr->currentDirectory) {
|
||||
if (chdir(attr->currentDirectory) < 0) {
|
||||
_exit(1); /* failed */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)execve(path, argv, envp);
|
||||
|
|
|
@ -431,7 +431,7 @@ PRProcess * _PR_CreateWindowsProcess(
|
|||
* string is in the form:
|
||||
* name=value
|
||||
* XXX: usually NULL */
|
||||
NULL, /* current drive and directory */
|
||||
attr->currentDirectory, /* current drive and directory */
|
||||
&startupInfo,
|
||||
&procInfo
|
||||
);
|
||||
|
@ -629,7 +629,7 @@ PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
|
|||
{
|
||||
mov ecx, val
|
||||
mov eax, 1
|
||||
xadd dword ptr [ecx], eax
|
||||
lock xadd dword ptr [ecx], eax
|
||||
inc eax
|
||||
}
|
||||
}
|
||||
|
@ -642,7 +642,7 @@ PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
|
|||
{
|
||||
mov ecx, val
|
||||
mov eax, 0ffffffffh
|
||||
xadd dword ptr [ecx], eax
|
||||
lock xadd dword ptr [ecx], eax
|
||||
dec eax
|
||||
}
|
||||
}
|
||||
|
|
|
@ -382,21 +382,22 @@ PR_NewProcessAttr(void)
|
|||
PR_IMPLEMENT(void)
|
||||
PR_ResetProcessAttr(PRProcessAttr *attr)
|
||||
{
|
||||
PR_FREEIF(attr->currentDirectory);
|
||||
memset(attr, 0, sizeof(*attr));
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_DestroyProcessAttr(PRProcessAttr *attr)
|
||||
{
|
||||
PR_FREEIF(attr->currentDirectory);
|
||||
PR_DELETE(attr);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PR_SetStdioRedirect(
|
||||
PR_ProcessAttrSetStdioRedirect(
|
||||
PRProcessAttr *attr,
|
||||
PRSpecialFD stdioFd,
|
||||
PRFileDesc *redirectFd
|
||||
)
|
||||
PRFileDesc *redirectFd)
|
||||
{
|
||||
switch (stdioFd) {
|
||||
case PR_StandardInput:
|
||||
|
@ -413,6 +414,40 @@ PR_SetStdioRedirect(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* OBSOLETE
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
PR_SetStdioRedirect(
|
||||
PRProcessAttr *attr,
|
||||
PRSpecialFD stdioFd,
|
||||
PRFileDesc *redirectFd)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
static PRBool warn = PR_TRUE;
|
||||
if (warn) {
|
||||
warn = _PR_Obsolete("PR_SetStdioRedirect()",
|
||||
"PR_ProcessAttrSetStdioRedirect()");
|
||||
}
|
||||
#endif
|
||||
PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus)
|
||||
PR_ProcessAttrSetCurrentDirectory(
|
||||
PRProcessAttr *attr,
|
||||
const char *dir)
|
||||
{
|
||||
PR_FREEIF(attr->currentDirectory);
|
||||
attr->currentDirectory = PR_MALLOC(strlen(dir) + 1);
|
||||
if (!attr->currentDirectory) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
strcpy(attr->currentDirectory, dir);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRProcess*) PR_CreateProcess(
|
||||
const char *path,
|
||||
char *const *argv,
|
||||
|
|
|
@ -76,10 +76,10 @@ PRIntn main (PRIntn argc, char **argv)
|
|||
if (NULL != debug) PR_fprintf(debug, "Forking %s\n", child->name);
|
||||
|
||||
child->attr = PR_NewProcessAttr();
|
||||
PR_SetStdioRedirect(
|
||||
PR_ProcessAttrSetStdioRedirect(
|
||||
child->attr, PR_StandardOutput,
|
||||
PR_GetSpecialFD(PR_StandardOutput));
|
||||
PR_SetStdioRedirect(
|
||||
PR_ProcessAttrSetStdioRedirect(
|
||||
child->attr, PR_StandardError,
|
||||
PR_GetSpecialFD(PR_StandardError));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче