1abd6d6c32f6a35f37435475af1308b319ef8ca5dmjw#include <assert.h>
2#include <stdio.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/wait.h>
6#include <unistd.h>
7
8extern char **environ;
9
10#define S(...) (fprintf(stdout, __VA_ARGS__),fflush(stdout))
11#define FORKEXECWAIT(exec_call) do { \
12      int status;\
13      pid_t child = fork(); \
14      if (child == 0) {exec_call; perror ("exec failed");} \
15      else if (child == -1) perror ("cannot fork\n"); \
16      else if (child != wait (&status)) perror ("error waiting child"); \
17      else S("child exited\n"); \
18   } while (0)
19
20void test_allexec (char *exec)
21{
22   FORKEXECWAIT (execlp(exec, exec, (char *) NULL));
23   FORKEXECWAIT (execlp(exec, exec, "constant_arg1", "constant_arg2",
24                        (char *) NULL));
25   {
26      /* Solaris requires that the argv parameter to execve() isn't NULL, so
27         set it.  Note that this isn't necessary on Linux. */
28      char *const argv[] = {exec, NULL};
29      FORKEXECWAIT (execve(exec, argv, environ));
30   }
31}
32
33
34/* If a single argument "exec" is given, will execute itself
35   (in bi-arch, a 32 bit and 64 bit variant) via various exec system calls.
36   Note that this test can only be run after the prerequisite have been
37   prepared by allexec_prepare_prereq, which will a.o. make links
38   for the allexec32 and allexec64 executables. On single arch build,
39   these links points to the same executable to ensure this test works
40   everywhere the same.
41   No arguments or more arguments means just print its args. */
42int main(int argc, char **argv, char **envp)
43{
44   if ( (argc == 2) && (strcmp (argv[1], "exec") == 0)) {
45      S("%s will exec ./allexec32\n", argv[0]);
46      test_allexec ("./allexec32");
47      S("%s will exec ./allexec64\n", argv[0]);
48      test_allexec ("./allexec64");
49   } else {
50      int i;
51      S("program exec-ed:");
52      for (i = 0; i < argc; i++) S(" %s", argv[i]);
53      S("\n");
54   }
55   return 0;
56}
57