Browse Source

Merge branch 'develop'

master v0.2.1
Damien Goutte-Gattat 8 years ago
parent
commit
749183d470
  1. 2
      Makefile.am
  2. 6
      NEWS
  3. 4
      configure.ac
  4. 32
      src/wait4.c
  5. 52
      src/wait4pid.c
  6. 3
      src/wait4pid.h
  7. 60
      wait4.1.in

2
Makefile.am

@ -2,4 +2,6 @@ SUBDIRS = lib src
ACLOCAL_AMFLAGS = -I m4 --install
man_MANS = wait4.1
dist_doc_DATA = AUTHORS COPYING NEWS README

6
NEWS

@ -1,3 +1,9 @@
Changes in wait4 0.2.1
* Add the -t, --timeout option.
* Add manual page.
Changes in wait4 0.2.0
* Wait for several processes at once.

4
configure.ac

@ -1,6 +1,6 @@
dnl Configure template for the wait4 package
AC_INIT([wait4], [0.2.0],
AC_INIT([wait4], [0.2.1],
[dgouttegattat@incenp.org])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])
@ -25,7 +25,7 @@ AC_CHECK_HEADERS([linux/netlink.h],
AM_CONDITIONAL([HAVE_NETLINK], [test x$ac_cv_header_linux_netlink_h = xyes])
dnl Output files
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
AC_CONFIG_FILES([Makefile wait4.1 lib/Makefile src/Makefile])
AC_OUTPUT
dnl Summary

32
src/wait4.c

@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>
#include <errno.h>
#include <err.h>
@ -43,6 +44,10 @@ PID is specified, waits for all of them.\n");
-v, --version Display the version message.\n\
");
puts("\
-t, --timeout TIME Abort waiting after TIME seconds.\n\
");
printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
exit(status);
@ -79,23 +84,31 @@ get_integer_or_die(const char *arg)
return val;
}
static void
on_alarm(int sig)
{
exit(EXIT_SUCCESS);
}
/* Main function. */
int
main(int argc, char **argv)
{
int c, ec, len, *pids, i;
int c, ec, len, *pids, i, timeout;
struct option options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'v' },
{ "timeout", 1, NULL, 't' },
{ NULL, 0, NULL, 0 }
};
setprogname(argv[0]);
timeout = 0;
while ( (c = getopt_long(argc, argv, "hv", options, NULL)) != -1 ) {
while ( (c = getopt_long(argc, argv, "hvt:", options, NULL)) != -1 ) {
switch ( c ) {
case 'h':
usage(EXIT_SUCCESS);
@ -108,12 +121,27 @@ main(int argc, char **argv)
case 'v':
info();
break;
case 't':
timeout = get_integer_or_die(optarg);
break;
}
}
if ( (len = argc - optind) < 1 )
usage(EXIT_FAILURE);
if ( timeout ) {
struct sigaction sa;
sa.sa_handler = on_alarm;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM, &sa, NULL);
alarm(timeout);
}
pids = xmalloc(len * sizeof(int));
for ( i = 0; i < len; i++ )
pids[i] = get_integer_or_die(argv[optind + i]);

52
src/wait4pid.c

@ -98,11 +98,6 @@ wait4pid_init(void)
return 0;
}
struct __attribute__ ((__packed__)) cn_proc_msg {
struct cn_msg msg;
struct proc_event evt;
};
static int
do_recv(int sock, void *buf, size_t len, int flags)
{
@ -115,37 +110,15 @@ do_recv(int sock, void *buf, size_t len, int flags)
return ret;
}
int
wait4pid(pid_t pid)
{
int ec;
struct cn_proc_msg *payload;
char buf[NLMSG_SPACE(sizeof(struct cn_proc_msg))];
if ( ! listener_set && wait4pid_init() == -1 )
return -1;
if ( kill(pid, 0) == -1 && errno == ESRCH )
return -1;
while ( do_recv(sock, buf, sizeof(buf), 0) > 0 ) {
payload = (struct cn_proc_msg *) NLMSG_DATA(buf);
if ( payload->evt.what == PROC_EVENT_EXIT
&& payload->evt.event_data.exit.process_pid == pid ) {
ec = payload->evt.event_data.exit.exit_code / 256;
break;
}
}
return ec;
}
int
wait4all(pid_t *pids, size_t len)
{
int ec, nproc, i;
struct cn_proc_msg *payload;
char buf[NLMSG_SPACE(sizeof(struct cn_proc_msg))];
struct __attribute__ ((__packed__ )) payload_t {
struct cn_msg msg;
struct proc_event evt;
} *payload;
char buf[NLMSG_SPACE(sizeof(struct payload_t))];
if ( ! listener_set && wait4pid_init() == -1 )
return -1;
@ -160,7 +133,7 @@ wait4all(pid_t *pids, size_t len)
if ( do_recv(sock, buf, sizeof(buf), 0) <= 0 )
return -1;
payload = (struct cn_proc_msg *) NLMSG_DATA(buf);
payload = (struct payload_t *) NLMSG_DATA(buf);
if ( payload->evt.what != PROC_EVENT_EXIT )
continue;
@ -180,21 +153,14 @@ wait4all(pid_t *pids, size_t len)
#else /* HAVE_LINUX_NETLINK_H */
#include <time.h>
#include <signal.h>
int
wait4pid(pid_t pid)
{
while ( kill(pid, 0) != -1 || errno != ESRCH )
sleep(1);
return 0;
}
int
wait4all(pid_t *pids, size_t len)
{
int nproc, i;
struct timespec ts = { 1, 0 };
nproc = len;
while ( nproc > 0 ) {
@ -208,7 +174,7 @@ wait4all(pid_t *pids, size_t len)
}
}
sleep(1);
nanosleep(&ts, NULL);
}
return 0;

3
src/wait4pid.h

@ -25,9 +25,6 @@
extern "C" {
#endif
int
wait4pid(pid_t);
int
wait4all(pid_t *, size_t);

60
wait4.1.in

@ -0,0 +1,60 @@
.TH WAIT 03/21/2013 "wait4 @PACKAGE_VERSION]" "wait4 Manual"
.SH NAME
wait4 \- Wait for arbitrary processes
.SH SYNOPSIS
.SY wait4
.RB [ \-h | --help ]
.RB [ \-v | --version ]
.RB [ \-t | --timeout
.IR time ]
.IR pid ...
.YS
.SH DESCRIPTION
.PP
.B wait4
waits for the process(es) identified by the specified PID(s)
to terminate, and reports the termination status of the
process whose PID is specified last.
.SH OPTIONS
.TP
.BR -h ", " --help
Display the help message.
.TP
.BR -v ", " --version
Display the version message.
.TP
.BR -t ", " --timeout " " \fItime\fR
Aborts waiting after the specified
.I time
(in seconds).
.SH NOTES
.PP
The ability to report the termination status of the waited
process depends on
.BR netlink (7).
On systems without netlink, a fallback
.BR kill (2)-based
mechanism is used, which does not allow to retrieve the
termination status; the exit status is then always 0.
.SH REPORTING BUGS
.PP
Report bugs to
.MT @PACKAGE_BUGREPORT@
Damien Goutte-Gattat
.ME .
.SH COPYRIGHT
.ad l
.PP
Copyright \(co 2013 Damien Goutte-Gattat
.PP
This program is released under the GNU General Public License.
See the COPYING file in the source distribution or
.UR http://www.gnu.org/licenses/gpl.html
.UE .
Loading…
Cancel
Save