Skip to content
Permalink
f752a601bf
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
104 lines (93 sloc) 2.76 KB
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
static const char REAPER_PNAME[] = "mxqd reaper";
__attribute__((noreturn)) static void die(char *msg) {
perror(msg);
_exit(1);
}
int main(int argc, char **argv) {
if (argc < 5 || strcmp(argv[3], "--") != 0) {
fprintf(stderr, "usage: %s UID SPOOLFILENAME -- CMD [ARGS...]\n", argv[0]);
exit(1);
}
uid_t uid = atoi(argv[1]);
char *spoolfilename = argv[2];
char **user_argv = &argv[4];
pid_t user_pid;
int user_status = -1;
struct rusage user_rusage;
struct timeval user_time;
struct timeval starttime;
struct timeval endtime;
if (prctl(PR_SET_NAME, REAPER_PNAME, NULL, NULL, NULL) == -1)
die("PR_SET_NAME");
user_pid = fork();
if (user_pid == 0) {
if (setreuid(uid, uid) == -1)
die("setreuid");
execvp(user_argv[0], user_argv);
die(user_argv[0]);
}
if (user_pid == -1)
die("fork");
if (gettimeofday(&starttime, NULL) == -1)
die("gettimeofday");
while (1) {
int status;
pid_t pid = wait(&status);
if (pid < 0 && errno == ECHILD)
break;
if (pid == user_pid)
user_status = status;
}
if (gettimeofday(&endtime, NULL) == -1)
die("gettimeofday");
timersub(&endtime, &starttime, &user_time);
if (getrusage(RUSAGE_CHILDREN, &user_rusage) == -1)
die("getrusage");
if (user_time.tv_sec<30) {
int wait=30-user_time.tv_sec;
sleep(wait);
}
char *tmpfilename;
if (asprintf(&tmpfilename, "%s.tmp", spoolfilename) == -1)
die("");
FILE *out = fopen(tmpfilename,"w");
if (out == NULL)
die(tmpfilename);
fprintf(out,"1 %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n",
getpid(),
user_status,
user_time.tv_sec, user_time.tv_usec,
user_rusage.ru_utime.tv_sec, user_rusage.ru_utime.tv_usec,
user_rusage.ru_stime.tv_sec, user_rusage.ru_stime.tv_usec,
user_rusage.ru_maxrss,
user_rusage.ru_ixrss,
user_rusage.ru_idrss,
user_rusage.ru_isrss,
user_rusage.ru_minflt,
user_rusage.ru_majflt,
user_rusage.ru_nswap,
user_rusage.ru_inblock,
user_rusage.ru_oublock,
user_rusage.ru_msgsnd,
user_rusage.ru_msgrcv,
user_rusage.ru_nsignals,
user_rusage.ru_nvcsw,
user_rusage.ru_nivcsw
);
fflush(out);
fsync(fileno(out));
fclose(out);
if (rename(tmpfilename, spoolfilename) == -1)
die(spoolfilename);
return 0;
}