posix_spawn: add posix_spawn_file_actions_add[f]chdir_np.
see http://austingroupbugs.net/view.php?id=1208 and https://sourceware.org/bugzilla/show_bug.cgi?id=17405 * also free paths in posix_spawn_file_actions_destroy(). Change-Id: I8bed848154025bd5a25322bdc4c25aa417f86ec6 Reviewed-on: https://review.haiku-os.org/c/1010 Reviewed-by: Rene Gollent <[email protected]>
This commit is contained in:
committed by
Rene Gollent
parent
e4803b2c61
commit
f33f4868fe
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019 Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the Haiku License.
|
||||
*/
|
||||
#ifndef _GNU_SPAWN_H_
|
||||
#define _GNU_SPAWN_H_
|
||||
|
||||
|
||||
#include_next <spawn.h>
|
||||
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int posix_spawn_file_actions_addchdir_np(
|
||||
posix_spawn_file_actions_t *file_actions, const char *path);
|
||||
extern int posix_spawn_file_actions_addfchdir_np(
|
||||
posix_spawn_file_actions_t *file_actions, int fildes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _GNU_SPAWN_H_ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017, Jérôme Duval, [email protected]
|
||||
* Copyright 2017-2019, Jérôme Duval, [email protected]
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
enum action_type {
|
||||
file_action_open,
|
||||
file_action_close,
|
||||
file_action_dup2
|
||||
file_action_dup2,
|
||||
file_action_chdir,
|
||||
file_action_fchdir
|
||||
};
|
||||
|
||||
struct _file_action {
|
||||
@@ -35,6 +37,9 @@ struct _file_action {
|
||||
struct {
|
||||
int srcfd;
|
||||
} dup2_action;
|
||||
struct {
|
||||
char* path;
|
||||
} chdir_action;
|
||||
} action;
|
||||
};
|
||||
|
||||
@@ -90,6 +95,15 @@ posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *_actions)
|
||||
if (actions == NULL)
|
||||
return EINVAL;
|
||||
|
||||
for (int i = 0; i < actions->count; i++) {
|
||||
struct _file_action *action = &actions->actions[i];
|
||||
|
||||
if (action->type == file_action_open)
|
||||
free(action->action.open_action.path);
|
||||
else if (action->type == file_action_chdir)
|
||||
free(action->action.chdir_action.path);
|
||||
}
|
||||
|
||||
free(actions);
|
||||
|
||||
return 0;
|
||||
@@ -179,6 +193,58 @@ posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *_actions,
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t *_actions,
|
||||
const char *path)
|
||||
{
|
||||
struct _posix_spawn_file_actions* actions = _actions != NULL ? *_actions : NULL;
|
||||
|
||||
if (actions == NULL)
|
||||
return EINVAL;
|
||||
|
||||
char* npath = strdup(path);
|
||||
if (npath == NULL)
|
||||
return ENOMEM;
|
||||
if (actions->count == actions->size
|
||||
&& posix_spawn_file_actions_extend(actions) != 0) {
|
||||
free(npath);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
struct _file_action *action = &actions->actions[actions->count];
|
||||
action->type = file_action_chdir;
|
||||
action->fd = -1;
|
||||
action->action.chdir_action.path = npath;
|
||||
actions->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *_actions,
|
||||
int fildes)
|
||||
{
|
||||
struct _posix_spawn_file_actions* actions = _actions != NULL ? *_actions : NULL;
|
||||
|
||||
if (actions == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (fildes < 0 || fildes >= sysconf(_SC_OPEN_MAX))
|
||||
return EBADF;
|
||||
|
||||
if (actions->count == actions->size
|
||||
&& posix_spawn_file_actions_extend(actions) != 0) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
struct _file_action *action = &actions->actions[actions->count];
|
||||
action->type = file_action_fchdir;
|
||||
action->fd = fildes;
|
||||
actions->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
posix_spawnattr_init(posix_spawnattr_t *_attr)
|
||||
{
|
||||
@@ -415,6 +481,12 @@ process_file_actions(const posix_spawn_file_actions_t *_actions, int *errfd)
|
||||
} else if (action->type == file_action_dup2) {
|
||||
if (dup2(action->action.dup2_action.srcfd, action->fd) == -1)
|
||||
return errno;
|
||||
} else if (action->type == file_action_chdir) {
|
||||
if (chdir(action->action.chdir_action.path) == -1)
|
||||
return errno;
|
||||
} else if (action->type == file_action_fchdir) {
|
||||
if (fchdir(action->fd) == -1)
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user