ntdll: Add a __wine_unix_spawnvp syscall.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a851703ed7
commit
c1b3d6eb10
|
@ -1622,6 +1622,7 @@
|
|||
|
||||
# Unix interface
|
||||
@ stdcall -syscall __wine_unix_call(int64 long ptr)
|
||||
@ stdcall -syscall __wine_unix_spawnvp(long ptr)
|
||||
@ cdecl __wine_set_unix_funcs(long ptr)
|
||||
@ cdecl __wine_init_unix_lib(long long ptr ptr)
|
||||
@ stdcall __wine_ctrl_routine(ptr)
|
||||
|
|
|
@ -344,6 +344,7 @@ static void * const syscalls[] =
|
|||
NtYieldExecution,
|
||||
__wine_dbg_write,
|
||||
__wine_unix_call,
|
||||
__wine_unix_spawnvp,
|
||||
wine_nt_to_unix_file_name,
|
||||
wine_server_call,
|
||||
wine_server_fd_to_handle,
|
||||
|
|
|
@ -481,6 +481,59 @@ static NTSTATUS spawn_process( const RTL_USER_PROCESS_PARAMETERS *params, int so
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* __wine_unix_spawnvp
|
||||
*/
|
||||
NTSTATUS WINAPI __wine_unix_spawnvp( char * const argv[], int wait )
|
||||
{
|
||||
pid_t pid, wret;
|
||||
int fd[2], status, err;
|
||||
|
||||
#ifdef HAVE_PIPE2
|
||||
if (pipe2( fd, O_CLOEXEC ) == -1)
|
||||
#endif
|
||||
{
|
||||
if (pipe(fd) == -1) return STATUS_TOO_MANY_OPENED_FILES;
|
||||
fcntl( fd[0], F_SETFD, FD_CLOEXEC );
|
||||
fcntl( fd[1], F_SETFD, FD_CLOEXEC );
|
||||
}
|
||||
|
||||
if (!(pid = fork()))
|
||||
{
|
||||
/* in child */
|
||||
close( fd[0] );
|
||||
signal( SIGPIPE, SIG_DFL );
|
||||
if (!wait)
|
||||
{
|
||||
if (!(pid = fork())) execvp( argv[0], argv ); /* in grandchild */
|
||||
if (pid > 0) _exit(0); /* exit child if fork succeeded */
|
||||
}
|
||||
else execvp( argv[0], argv );
|
||||
|
||||
err = errno_to_status( errno );
|
||||
write( fd[1], &err, sizeof(err) );
|
||||
_exit(1);
|
||||
}
|
||||
close( fd[1] );
|
||||
|
||||
if (pid != -1)
|
||||
{
|
||||
while (pid != (wret = waitpid( pid, &status, 0 )))
|
||||
if (wret == -1 && errno != EINTR) break;
|
||||
|
||||
if (read( fd[0], &err, sizeof(err) ) <= 0) /* if we read something, exec or second fork failed */
|
||||
{
|
||||
if (pid == wret && WIFEXITED(status)) err = WEXITSTATUS(status);
|
||||
else err = 255; /* abnormal exit with an abort or an interrupt */
|
||||
}
|
||||
}
|
||||
else err = errno_to_status( errno );
|
||||
|
||||
close( fd[0] );
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* fork_and_exec
|
||||
*
|
||||
|
|
|
@ -2854,7 +2854,7 @@ static LRESULT start_screensaver(void)
|
|||
if (!is_virtual_desktop())
|
||||
{
|
||||
const char *argv[3] = { "xdg-screensaver", "activate", NULL };
|
||||
int pid = _spawnvp( _P_DETACH, argv[0], argv );
|
||||
int pid = __wine_unix_spawnvp( (char **)argv, FALSE );
|
||||
if (pid > 0)
|
||||
{
|
||||
TRACE( "started process %d\n", pid );
|
||||
|
|
|
@ -284,6 +284,25 @@ NTSTATUS WINAPI wow64___wine_unix_call( UINT *args )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64___wine_unix_spawnvp
|
||||
*/
|
||||
NTSTATUS WINAPI wow64___wine_unix_spawnvp( UINT *args )
|
||||
{
|
||||
ULONG *argv32 = get_ptr( &args );
|
||||
int wait = get_ulong( &args );
|
||||
|
||||
unsigned int i, count = 0;
|
||||
char **argv;
|
||||
|
||||
while (argv32[count]) count++;
|
||||
argv = Wow64AllocateTemp( (count + 1) * sizeof(*argv) );
|
||||
for (i = 0; i < count; i++) argv[i] = ULongToPtr( argv32[i] );
|
||||
argv[count] = NULL;
|
||||
return __wine_unix_spawnvp( argv, wait );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* wow64_wine_server_call
|
||||
*/
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
SYSCALL_ENTRY( NtYieldExecution ) \
|
||||
SYSCALL_ENTRY( __wine_dbg_write ) \
|
||||
SYSCALL_ENTRY( __wine_unix_call ) \
|
||||
SYSCALL_ENTRY( __wine_unix_spawnvp ) \
|
||||
SYSCALL_ENTRY( wine_nt_to_unix_file_name ) \
|
||||
SYSCALL_ENTRY( wine_server_call ) \
|
||||
SYSCALL_ENTRY( wine_server_fd_to_handle ) \
|
||||
|
|
|
@ -4603,6 +4603,7 @@ static inline PLIST_ENTRY RemoveTailList(PLIST_ENTRY le)
|
|||
|
||||
/* Wine internal functions */
|
||||
extern NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out );
|
||||
extern NTSTATUS WINAPI __wine_unix_spawnvp( char * const argv[], int wait );
|
||||
|
||||
/* The thread information for 16-bit threads */
|
||||
/* NtCurrentTeb()->SubSystemTib points to this */
|
||||
|
|
Loading…
Reference in New Issue