(root)/
glibc-2.38/
posix/
tst-execvpe6.c
       1  /* Check execvpe script argument handling.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <string.h>
      22  #include <unistd.h>
      23  #include <sys/stat.h>
      24  #include <sys/param.h>
      25  
      26  static char *fname1;
      27  static char *fname2;
      28  static char *logname;
      29  
      30  static void do_prepare (void);
      31  #define PREPARE(argc, argv) do_prepare ()
      32  static int do_test (void);
      33  #define TEST_FUNCTION do_test ()
      34  
      35  #include "../test-skeleton.c"
      36  
      37  static void
      38  do_prepare (void)
      39  {
      40    int logfd = create_temp_file ("logfile", &logname);
      41    close (logfd);
      42  
      43    int fd1 = create_temp_file ("testscript", &fname1);
      44    dprintf (fd1, "echo foo $1 $2 $3 > %s\n", logname);
      45    fchmod (fd1, 0700);
      46    close (fd1);
      47  
      48    int fd2 = create_temp_file ("testscript", &fname2);
      49    dprintf (fd2, "echo foo > %s\n", logname);
      50    fchmod (fd2, 0700);
      51    close (fd2);
      52  }
      53  
      54  static int
      55  run_script (const char *fname, char *args[])
      56  {
      57    /* We want to test the `execvpe' function.  To do this we restart the
      58       program with an additional parameter.  */
      59    int status;
      60    pid_t pid = fork ();
      61    if (pid == 0)
      62      {
      63        execvpe (fname, args, NULL);
      64  
      65        puts ("Cannot exec");
      66        exit (EXIT_FAILURE);
      67      }
      68    else if (pid == (pid_t) -1)
      69      {
      70        puts ("Cannot fork");
      71        return 1;
      72      }
      73  
      74    /* Wait for the child.  */
      75    if (waitpid (pid, &status, 0) != pid)
      76      {
      77        puts ("Wrong child");
      78        return 1;
      79      }
      80  
      81    if (WTERMSIG (status) != 0)
      82      {
      83        puts ("Child terminated incorrectly");
      84        return 1;
      85      }
      86  
      87    return 0;
      88  }
      89  
      90  static int
      91  check_output (const char *expected)
      92  {
      93    /* Check log output.  */
      94    FILE *arq = fopen (logname, "r");
      95    if (arq == NULL)
      96      {
      97        puts ("Error opening output file");
      98        return 1;
      99      }
     100  
     101    char line[128];
     102    if (fgets (line, sizeof (line), arq) == NULL)
     103      {
     104        puts ("Error reading output file");
     105        return 1;
     106      }
     107    fclose (arq);
     108  
     109    if (strcmp (line, expected) != 0)
     110      {
     111        puts ("Output file different than expected");
     112        return 1;
     113      }
     114  
     115    return 0;
     116  }
     117  
     118  static int
     119  do_test (void)
     120  {
     121    if  (setenv ("PATH", test_dir, 1) != 0)
     122      {
     123        puts ("setenv failed");
     124        return 1;
     125      }
     126  
     127    /* First check resulting script run with some arguments results in correct
     128       output file.  */
     129    char *args1[] = { fname1, (char*) "1", (char *) "2", (char *) "3", NULL };
     130    if (run_script (fname1,args1))
     131      return 1;
     132    if (check_output ("foo 1 2 3\n"))
     133      return 1;
     134  
     135    /* Same as before but with an expected empty argument list.  */
     136    char *args2[] = { fname2, NULL };
     137    if (run_script (fname2, args2))
     138      return 1;
     139    if (check_output ("foo\n"))
     140      return 1;
     141  
     142    /* Same as before but with an empty argument list.  */
     143    char *args3[] = { NULL };
     144    if (run_script (fname2, args3))
     145      return 1;
     146    if (check_output ("foo\n"))
     147      return 1;
     148  
     149    return 0;
     150  }