Merge "<spawn.h>: add posix_spawn_file_actions_addchdir_np()/posix_spawn_file_actions_addfchdir_np()."
This commit is contained in:
commit
7b5cc4b251
5 changed files with 46 additions and 4 deletions
|
@ -59,6 +59,9 @@ New libc functions in U (API level 34):
|
|||
* `close_range` and `copy_file_range` (Linux-specific GNU extensions).
|
||||
* `memset_explicit` in <string.h> (C23 addition).
|
||||
* `__freadahead` in <stdio_ext.h> (in musl but not glibc).
|
||||
* `posix_spawn_file_actions_addchdir_np` and
|
||||
`posix_spawn_file_actions_addfchdir_np` in <spawn.h> (in musl/glibc
|
||||
and macOS, but not iOS).
|
||||
|
||||
New libc behavior in U (API level 34):
|
||||
* Support for `%b` and `%B` in the printf/wprintf family, `%b` in the
|
||||
|
|
|
@ -68,7 +68,9 @@ static int cloexec_except_stdioe() {
|
|||
enum Action {
|
||||
kOpen,
|
||||
kClose,
|
||||
kDup2
|
||||
kDup2,
|
||||
kChdir,
|
||||
kFchdir,
|
||||
};
|
||||
|
||||
struct __posix_spawn_file_action {
|
||||
|
@ -93,6 +95,10 @@ struct __posix_spawn_file_action {
|
|||
} 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 @@ static int posix_spawn_add_file_action(posix_spawn_file_actions_t* actions,
|
|||
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 @@ int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* actions, int fd
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -87,6 +87,9 @@ int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t _Nonnull * _Nonn
|
|||
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
|
||||
|
|
|
@ -1580,6 +1580,8 @@ LIBC_U { # introduced=UpsideDownCake
|
|||
close_range;
|
||||
copy_file_range;
|
||||
memset_explicit;
|
||||
posix_spawn_file_actions_addchdir_np;
|
||||
posix_spawn_file_actions_addfchdir_np;
|
||||
} LIBC_T;
|
||||
|
||||
LIBC_PRIVATE {
|
||||
|
|
|
@ -232,18 +232,28 @@ TEST(spawn, posix_spawn_environment) {
|
|||
}
|
||||
|
||||
TEST(spawn, posix_spawn_file_actions) {
|
||||
#if !defined(__GLIBC__)
|
||||
int fds[2];
|
||||
ASSERT_NE(-1, pipe(fds));
|
||||
|
||||
posix_spawn_file_actions_t fa;
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
|
||||
|
||||
// Test addclose and adddup2 by redirecting output to the pipe created above.
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
|
||||
// Check that close(2) failures are ignored by closing the same fd again.
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
|
||||
// Open a file directly, to test addopen.
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 56, "/proc/version", O_RDONLY, 0));
|
||||
// Test addfchdir by opening the same file a second way...
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 57, "/proc", O_PATH, 0));
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addfchdir_np(&fa, 57));
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 58, "version", O_RDONLY, 0));
|
||||
// Test addchdir by opening the same file a third way...
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addchdir_np(&fa, "/"));
|
||||
ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 59, "proc/version", O_RDONLY, 0));
|
||||
|
||||
ExecTestHelper eth;
|
||||
eth.SetArgs({"ls", "-l", "/proc/self/fd", nullptr});
|
||||
|
@ -259,12 +269,21 @@ TEST(spawn, posix_spawn_file_actions) {
|
|||
AssertChildExited(pid, 0);
|
||||
|
||||
// We'll know the dup2 worked if we see any ls(1) output in our pipe.
|
||||
// The open we can check manually...
|
||||
// The opens we can check manually (and they implicitly check the chdirs)...
|
||||
bool open_to_fd_56_worked = false;
|
||||
bool open_to_fd_58_worked = false;
|
||||
bool open_to_fd_59_worked = false;
|
||||
for (const auto& line : android::base::Split(content, "\n")) {
|
||||
if (line.find(" 56 -> /proc/version") != std::string::npos) open_to_fd_56_worked = true;
|
||||
if (line.find(" 58 -> /proc/version") != std::string::npos) open_to_fd_58_worked = true;
|
||||
if (line.find(" 59 -> /proc/version") != std::string::npos) open_to_fd_59_worked = true;
|
||||
}
|
||||
ASSERT_TRUE(open_to_fd_56_worked);
|
||||
ASSERT_TRUE(open_to_fd_56_worked) << content;
|
||||
ASSERT_TRUE(open_to_fd_58_worked) << content;
|
||||
ASSERT_TRUE(open_to_fd_59_worked) << content;
|
||||
#else
|
||||
GTEST_SKIP() << "our old glibc doesn't have the chdirs; newer versions and musl do.";
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CatFileToString(posix_spawnattr_t* sa, const char* path, std::string* content) {
|
||||
|
|
Loading…
Reference in a new issue