posix_spawn: add chdir-related non-portable actions

Namely posix_spawn_file_actions_addchdir_np and
posix_spawn_file_actions_addfchdir_np.

Reviewed by:	kevans, ngie (previous version)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D33143
This commit is contained in:
Konstantin Belousov 2021-11-28 00:49:03 +02:00
parent 8ed1e4a5c1
commit 25cda42a49
3 changed files with 65 additions and 1 deletions

View File

@ -87,6 +87,13 @@ int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict,
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int);
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int);
#if __BSD_VISIBLE
int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t *
__restrict, const char * __restrict);
int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *,
int);
#endif
/*
* Spawn attributes
*/

View File

@ -436,6 +436,8 @@ FBSD_1.6 {
};
FBSD_1.7 {
posix_spawn_file_actions_addchdir_np;
posix_spawn_file_actions_addfchdir_np;
sched_getaffinity;
sched_setaffinity;
sched_getcpu;

View File

@ -66,6 +66,8 @@ typedef struct __posix_spawn_file_actions_entry {
FAE_OPEN,
FAE_DUP2,
FAE_CLOSE,
FAE_CHDIR,
FAE_FCHDIR,
} fae_action;
int fae_fildes;
@ -180,6 +182,14 @@ process_file_actions_entry(posix_spawn_file_actions_entry_t *fae)
/* Perform a close(), do not fail if already closed */
(void)_close(fae->fae_fildes);
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;
}
return (0);
}
@ -393,7 +403,8 @@ posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa)
STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list);
/* 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);
}
@ -478,6 +489,50 @@ posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa,
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);
}
/*
* Spawn attributes
*/