Back to index

cell-binutils  2.17cvs20070401
Defines | Functions
test-pexecute.c File Reference
#include "ansidecl.h"
#include "libiberty.h"
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>

Go to the source code of this file.

Defines

#define WIFSIGNALED(S)   (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
#define WTERMSIG(S)   ((S) & 0x7f)
#define WIFEXITED(S)   (((S) & 0xff) == 0)
#define WEXITSTATUS(S)   (((S) & 0xff00) >> 8)
#define WSTOPSIG   WEXITSTATUS
#define WCOREDUMP(S)   ((S) & WCOREFLG)
#define WCOREFLG   0200
#define EXIT_SUCCESS   0
#define EXIT_FAILURE   1
#define FATAL_ERROR(ERRMSG, ERR)   fatal_error (__LINE__, ERRMSG, ERR)
#define ERROR(ERRMSG)   error (__LINE__, ERRMSG)
#define CHECK_LINE(E, STR)   check_line (__LINE__, E, STR)
#define TEST_PEX_INIT(FLAGS, TEMPBASE)
#define TEST_PEX_RUN(PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, ERRNAME)
#define TEST_PEX_GET_STATUS_1(PEXOBJ)
#define TEST_PEX_GET_STATUS(PEXOBJ, COUNT, VECTOR)
#define TEST_PEX_READ_OUTPUT(PEXOBJ)

Functions

static void fatal_error (static void error(int, const char *, static void error(int)
static void error (int line, const char *errmsg)
static void check_line (int line, FILE *e, const char *str)
int main (int argc, char **argv)
static void do_cmd (int argc, char **argv)

Define Documentation

#define CHECK_LINE (   E,
  STR 
)    check_line (__LINE__, E, STR)

Definition at line 173 of file test-pexecute.c.

#define ERROR (   ERRMSG)    error (__LINE__, ERRMSG)

Definition at line 131 of file test-pexecute.c.

#define EXIT_FAILURE   1

Definition at line 77 of file test-pexecute.c.

#define EXIT_SUCCESS   0

Definition at line 73 of file test-pexecute.c.

#define FATAL_ERROR (   ERRMSG,
  ERR 
)    fatal_error (__LINE__, ERRMSG, ERR)

Definition at line 118 of file test-pexecute.c.

#define TEST_PEX_GET_STATUS (   PEXOBJ,
  COUNT,
  VECTOR 
)
Value:
do                                                             \
    {                                                          \
      if (!pex_get_status (PEXOBJ, COUNT, VECTOR))                    \
       FATAL_ERROR ("pex_get_status failed", errno);                  \
    }                                                          \
  while (0)
#define TEST_PEX_GET_STATUS_1 (   PEXOBJ)
Value:
(pex_get_status (PEXOBJ, 1, &test_pex_status)                         \
   ? test_pex_status                                           \
   : (FATAL_ERROR ("pex_get_status failed", errno), 1))
#define TEST_PEX_INIT (   FLAGS,
  TEMPBASE 
)
Value:
(((test_pex_tmp = pex_init (FLAGS, "test-pexecute", TEMPBASE)) \
    != NULL)                                                   \
   ? test_pex_tmp                                              \
   : (FATAL_ERROR ("pex_init failed", 0), NULL))
#define TEST_PEX_READ_OUTPUT (   PEXOBJ)
Value:
((test_pex_file = pex_read_output (PEXOBJ, 0)) != NULL         \
   ? test_pex_file                                             \
   : (FATAL_ERROR ("pex_read_output failed", errno), NULL))
#define TEST_PEX_RUN (   PEXOBJ,
  FLAGS,
  EXECUTABLE,
  ARGV,
  OUTNAME,
  ERRNAME 
)
Value:
do                                                             \
    {                                                          \
      int err;                                                        \
      const char *pex_run_err;                                        \
      if (trace)                                               \
       fprintf (stderr, "Line %d: running %s %s\n",                   \
               __LINE__, EXECUTABLE, ARGV[0]);                 \
      pex_run_err = pex_run (PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME,       \
                          ERRNAME, &err);                      \
      if (pex_run_err != NULL)                                        \
       FATAL_ERROR (pex_run_err, err);                                \
    }                                                          \
  while (0)
#define WCOREDUMP (   S)    ((S) & WCOREFLG)

Definition at line 66 of file test-pexecute.c.

