(root)/
gettext-0.22.4/
gettext-tools/
gnulib-tests/
test-execute-script.c
       1  /* Test of execute.
       2     Copyright (C) 2020-2023 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 <stdio.h>
      22  #include <string.h>
      23  #include <unistd.h>
      24  
      25  #include "read-file.h"
      26  #include "macros.h"
      27  
      28  #define DATA_FILENAME "test-execute-script.tmp"
      29  
      30  int
      31  main ()
      32  {
      33    unlink (DATA_FILENAME);
      34  
      35    /* Check an invocation of an executable script.
      36       This should only be supported if the script has a '#!' marker; otherwise
      37       it is unsecure: <https://sourceware.org/bugzilla/show_bug.cgi?id=13134>.
      38       POSIX says that the execlp() and execvp() functions support executing
      39       shell scripts
      40       <https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html>,
      41       but this is considered an antiquated feature.  */
      42  
      43    /* This test is an extension of
      44       "Check stdout is inherited, part 1 (regular file)"
      45       in test-execute-main.c.  */
      46    FILE *fp = freopen (DATA_FILENAME, "w", stdout);
      47    ASSERT (fp != NULL);
      48  
      49    {
      50      size_t i;
      51  
      52      for (i = 0; i < 2; i++)
      53        {
      54          const char *progname =
      55            (i == 0 ? "executable-script" : "executable-script.sh");
      56          const char *prog_path =
      57            (i == 0 ? SRCDIR "executable-script" : SRCDIR "executable-script.sh");
      58          const char *prog_argv[2] = { prog_path, NULL };
      59  
      60          int ret = execute (progname, prog_argv[0], prog_argv, NULL,
      61                             false, false, false, false, true, false, NULL);
      62          ASSERT (ret == 127);
      63        }
      64    }
      65  
      66  #if defined _WIN32 && !defined __CYGWIN__
      67    /* On native Windows, scripts - even with '#!' marker - are not executable.
      68       Only .bat and .cmd files are.  */
      69    ASSERT (fclose (fp) == 0);
      70    ASSERT (unlink (DATA_FILENAME) == 0);
      71    fprintf (stderr, "Skipping test: scripts are not executable on this platform.\n");
      72    return 77;
      73  #else
      74    {
      75      const char *progname = "executable-shell-script";
      76      const char *prog_path = SRCDIR "executable-shell-script";
      77      const char *prog_argv[2] = { prog_path, NULL };
      78  
      79      int ret = execute (progname, prog_argv[0], prog_argv, NULL,
      80                         false, false, false, false, true, false, NULL);
      81      ASSERT (ret == 0);
      82  
      83      ASSERT (fclose (fp) == 0);
      84  
      85      size_t length;
      86      char *contents = read_file (DATA_FILENAME, 0, &length);
      87      ASSERT (length == 11 && memcmp (contents, "Halle Potta", 11) == 0);
      88    }
      89  
      90    ASSERT (unlink (DATA_FILENAME) == 0);
      91  
      92    return 0;
      93  #endif
      94  }