hrev52843 adds 1 changeset to branch 'master'
old head: e4803b2c612547d74d98fcc91d7cc27ff9eea0e8
new head: f33f4868feabef0fbd3b5aaff459e23eedfb7b5a
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=f33f4868feab+%5Ee4803b2c6125
----------------------------------------------------------------------------
f33f4868feab: 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 <rene@xxxxxxxxxxx>
[ Jérôme Duval <jerome.duval@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev52843
Commit: f33f4868feabef0fbd3b5aaff459e23eedfb7b5a
URL: https://git.haiku-os.org/haiku/commit/?id=f33f4868feab
Author: Jérôme Duval <jerome.duval@xxxxxxxxx>
Date: Tue Feb 5 19:54:45 2019 UTC
Committer: Rene Gollent <rene@xxxxxxxxxxx>
Commit-Date: Wed Feb 6 16:39:33 2019 UTC
----------------------------------------------------------------------------
2 files changed, 107 insertions(+), 2 deletions(-)
headers/compatibility/gnu/spawn.h | 33 +++++++++++++++
src/system/libroot/posix/spawn.cpp | 76 +++++++++++++++++++++++++++++++++-
----------------------------------------------------------------------------
diff --git a/headers/compatibility/gnu/spawn.h
b/headers/compatibility/gnu/spawn.h
new file mode 100644
index 0000000000..6c5745f687
--- /dev/null
+++ b/headers/compatibility/gnu/spawn.h
@@ -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_ */
+
diff --git a/src/system/libroot/posix/spawn.cpp
b/src/system/libroot/posix/spawn.cpp
index 473a3b067d..bb5ddfaefc 100644
--- a/src/system/libroot/posix/spawn.cpp
+++ b/src/system/libroot/posix/spawn.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2017, Jérôme Duval, jerome.Duval@xxxxxxxxx
+ * Copyright 2017-2019, Jérôme Duval, jerome.Duval@xxxxxxxxx
* 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;
}
}