Blame posix/tst-execvpe5.c

Packit 6c4009
/* General tests for execpve.
Packit 6c4009
   Copyright (C) 2016-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <fcntl.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <unistd.h>
Packit 6c4009
#include <wait.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Nonzero if the program gets called via `exec'.  */
Packit 6c4009
static int restart;
Packit 6c4009
Packit 6c4009
Packit 6c4009
#define CMDLINE_OPTIONS \
Packit 6c4009
  { "restart", no_argument, &restart, 1 },
Packit 6c4009
Packit 6c4009
/* Prototype for our test function.  */
Packit 6c4009
extern void do_prepare (int argc, char *argv[]);
Packit 6c4009
extern int do_test (int argc, char *argv[]);
Packit 6c4009
Packit 6c4009
#include "../test-skeleton.c"
Packit 6c4009
Packit 6c4009
#define EXECVPE_KEY    "EXECVPE_ENV"
Packit 6c4009
#define EXECVPE_VALUE  "execvpe_test"
Packit 6c4009
Packit 6c4009
Packit 6c4009
static int
Packit 6c4009
handle_restart (void)
Packit 6c4009
{
Packit 6c4009
  /* First check if only one variable is passed on execvpe.  */
Packit 6c4009
  int env_count = 0;
Packit 6c4009
  for (char **e = environ; *e != NULL; ++e)
Packit 6c4009
    if (++env_count == INT_MAX)
Packit 6c4009
      {
Packit 6c4009
	printf ("Environment variable number overflow");
Packit 6c4009
	exit (EXIT_FAILURE);
Packit 6c4009
      }
Packit 6c4009
  if (env_count != 1)
Packit 6c4009
    {
Packit 6c4009
      printf ("Wrong number of environment variables");
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Check if the combinarion os "EXECVPE_ENV=execvpe_test"  */
Packit 6c4009
  const char *env = getenv (EXECVPE_KEY);
Packit 6c4009
  if (env == NULL)
Packit 6c4009
    {
Packit 6c4009
      printf ("Test environment variable not found");
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (strncmp (env, EXECVPE_VALUE, sizeof (EXECVPE_VALUE)))
Packit 6c4009
    {
Packit 6c4009
      printf ("Test environment variable with wrong value");
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
do_test (int argc, char *argv[])
Packit 6c4009
{
Packit 6c4009
  pid_t pid;
Packit 6c4009
  int status;
Packit 6c4009
Packit 6c4009
  /* We must have
Packit 6c4009
     - one or four parameters left if called initially
Packit 6c4009
       + path for ld.so		optional
Packit 6c4009
       + "--library-path"	optional
Packit 6c4009
       + the library path	optional
Packit 6c4009
       + the application name
Packit 6c4009
Packit 6c4009
    if --enable-hardcoded-path-in-tests is used, just
Packit 6c4009
      + the application name
Packit 6c4009
  */
Packit 6c4009
Packit 6c4009
  if (restart)
Packit 6c4009
    {
Packit 6c4009
      if (argc != 1)
Packit 6c4009
	{
Packit 6c4009
	  printf ("Wrong number of arguments (%d) in restart\n", argc);
Packit 6c4009
	  exit (EXIT_FAILURE);
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      return handle_restart ();
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (argc != 2 && argc != 5)
Packit 6c4009
    {
Packit 6c4009
      printf ("Wrong number of arguments (%d)\n", argc);
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* We want to test the `execvpe' function.  To do this we restart the
Packit 6c4009
     program with an additional parameter.  */
Packit 6c4009
  pid = fork ();
Packit 6c4009
  if (pid == 0)
Packit 6c4009
    {
Packit 6c4009
      /* This is the child.  Construct the command line.  */
Packit 6c4009
Packit 6c4009
      /* We cast here to char* because the test itself does not modify neither
Packit 6c4009
	 the argument nor the environment list.  */
Packit 6c4009
      char *envs[] = { (char*)(EXECVPE_KEY "=" EXECVPE_VALUE), NULL };
Packit 6c4009
      if (argc == 5)
Packit 6c4009
	{
Packit 6c4009
	  char *args[] = { argv[1], argv[2], argv[3], argv[4],
Packit 6c4009
			   (char *) "--direct", (char *) "--restart", NULL };
Packit 6c4009
	  execvpe (args[0], args, envs);
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
	  char *args[] = { argv[0],
Packit 6c4009
			   (char *) "--direct", (char *) "--restart", NULL };
Packit 6c4009
	  execvpe (args[0], args, envs);
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      puts ("Cannot exec");
Packit 6c4009
      exit (EXIT_FAILURE);
Packit 6c4009
    }
Packit 6c4009
  else if (pid == (pid_t) -1)
Packit 6c4009
    {
Packit 6c4009
      puts ("Cannot fork");
Packit 6c4009
      return 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Wait for the child.  */
Packit 6c4009
  if (waitpid (pid, &status, 0) != pid)
Packit 6c4009
    {
Packit 6c4009
      puts ("Wrong child");
Packit 6c4009
      return 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (WTERMSIG (status) != 0)
Packit 6c4009
    {
Packit 6c4009
      puts ("Child terminated incorrectly");
Packit 6c4009
      return 1;
Packit 6c4009
    }
Packit 6c4009
  status = WEXITSTATUS (status);
Packit 6c4009
Packit 6c4009
  return status;
Packit 6c4009
}