[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-gnulib] addition: wait-process.h, wait-process.c
From: |
Bruno Haible |
Subject: |
[Bug-gnulib] addition: wait-process.h, wait-process.c |
Date: |
Wed, 23 Apr 2003 22:08:27 +0200 (CEST) |
Continuing the series of modules for executing programs. Here is
'wait-process - Waiting for a subprocess to finish.' Its intended use
is to be applied to the PID of a subprocess created by execute
(fork/exec) or pipe.
The main points of this code are:
- to provide reasonable error messages,
- to handle the return code 127 correctly (a convention specified
in POSIX).
The mingw32 part is not finished, I'm currently working on it.
Any objections?
Bruno
========================= wait-process.h =========================
/* Waiting for a subprocess to finish.
Copyright (C) 2001-2002 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _WAIT_PROCESS_H
#define _WAIT_PROCESS_H
/* Get pid_t. */
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <stdbool.h>
/* Wait for a subprocess to finish. Return its exit code.
If it didn't terminate correctly, exit if exit_on_error is true, otherwise
return 127. */
extern int wait_subprocess (pid_t child, const char *progname,
bool exit_on_error);
#endif /* _WAIT_PROCESS_H */
========================= wait-process.c =========================
/* Waiting for a subprocess to finish.
Copyright (C) 2001-2003 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/* Specification. */
#include "wait-process.h"
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#if defined _MSC_VER || defined __MINGW32__
/* Native Woe32 API. */
#include <process.h>
#define waitpid(pid,statusp,options) _cwait (statusp, pid, WAIT_CHILD)
#define WAIT_T int
#define WTERMSIG(x) ((x) & 0xff) /* or: SIGABRT ?? */
#define WCOREDUMP(x) 0
#define WEXITSTATUS(x) (((x) >> 8) & 0xff) /* or: (x) ?? */
#define WIFSIGNALED(x) (WTERMSIG (x) != 0) /* or: ((x) == 3) ?? */
#define WIFEXITED(x) (WTERMSIG (x) == 0) /* or: ((x) != 3) ?? */
#define WIFSTOPPED(x) 0
#else
/* Unix API. */
#include <sys/wait.h>
/* On Linux, WEXITSTATUS are bits 15..8 and WTERMSIG are bits 7..0, while
BeOS uses the contrary. Therefore we use the abstract macros. */
#if HAVE_UNION_WAIT
# define WAIT_T union wait
# ifndef WTERMSIG
# define WTERMSIG(x) ((x).w_termsig)
# endif
# ifndef WCOREDUMP
# define WCOREDUMP(x) ((x).w_coredump)
# endif
# ifndef WEXITSTATUS
# define WEXITSTATUS(x) ((x).w_retcode)
# endif
#else
# define WAIT_T int
# ifndef WTERMSIG
# define WTERMSIG(x) ((x) & 0x7f)
# endif
# ifndef WCOREDUMP
# define WCOREDUMP(x) ((x) & 0x80)
# endif
# ifndef WEXITSTATUS
# define WEXITSTATUS(x) (((x) >> 8) & 0xff)
# endif
#endif
/* For valid x, exactly one of WIFSIGNALED(x), WIFEXITED(x), WIFSTOPPED(x)
is true. */
#ifndef WIFSIGNALED
# define WIFSIGNALED(x) (WTERMSIG (x) != 0 && WTERMSIG(x) != 0x7f)
#endif
#ifndef WIFEXITED
# define WIFEXITED(x) (WTERMSIG (x) == 0)
#endif
#ifndef WIFSTOPPED
# define WIFSTOPPED(x) (WTERMSIG (x) == 0x7f)
#endif
/* Note that portable applications may access
WTERMSIG(x) only if WIFSIGNALED(x) is true, and
WEXITSTATUS(x) only if WIFEXITED(x) is true. */
#endif
#include "error.h"
#include "exit.h"
#include "gettext.h"
#define _(str) gettext (str)
int
wait_subprocess (pid_t child, const char *progname, bool exit_on_error)
{
/* waitpid() is just as portable as wait() nowadays. */
WAIT_T status;
*(int *) &status = 0;
for (;;)
{
int result = waitpid (child, &status, 0);
if (result != child)
{
#ifdef EINTR
if (errno == EINTR)
continue;
#endif
#if 0 /* defined ECHILD */
if (errno == ECHILD)
{
/* Child process nonexistent?! Assume it terminated
successfully. */
*(int *) &status = 0;
break;
}
#endif
if (exit_on_error)
error (EXIT_FAILURE, errno, _("%s subprocess"), progname);
else
return 127;
}
/* One of WIFSIGNALED (status), WIFEXITED (status), WIFSTOPPED (status)
must always be true. Loop until the program terminates. */
if (!WIFSTOPPED (status))
break;
}
if (WIFSIGNALED (status))
{
if (exit_on_error)
error (EXIT_FAILURE, 0, _("%s subprocess got fatal signal %d"),
progname, (int) WTERMSIG (status));
else
return 127;
}
if (WEXITSTATUS (status) == 127)
{
if (exit_on_error)
error (EXIT_FAILURE, 0, _("%s subprocess failed"), progname);
else
return 127;
}
return WEXITSTATUS (status);
}
- [Bug-gnulib] addition: wait-process.h, wait-process.c,
Bruno Haible <=