<spawn.h>: add posix_spawn_file_actions_addchdir_np()/posix_spawn_file_actions_addfchdir_np().
The recent header nullability additions and the corresponding source
cleanup made me notice that we're missing a couple of actions that most
of the other implementations have. They've also been added to the _next_
revision of POSIX, unchanged except for the removal of the `_np` suffix.
They're trivial to implement, the testing is quite simple too, and
if they're going to be in POSIX soon, having them accessible in older
versions of Android via __RENAME() seems useful. (No-one else has shipped
the POSIX names yet.)
Bug: http://b/152414297
Test: treehugger
Change-Id: I0d2a1e47fbd2e826cff9c45038928aa1b6fcce59
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 5cf95d8..5d76f77 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -68,7 +68,9 @@
enum Action {
kOpen,
kClose,
- kDup2
+ kDup2,
+ kChdir,
+ kFchdir,
};
struct __posix_spawn_file_action {
@@ -93,6 +95,10 @@
} else if (what == kClose) {
// Failure to close is ignored.
close(fd);
+ } else if (what == kChdir) {
+ if (chdir(path) == -1) _exit(127);
+ } else if (what == kFchdir) {
+ if (fchdir(fd) == -1) _exit(127);
} else {
// It's a dup2.
if (fd == new_fd) {
@@ -340,7 +346,7 @@
if (action == nullptr) return errno;
action->next = nullptr;
- if (what == kOpen) {
+ if (what == kOpen || what == kChdir) {
action->path = strdup(path);
if (action->path == nullptr) {
free(action);
@@ -380,3 +386,12 @@
if (fd < 0 || new_fd < 0) return EBADF;
return posix_spawn_add_file_action(actions, kDup2, fd, new_fd, nullptr, 0, 0);
}
+
+int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t* actions, const char* path) {
+ return posix_spawn_add_file_action(actions, kChdir, -1, -1, path, 0, 0);
+}
+
+int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t* actions, int fd) {
+ if (fd < 0) return EBADF;
+ return posix_spawn_add_file_action(actions, kFchdir, fd, -1, nullptr, 0, 0);
+}
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index 8bb34d0..6c34b98 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -87,6 +87,9 @@
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(28);
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, const char* _Nonnull __path) __INTRODUCED_IN(34);
+int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(34);
+
__END_DECLS
#endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 4a4e607..c75b13a 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1580,6 +1580,8 @@
close_range;
copy_file_range;
memset_explicit;
+ posix_spawn_file_actions_addchdir_np;
+ posix_spawn_file_actions_addfchdir_np;
} LIBC_T;
LIBC_PRIVATE {