12aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#include <assert.h>
22aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#include <stdio.h>
32aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#include <string.h>
42aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#include <sys/types.h>
52aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#include <sys/wait.h>
62aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#include <unistd.h>
72aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe
82aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippeextern char **environ;
92aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe
102aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#define S(...) (fprintf(stdout, __VA_ARGS__),fflush(stdout))
112aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe#define FORKEXECWAIT(exec_call) do { \
122aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      int status;\
132aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      pid_t child = fork(); \
142aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      if (child == 0) {exec_call; perror ("exec failed");} \
152aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      else if (child == -1) perror ("cannot fork\n"); \
162aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      else if (child != wait (&status)) perror ("error waiting child"); \
172aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      else S("child exited\n"); \
182aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   } while (0)
192aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe
202aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippevoid test_allexec (char *exec)
212aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe{
228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   FORKEXECWAIT (execlp(exec, exec, (char *) NULL));
238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   FORKEXECWAIT (execlp(exec, exec, "constant_arg1", "constant_arg2",
248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj                        (char *) NULL));
258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   {
268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      /* Solaris requires that the argv parameter to execve() isn't NULL, so
278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         set it.  Note that this isn't necessary on Linux. */
288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      char *const argv[] = {exec, NULL};
298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      FORKEXECWAIT (execve(exec, argv, environ));
308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   }
312aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe}
322aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe
332aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe
342aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe/* If a single argument "exec" is given, will execute itself
352aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   (in bi-arch, a 32 bit and 64 bit variant) via various exec system calls.
362aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   Note that this test can only be run after the prerequisite have been
372aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   prepared by allexec_prepare_prereq, which will a.o. make links
382aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   for the allexec32 and allexec64 executables. On single arch build,
392aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   these links points to the same executable to ensure this test works
402aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   everywhere the same.
412aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   No arguments or more arguments means just print its args. */
4234ff174f3cef6e6058385c0a404572d5e8e5c67cdejanjint main(int argc, char **argv, char **envp)
432aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe{
442aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   if ( (argc == 2) && (strcmp (argv[1], "exec") == 0)) {
452aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      S("%s will exec ./allexec32\n", argv[0]);
462aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      test_allexec ("./allexec32");
472aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      S("%s will exec ./allexec64\n", argv[0]);
482aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      test_allexec ("./allexec64");
492aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   } else {
502aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      int i;
512aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      S("program exec-ed:");
522aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      for (i = 0; i < argc; i++) S(" %s", argv[i]);
532aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe      S("\n");
542aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   }
552aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe   return 0;
562aeaf8e8f171a27a2ca6c2c71df4ba7527099f52philippe}
57