(root)/
m4-1.4.19/
tests/
test-execute-script.c
       1  /* Test of execute.
       2     Copyright (C) 2020-2021 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3, or (at your option)
       7     any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program; if not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include <config.h>
      18  
      19  #include "execute.h"
      20  
      21  #include <stdbool.h>
      22  #include <stdio.h>
      23  #include <string.h>
      24  #include <unistd.h>
      25  
      26  #include "read-file.h"
      27  #include "macros.h"
      28  
      29  #define DATA_FILENAME "test-execute-script.tmp"
      30  
      31  int
      32  main ()
      33  {
      34    unlink (DATA_FILENAME);
      35  
      36    /* Check an invocation of an executable script.
      37       This should only be supported if the script has a '#!' marker; otherwise
      38       it is unsecure: <https://sourceware.org/bugzilla/show_bug.cgi?id=13134>.
      39       POSIX says that the execlp() and execvp() functions support executing
      40       shell scripts
      41       <https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html>,
      42       but this is considered an antiquated feature.  */
      43  
      44    /* This test is an extension of
      45       "Check stdout is inherited, part 1 (regular file)"
      46       in test-execute-main.c.  */
      47    FILE *fp = freopen (DATA_FILENAME, "w", stdout);
      48    ASSERT (fp != NULL);
      49  
      50    {
      51      size_t i;
      52  
      53      for (i = 0; i < 2; i++)
      54        {
      55          const char *progname =
      56            (i == 0 ? "executable-script" : "executable-script.sh");
      57          const char *prog_path =
      58            (i == 0 ? SRCDIR "executable-script" : SRCDIR "executable-script.sh");
      59          const char *prog_argv[2] = { prog_path, NULL };
      60  
      61          int ret = execute (progname, prog_argv[0], prog_argv, NULL,
      62                             false, false, false, false, true, false, NULL);
      63          ASSERT (ret == 127);
      64        }
      65    }
      66  
      67  #if defined _WIN32 && !defined __CYGWIN__
      68    /* On native Windows, scripts - even with '#!' marker - are not executable.
      69       Only .bat and .cmd files are.  */
      70    ASSERT (fclose (fp) == 0);
      71    ASSERT (unlink (DATA_FILENAME) == 0);
      72    fprintf (stderr, "Skipping test: scripts are not executable on this platform.\n");
      73    return 77;
      74  #else
      75    {
      76      const char *progname = "executable-shell-script";
      77      const char *prog_path = SRCDIR "executable-shell-script";
      78      const char *prog_argv[2] = { prog_path, NULL };
      79  
      80      int ret = execute (progname, prog_argv[0], prog_argv, NULL,
      81                         false, false, false, false, true, false, NULL);
      82      ASSERT (ret == 0);
      83  
      84      ASSERT (fclose (fp) == 0);
      85  
      86      size_t length;
      87      char *contents = read_file (DATA_FILENAME, 0, &length);
      88      ASSERT (length == 11 && memcmp (contents, "Halle Potta", 11) == 0);
      89    }
      90  
      91    ASSERT (unlink (DATA_FILENAME) == 0);
      92  
      93    return 0;
      94  #endif
      95  }