Browse Source

Add the wait4pid module

develop
Damien Goutte-Gattat 8 years ago
parent
commit
9fdf7c015a
  1. 2
      src/Makefile.am
  2. 118
      src/wait4pid.c
  3. 33
      src/wait4pid.h

2
src/Makefile.am

@ -1,6 +1,6 @@
bin_PROGRAMS = wait4
wait4_SOURCES = wait4.c
wait4_SOURCES = wait4.c wait4pid.h wait4pid.c
AM_CPPFLAGS = -I$(top_srcdir)/lib
AM_LDFLAGS = -L$(top_builddir)/lib

118
src/wait4pid.c

@ -0,0 +1,118 @@
/*
* wait4pid - Wait for an arbitrary process
* Copyright (C) 2013 Damien Goutte-Gattat
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/connector.h>
#include <linux/cn_proc.h>
int sock = 0;
int listener_set = 0;
static int
set_proc_listen(int sock, int enable)
{
struct nlmsghdr *hdr;
struct __attribute__ ((__packed__)) payload_t {
struct cn_msg msg;
enum proc_cn_mcast_op op;
} *payload;
char buf[NLMSG_SPACE(sizeof(struct payload_t))];
hdr = (struct nlmsghdr *)buf;
hdr->nlmsg_type = NLMSG_DONE;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*payload));
hdr->nlmsg_pid = getpid();
payload = (struct payload_t *) NLMSG_DATA(hdr);
payload->msg.id.idx = CN_IDX_PROC;
payload->msg.id.val = CN_VAL_PROC;
payload->op = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE;
return send(sock, hdr, NLMSG_SPACE(sizeof(*payload)), 0);
}
static void
wait4pid_close(void)
{
if ( listener_set ) {
set_proc_listen(sock, 0);
listener_set = 0;
}
if ( sock ) {
close(sock);
sock = 0;
}
}
static int
wait4pid_init(void)
{
struct sockaddr_nl sa;
if ( (sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR)) == -1 )
return -1;
atexit(wait4pid_close);
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_groups = CN_IDX_PROC;
sa.nl_pid = getpid();
if ( bind(sock, (struct sockaddr *)&sa, sizeof(sa)) == -1 )
return -1;
if ( setgid(getgid()) == -1 || setuid(getuid()) == -1 )
return -1;
if ( set_proc_listen(sock, 1) == -1 )
return -1;
return 0;
}
int
wait4pid(pid_t pid)
{
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;
while ( recv(sock, buf, sizeof(buf), 0) > 0 ) {
payload = (struct payload_t *) NLMSG_DATA(buf);
if ( payload->evt.what == PROC_EVENT_EXIT
&& payload->evt.event_data.exit.process_pid == pid )
break;
}
return 0;
}

33
src/wait4pid.h

@ -0,0 +1,33 @@
/*
* wait4 - Wait for an arbitrary process
* Copyright (C) 2013 Damien Goutte-Gattat
*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20130319_WAIT4PID_H
#define ICP20130319_WAIT4PID_H
#ifdef __cpluscplus
extern "C" {
#endif
int
wait4pid(pid_t);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20130319_WAIT4PID_H */
Loading…
Cancel
Save