1/* Tests variant of SYS_execve where the first argument is a file descriptor. */
2
3#include <errno.h>
4#include <fcntl.h>
5#include <stdio.h>
6#include <unistd.h>
7#include <sys/execx.h>
8#include <sys/syscall.h>
9#include <sys/wait.h>
10
11static void test_EFAULT(void) {
12   int ret = syscall(SYS_execve, -1, 0, 0, 0);
13   int error = errno;
14   if ((ret != -1) || (error != EFAULT))
15      fprintf(stderr, "Expecting EFAULT\n");
16}
17
18static void test_EBADF(void) {
19   int ret = syscall(SYS_execve, -1, 0, 0, EXEC_DESCRIPTOR);
20   int error = errno;
21   if ((ret != -1) || (error != EBADF))
22      fprintf(stderr, "Expecting EBADF\n");
23}
24
25static int test_fexecve(char * const *envp) {
26   int fd = open("/usr/bin/printf", O_EXEC);
27   if (fd < 0) {
28      perror("open");
29      return 1;
30   }
31
32   pid_t pid = fork();
33   if (pid == -1) {
34      perror("fork");
35      return 1;
36   } else if (pid > 0) {
37      /* parent */
38   } else {
39      char *argv[] = {"printf", "PASSED\n", NULL};
40
41      if (fexecve(fd, argv, envp) < 0) {
42         perror("fexecve");
43         _exit(1);
44      }
45
46   }
47
48   wait(NULL);
49   return 0;
50}
51
52int main(int argc, const char *argv[], char * const *envp) {
53   /* First exercise the syscall with some invalid input. */
54   test_EFAULT();
55   test_EBADF();
56
57   return test_fexecve(envp);
58}
59