root/exec/test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_usage
  2. main

     1 /* Program execution for Emacs.
     2 
     3 Copyright (C) 2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 
    22 #include <signal.h>
    23 #include <stdio.h>
    24 #include <unistd.h>
    25 #include <stdlib.h>
    26 #include <errno.h>
    27 #include <string.h>
    28 
    29 #include <sys/wait.h>
    30 
    31 #include "exec.h"
    32 
    33 
    34 
    35 static void
    36 print_usage (void)
    37 {
    38   fprintf (stderr, "test loader-name program [args...]\n"
    39            "Run the given program using the specified loader.\n");
    40 }
    41 
    42 
    43 
    44 extern char **environ;
    45 
    46 /* This program uses libexec to wrap the execution of a child
    47    process.  */
    48 
    49 int
    50 main (int argc, char **argv)
    51 {
    52   pid_t pid, child;
    53   int sig;
    54   sigset_t sigset;
    55 
    56   /* Check that there are a sufficient number of arguments.  */
    57 
    58   if (argc < 3)
    59     {
    60       print_usage ();
    61       return 1;
    62     }
    63 
    64   exec_init (argv[1]);
    65 
    66   /* Block SIGCHLD to avoid reentrant modification of the child
    67      process list.  */
    68 
    69   sigemptyset (&sigset);
    70   sigaddset (&sigset, SIGCHLD);
    71   sigprocmask (SIG_BLOCK, &sigset, NULL);
    72 
    73   if (!(pid = fork ()))
    74     {
    75       tracing_execve (argv[2], argv + 2, environ);
    76       fprintf (stderr, "tracing_execve: %s\n",
    77                strerror (errno));
    78       exit (1);
    79     }
    80   else if (after_fork (pid))
    81     {
    82       fprintf (stderr, "after_fork: %s\n",
    83                strerror (errno));
    84       exit (1);
    85     }
    86 
    87   /* Now start waiting for child processes to exit.  */
    88 
    89   while (true)
    90     {
    91       child = exec_waitpid (-1, &sig, 0);
    92 
    93       /* If pid is -1, a system call has been handled.  */
    94 
    95       if (child == -1)
    96         continue;
    97 
    98       /* If the main process exits, then exit as well.  */
    99 
   100       if (child == pid && !WIFSTOPPED (sig))
   101         return (WIFEXITED (sig)
   102                 ? WEXITSTATUS (sig)
   103                 : WTERMSIG (sig));
   104     }
   105 }

/* [<][>][^][v][top][bottom][index][help] */