Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/gen/posix_spawn.c
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
struct __posix_spawn_file_actions { | struct __posix_spawn_file_actions { | ||||
STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list; | STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list; | ||||
}; | }; | ||||
typedef struct __posix_spawn_file_actions_entry { | typedef struct __posix_spawn_file_actions_entry { | ||||
STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list; | STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list; | ||||
enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action; | enum { | ||||
FAE_OPEN, | |||||
FAE_DUP2, | |||||
FAE_CLOSE, | |||||
FAE_CHDIR, | |||||
FAE_FCHDIR, | |||||
FAE_CLOSEFROM, | |||||
} fae_action; | |||||
int fae_fildes; | int fae_fildes; | ||||
union { | union { | ||||
struct { | struct { | ||||
char *path; | char *path; | ||||
#define fae_path fae_data.open.path | #define fae_path fae_data.open.path | ||||
int oflag; | int oflag; | ||||
#define fae_oflag fae_data.open.oflag | #define fae_oflag fae_data.open.oflag | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1) | ||||
return (errno); | return (errno); | ||||
if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) | if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) | ||||
return (errno); | return (errno); | ||||
break; | break; | ||||
case FAE_CLOSE: | case FAE_CLOSE: | ||||
/* Perform a close(), do not fail if already closed */ | /* Perform a close(), do not fail if already closed */ | ||||
(void)_close(fae->fae_fildes); | (void)_close(fae->fae_fildes); | ||||
break; | break; | ||||
case FAE_CHDIR: | |||||
if (chdir(fae->fae_path) != 0) | |||||
return (errno); | |||||
break; | |||||
case FAE_FCHDIR: | |||||
if (fchdir(fae->fae_fildes) != 0) | |||||
return (errno); | |||||
break; | |||||
case FAE_CLOSEFROM: | |||||
closefrom(fae->fae_fildes); | |||||
break; | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
process_file_actions(const posix_spawn_file_actions_t fa) | process_file_actions(const posix_spawn_file_actions_t fa) | ||||
{ | { | ||||
posix_spawn_file_actions_entry_t *fae; | posix_spawn_file_actions_entry_t *fae; | ||||
▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
int | int | ||||
posix_spawn(pid_t *pid, const char *path, | posix_spawn(pid_t *pid, const char *path, | ||||
const posix_spawn_file_actions_t *fa, | const posix_spawn_file_actions_t *fa, | ||||
const posix_spawnattr_t *sa, | const posix_spawnattr_t *sa, | ||||
char * const argv[], char * const envp[]) | char * const argv[], char * const envp[]) | ||||
{ | { | ||||
return do_posix_spawn(pid, path, fa, sa, argv, envp, 0); | return (do_posix_spawn(pid, path, fa, sa, argv, envp, 0)); | ||||
} | } | ||||
int | int | ||||
posix_spawnp(pid_t *pid, const char *path, | posix_spawnp(pid_t *pid, const char *path, | ||||
const posix_spawn_file_actions_t *fa, | const posix_spawn_file_actions_t *fa, | ||||
const posix_spawnattr_t *sa, | const posix_spawnattr_t *sa, | ||||
char * const argv[], char * const envp[]) | char * const argv[], char * const envp[]) | ||||
{ | { | ||||
return do_posix_spawn(pid, path, fa, sa, argv, envp, 1); | return (do_posix_spawn(pid, path, fa, sa, argv, envp, 1)); | ||||
} | } | ||||
/* | /* | ||||
* File descriptor actions | * File descriptor actions | ||||
*/ | */ | ||||
int | int | ||||
posix_spawn_file_actions_init(posix_spawn_file_actions_t *ret) | posix_spawn_file_actions_init(posix_spawn_file_actions_t *ret) | ||||
Show All 14 Lines | |||||
{ | { | ||||
posix_spawn_file_actions_entry_t *fae; | posix_spawn_file_actions_entry_t *fae; | ||||
while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) { | while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) { | ||||
/* Remove file action entry from the queue */ | /* Remove file action entry from the queue */ | ||||
STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list); | STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list); | ||||
/* Deallocate file action entry */ | /* Deallocate file action entry */ | ||||
if (fae->fae_action == FAE_OPEN) | if (fae->fae_action == FAE_OPEN || | ||||
fae->fae_action == FAE_CHDIR) | |||||
free(fae->fae_path); | free(fae->fae_path); | ||||
free(fae); | free(fae); | ||||
} | } | ||||
free(*fa); | free(*fa); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, | ||||
/* Allocate object */ | /* Allocate object */ | ||||
fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); | fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); | ||||
if (fae == NULL) | if (fae == NULL) | ||||
return (errno); | return (errno); | ||||
/* Set values and store in queue */ | /* Set values and store in queue */ | ||||
fae->fae_action = FAE_CLOSE; | fae->fae_action = FAE_CLOSE; | ||||
fae->fae_fildes = fildes; | fae->fae_fildes = fildes; | ||||
STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); | |||||
return (0); | |||||
} | |||||
int | |||||
posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t * | |||||
__restrict fa, const char *__restrict path) | |||||
{ | |||||
posix_spawn_file_actions_entry_t *fae; | |||||
int error; | |||||
fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); | |||||
if (fae == NULL) | |||||
return (errno); | |||||
fae->fae_action = FAE_CHDIR; | |||||
fae->fae_path = strdup(path); | |||||
if (fae->fae_path == NULL) { | |||||
error = errno; | |||||
free(fae); | |||||
return (error); | |||||
} | |||||
STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); | |||||
return (0); | |||||
} | |||||
int | |||||
posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *__restrict fa, | |||||
int fildes) | |||||
{ | |||||
posix_spawn_file_actions_entry_t *fae; | |||||
if (fildes < 0) | |||||
return (EBADF); | |||||
/* Allocate object */ | |||||
fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); | |||||
if (fae == NULL) | |||||
return (errno); | |||||
fae->fae_action = FAE_FCHDIR; | |||||
fae->fae_fildes = fildes; | |||||
STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); | |||||
return (0); | |||||
} | |||||
int | |||||
posix_spawn_file_actions_addclosefrom_np (posix_spawn_file_actions_t * | |||||
__restrict fa, int from) | |||||
{ | |||||
posix_spawn_file_actions_entry_t *fae; | |||||
if (from < 0) | |||||
return (EBADF); | |||||
/* Allocate object */ | |||||
fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); | |||||
if (fae == NULL) | |||||
return (errno); | |||||
fae->fae_action = FAE_CLOSEFROM; | |||||
fae->fae_fildes = from; | |||||
STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); | STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Spawn attributes | * Spawn attributes | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 114 Lines • Show Last 20 Lines |