File: xargs.c

package info (click to toggle)
debfoster 2.7-2.1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 1,188 kB
  • sloc: sh: 4,243; ansic: 2,397; perl: 39; makefile: 26; sed: 16
file content (77 lines) | stat: -rw-r--r-- 1,339 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "error.h"
#include "AVLTree.h"
#include "xargs.h"

#define NUMARGS 512

static int run(char **argv) {
	int i, status;
	pid_t pid;

	switch(pid = fork()) {
	case -1: /* error */
		perror("fork()");
		return -1;
	case 0: /* child */
		for(i = getdtablesize()-1; i>STDERR_FILENO; i--)
			fcntl(i, F_SETFD, ~0);
		execvp(argv[0], argv);
		perror_exit(255, argv[0]);
	default:
		for(i=0; i<0 ? errno==EINTR : i!=pid; i = waitpid(pid, &status, 0));
		return i<0 ? (perror(argv[0]), -1)
			: WIFEXITED(status) ? WEXITSTATUS(status)
			: WIFSIGNALED(status) ? WTERMSIG(status)+128
			: -1;
	}
	return -1;
}

int runv(char *cmd, ...) {
	return run(&cmd);
}

int xargs(AVLTree *t, const char *args) {
	char *s, *cmd, *argv[NUMARGS];
	AVLNode *c;
	int argc, i=0;

	if(!t || !t->head)
		return 0;

	s = alloca(strlen(args)+1);
	if(!s)
		return -1;
	strcpy(s, args);

	while(i<NUMARGS && s) {
		cmd = strsep(&s, " \t");
		if(!cmd)
			break;
		if(*cmd)
			argv[i++] = cmd;
	}

	argc = i;
	c = t->head;

	while(c) {
		for(i = argc; c && i<NUMARGS-1; c = c->next, i++)
			argv[i] = c->item;
		argv[i] = NULL;
		i = run(argv);
		if(i)
			return i;
	}
	return 0;
}