#define WCOREFLG   0200

Definition at line 69 of file test-pexecute.c.

#define WEXITSTATUS (   S)    (((S) & 0xff00) >> 8)

Definition at line 60 of file test-pexecute.c.

#define WIFEXITED (   S)    (((S) & 0xff) == 0)

Definition at line 57 of file test-pexecute.c.

#define WIFSIGNALED (   S)    (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)

Definition at line 51 of file test-pexecute.c.

#define WSTOPSIG   WEXITSTATUS

Definition at line 63 of file test-pexecute.c.

#define WTERMSIG (   S)    ((S) & 0x7f)

Definition at line 54 of file test-pexecute.c.


Function Documentation

static void check_line ( int  line,
FILE *  e,
const char *  str 
) [static]

Definition at line 136 of file test-pexecute.c.

{
  const char *p;
  int c;
  char buf[1000];

  p = str;
  while (1)
    {
      c = getc (e);

      if (*p == '\0')
       {
         if (c != '\n')
           {
             snprintf (buf, sizeof buf, "got '%c' when expecting newline", c);
             fatal_error (line, buf, 0);
           }
         c = getc (e);
         if (c != EOF)
           {
             snprintf (buf, sizeof buf, "got '%c' when expecting EOF", c);
             fatal_error (line, buf, 0);
           }
         return;
       }

      if (c != *p)
       {
         snprintf (buf, sizeof buf, "expected '%c', got '%c'", *p, c);
         fatal_error (line, buf, 0);
       }

      ++p;
    }
}

Here is the call graph for this function:

static void do_cmd ( int  argc,
char **  argv 
) [static]

Definition at line 442 of file test-pexecute.c.

