Add POSIX fexecve.
I'm skeptical about the usefulness of this, but it's in POSIX, it's
in glibc (but not iOS), and it is used in some internal source (test
runners and container code).
Bug: N/A
Test: ran tests
Change-Id: I92c5398f2a679b21a33fba92bc8e67e3ae2eb76f
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index ced0315..7c67cce 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1376,6 +1376,41 @@
"<unknown>: usage: run-as");
}
+TEST(UNISTD_TEST, fexecve_failure) {
+ ExecTestHelper eth;
+ errno = 0;
+ int fd = open("/", O_RDONLY);
+ ASSERT_NE(-1, fd);
+ ASSERT_EQ(-1, fexecve(fd, eth.GetArgs(), eth.GetEnv()));
+ ASSERT_EQ(EACCES, errno);
+ close(fd);
+}
+
+TEST(UNISTD_TEST, fexecve_bad_fd) {
+ ExecTestHelper eth;
+ errno = 0;
+ ASSERT_EQ(-1, fexecve(-1, eth.GetArgs(), eth.GetEnv()));
+ ASSERT_EQ(EBADF, errno);
+}
+
+TEST(UNISTD_TEST, fexecve_args) {
+ // Test basic argument passing.
+ int echo_fd = open(BIN_DIR "echo", O_RDONLY | O_CLOEXEC);
+ ASSERT_NE(-1, echo_fd);
+ ExecTestHelper eth;
+ eth.SetArgs({"echo", "hello", "world", nullptr});
+ eth.Run([&]() { fexecve(echo_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "hello world\n");
+ close(echo_fd);
+
+ // Test environment variable setting too.
+ int printenv_fd = open(BIN_DIR "printenv", O_RDONLY | O_CLOEXEC);
+ ASSERT_NE(-1, printenv_fd);
+ eth.SetArgs({"printenv", nullptr});
+ eth.SetEnv({"A=B", nullptr});
+ eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+ close(printenv_fd);
+}
+
TEST(UNISTD_TEST, getlogin_r) {
char buf[LOGIN_NAME_MAX] = {};
EXPECT_EQ(ERANGE, getlogin_r(buf, 0));