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.
|
* Distributed under the terms of the MIT license.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -20,7 +20,9 @@
|
|||||||
enum action_type {
|
enum action_type {
|
||||||
file_action_open,
|
file_action_open,
|
||||||
file_action_close,
|
file_action_close,
|
||||||
file_action_dup2
|
file_action_dup2,
|
||||||
|
file_action_chdir,
|
||||||
|
file_action_fchdir
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _file_action {
|
struct _file_action {
|
||||||
@@ -35,6 +37,9 @@ struct _file_action {
|
|||||||
struct {
|
struct {
|
||||||
int srcfd;
|
int srcfd;
|
||||||
} dup2_action;
|
} dup2_action;
|
||||||
|
struct {
|
||||||
|
char* path;
|
||||||
|
} chdir_action;
|
||||||
} action;
|
} action;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,6 +95,15 @@ posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *_actions)
|
|||||||
if (actions == NULL)
|
if (actions == NULL)
|
||||||
return EINVAL;
|
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);
|
free(actions);
|
||||||
|
|
||||||
return 0;
|
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
|
int
|
||||||
posix_spawnattr_init(posix_spawnattr_t *_attr)
|
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) {
|
} else if (action->type == file_action_dup2) {
|
||||||
if (dup2(action->action.dup2_action.srcfd, action->fd) == -1)
|
if (dup2(action->action.dup2_action.srcfd, action->fd) == -1)
|
||||||
return errno;
|
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