{
  const char *s;

  /* Try to prevent generating a core dump.  */
#ifdef RLIMIT_CORE
 {
   struct rlimit r;

   r.rlim_cur = 0;
   r.rlim_max = 0;
   setrlimit (RLIMIT_CORE, &r);
 }
#endif

  s = argv[1];
  if (strcmp (s, "exit") == 0)
    exit (EXIT_SUCCESS);
  else if (strcmp (s, "echo") == 0)
    {
      int i;

      for (i = 2; i < argc; ++i)
       {
         if (i > 2)
           putchar (' ');
         fputs (argv[i], stdout);
       }
      putchar ('\n');
      exit (EXIT_SUCCESS);
    }
  else if (strcmp (s, "echoerr") == 0)
    {
      int i;

      for (i = 2; i < argc; ++i)
       {
         if (i > 3)
           putc (' ', (i & 1) == 0 ? stdout : stderr);
         fputs (argv[i], (i & 1) == 0 ? stdout : stderr);
       }
      putc ('\n', stdout);
      putc ('\n', stderr);
      exit (EXIT_SUCCESS);
    }
  else if (strcmp (s, "error") == 0)
    exit (EXIT_FAILURE);
  else if (strcmp (s, "abort") == 0)
    abort ();
  else if (strcmp (s, "copy") == 0)
    {
      int c;

      while ((c = getchar ()) != EOF)
       putchar (c);
      exit (EXIT_SUCCESS);
    }
  else if (strcmp (s, "write") == 0)
    {
      FILE *e;
      int c;

      e = fopen (argv[2], "w");
      if (e == NULL)
       FATAL_ERROR ("fopen for write failed", errno);
      while ((c = getchar ()) != EOF)
       putc (c, e);
      if (fclose (e) != 0)
       FATAL_ERROR ("fclose for write failed", errno);
      exit (EXIT_SUCCESS);
    }
  else
    {
      char buf[1000];

      snprintf (buf, sizeof buf, "unrecognized command %s", argv[1]);
      FATAL_ERROR (buf, 0);
    }

  exit (EXIT_FAILURE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void error ( int  line,
const char *  errmsg 
) [static]

Definition at line 125 of file test-pexecute.c.

{
  fprintf (stderr, "test-pexecute:%d: %s\n", line, errmsg);
  ++error_count;
}

Here is the call graph for this function:

static void fatal_error ( static void error int,
const char *  ,
static void error int 
) [static]

Definition at line 95 of file test-pexecute.c.

{
  fprintf (stderr, "test-pexecute:%d: %s", line, errmsg);
  if (errno != 0)
    fprintf (stderr, ": %s", xstrerror (err));
  fprintf (stderr, "\n");
  exit (EXIT_FAILURE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 178 of file test-pexecute.c.

{
  int trace;
  struct pex_obj *test_pex_tmp;
  int test_pex_status;
  FILE *test_pex_file;
  struct pex_obj *pex1;
  char *subargv[10];
  int status;
  FILE *e;
  int statuses[10];

  trace = 0;
  if (argc > 1 && strcmp (argv[1], "-t") == 0)
    {
      trace = 1;
      --argc;
      ++argv;
    }

  if (argc > 1)
    do_cmd (argc, argv);

#define TEST_PEX_INIT(FLAGS, TEMPBASE)                                \
  (((test_pex_tmp = pex_init (FLAGS, "test-pexecute", TEMPBASE))      \
    != NULL)                                                   \
   ? test_pex_tmp                                              \
   : (FATAL_ERROR ("pex_init failed", 0), NULL))

#define TEST_PEX_RUN(PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, ERRNAME)      \
  do                                                           \
    {                                                          \
      int err;                                                        \
      const char *pex_run_err;                                        \
      if (trace)                                               \
       fprintf (stderr, "Line %d: running %s %s\n",                   \
               __LINE__, EXECUTABLE, ARGV[0]);                 \
      pex_run_err = pex_run (PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME,       \
                          ERRNAME, &err);                      \
      if (pex_run_err != NULL)                                        \
       FATAL_ERROR (pex_run_err, err);                                \
    }                                                          \
  while (0)

#define TEST_PEX_GET_STATUS_1(PEXOBJ)                                 \
  (pex_get_status (PEXOBJ, 1, &test_pex_status)                       \
   ? test_pex_status                                           \
   : (FATAL_ERROR ("pex_get_status failed", errno), 1))

#define TEST_PEX_GET_STATUS(PEXOBJ, COUNT, VECTOR)                    \
  do                                                           \
    {                                                          \
      if (!pex_get_status (PEXOBJ, COUNT, VECTOR))                    \
       FATAL_ERROR ("pex_get_status failed", errno);                  \
    }                                                          \
  while (0)

#define TEST_PEX_READ_OUTPUT(PEXOBJ)                                  \
  ((test_pex_file = pex_read_output (PEXOBJ, 0)) != NULL              \
   ? test_pex_file                                             \
   : (FATAL_ERROR ("pex_read_output failed", errno), NULL))

  remove ("temp.x");
  remove ("temp.y");

  memset (subargv, 0, sizeof subargv);

  subargv[0] = "./test-pexecute";

  pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
  subargv[1] = "exit";
  subargv[2] = NULL;
  TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL);
  status = TEST_PEX_GET_STATUS_1 (pex1);
  if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
    ERROR ("exit failed");
  pex_free (pex1);

  pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
  subargv[1] = "error";
  subargv[2] = NULL;
  TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL);
  status = TEST_PEX_GET_STATUS_1 (pex1);
  if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_FAILURE)
    ERROR ("error test failed");
  pex_free (pex1);

  /* We redirect stderr to a file to avoid an error message which is
     printed on mingw32 when the child calls abort.  */
  pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL);
  subargv[1] = "abort";
  subargv[2] = NULL;
  TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, "temp.z");
  status = TEST_PEX_GET_STATUS_1 (pex1);
  if (!WIFSIGNALED (status) || WTERMSIG (status) != SIGABRT)
    ERROR ("abort failed");
  pex_free (pex1);
  remove ("temp.z");

  pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
  subargv[1] = "echo";
  subargv[2] = "foo";
  subargv[3] = NULL;
  TEST_PEX_RUN (pex1, 0, "./test-pexecute", subargv, NULL, NULL);
  e = TEST_PEX_READ_OUTPUT (pex1);
  CHECK_LINE (e, "foo");
  if (TEST_PEX_GET_STATUS_1 (pex1) != 0)
    ERROR ("echo exit status failed");
  pex_free (pex1);

  pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
  subargv[1] = "echo";
  subargv[2] = "bar";
  subargv[3] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
  subargv[1] = "copy";
  subargv[2] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
  e = TEST_PEX_READ_OUTPUT (pex1);
  CHECK_LINE (e, "bar");
  TEST_PEX_GET_STATUS (pex1, 2, statuses);
  if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
      || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    ERROR ("copy exit status failed");
  pex_free (pex1);
  if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
    ERROR ("temporary files exist");

  pex1 = TEST_PEX_INIT (0, "temp");
  subargv[1] = "echo";
  subargv[2] = "bar";
  subargv[3] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
  subargv[1] = "copy";
  subargv[2] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
  e = TEST_PEX_READ_OUTPUT (pex1);
  CHECK_LINE (e, "bar");
  TEST_PEX_GET_STATUS (pex1, 2, statuses);
  if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
      || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    ERROR ("copy exit status failed");
  pex_free (pex1);
  if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
    ERROR ("temporary files exist");

  pex1 = TEST_PEX_INIT (PEX_SAVE_TEMPS, "temp");
  subargv[1] = "echo";
  subargv[2] = "quux";
  subargv[3] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL);
  subargv[1] = "copy";
  subargv[2] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
  e = TEST_PEX_READ_OUTPUT (pex1);
  CHECK_LINE (e, "quux");
  TEST_PEX_GET_STATUS (pex1, 2, statuses);
  if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
      || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    ERROR ("copy temp exit status failed");
  e = fopen ("temp.x", "r");
  if (e == NULL)
    FATAL_ERROR ("fopen temp.x failed in copy temp", errno);
  CHECK_LINE (e, "quux");
  fclose (e);
  e = fopen ("temp.y", "r");
  if (e == NULL)
    FATAL_ERROR ("fopen temp.y failed in copy temp", errno);
  CHECK_LINE (e, "quux");
  fclose (e);
  pex_free (pex1);
  remove ("temp.x");
  remove ("temp.y");

  pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp");
  subargv[1] = "echoerr";
  subargv[2] = "one";
  subargv[3] = "two";
  subargv[4] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", "temp2.x");
  subargv[1] = "write";
  subargv[2] = "temp2.y";
  subargv[3] = NULL;
  TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL);
  TEST_PEX_GET_STATUS (pex1, 2, statuses);
  if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS
      || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS)
    ERROR ("echoerr exit status failed");
  pex_free (pex1);
  if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL)
    ERROR ("temporary files exist");
  e = fopen ("temp2.x", "r");
  if (e == NULL)
    FATAL_ERROR ("fopen temp2.x failed in echoerr", errno);
  CHECK_LINE (e, "two");
  fclose (e);
  e = fopen ("temp2.y", "r");
  if (e == NULL)
    FATAL_ERROR ("fopen temp2.y failed in echoerr", errno);
  CHECK_LINE (e, "one");
  fclose (e);
  remove ("temp2.x");
  remove ("temp2.y");

  /* Test the old pexecute interface.  */
  {
    int pid1, pid2;
    char *errmsg_fmt;
    char *errmsg_arg;
    char errbuf1[1000];
    char errbuf2[1000];

    subargv[1] = "echo";
    subargv[2] = "oldpexecute";
    subargv[3] = NULL;
    pid1 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp",
                   &errmsg_fmt, &errmsg_arg, PEXECUTE_FIRST);
    if (pid1 < 0)
      {
       snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg);
       snprintf (errbuf2, sizeof errbuf2, "pexecute 1 failed: %s", errbuf1);
       FATAL_ERROR (errbuf2, 0);
      }

    subargv[1] = "write";
    subargv[2] = "temp.y";
    subargv[3] = NULL;
    pid2 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp",
                   &errmsg_fmt, &errmsg_arg, PEXECUTE_LAST);
    if (pid2 < 0)
      {
       snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg);
       snprintf (errbuf2, sizeof errbuf2, "pexecute 2 failed: %s", errbuf1);
       FATAL_ERROR (errbuf2, 0);
      }

    if (pwait (pid1, &status, 0) < 0)
      FATAL_ERROR ("write pwait 1 failed", errno);
    if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
      ERROR ("write exit status 1 failed");

    if (pwait (pid2, &status, 0) < 0)
      FATAL_ERROR ("write pwait 1 failed", errno);
    if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS)
      ERROR ("write exit status 2 failed");

    e = fopen ("temp.y", "r");
    if (e == NULL)
      FATAL_ERROR ("fopen temp.y failed in copy temp", errno);
    CHECK_LINE (e, "oldpexecute");
    fclose (e);

    remove ("temp.y");
  }

  if (trace)
    fprintf (stderr, "Exiting with status %d\n", error_count);

  return error_count;
}

Here is the call graph for this function: