summaryrefslogtreecommitdiff
path: root/support/nfs/execute.c
blob: d1be2ff3a874fe48a377e476dadec506c4eb22e1 (plain)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include "xlog.h"

/*
 * Log system errors or error messages.
 */
void 
syserror(char *message)
{
	if (errno)
		xlog(L_ERROR, "%s: errno %d (%s)", message, errno, strerror(errno));
	else
		xlog(L_ERROR, "Error: %s", message);
}
/*
 * Log the the given argv[] if debugging is on.
 */
static void
show_argv(char *msg, char *const argv[])
{
	char buf[BUFSIZ];
	int i, cc=0;

	if (!xlog_enabled(D_CALL))
		return;

	if (msg) {
		sprintf(buf+cc, "%s ", msg);
		cc = strlen(buf);
	}
	for (i=0; argv[i] != NULL && cc < BUFSIZ; i++) {
		if ((cc + strlen(argv[i])) >= BUFSIZ)
			break;
		sprintf(buf+cc, "%s ", argv[i]);
		cc = strlen(buf);
	}
	xlog(D_CALL, "%s", buf);
}
/*
 *  Execute the given command using the 
 *  given argv as the arguments.
 */
int
execute_cmd(const char *cmd,  char *const myargv[])
{
	int pfd[2], status, cc;
	pid_t pid;
	char buf[BUFSIZ], *ch;

	show_argv("executing:", myargv);

	if (pipe(pfd) < 0) {
		syserror("pipe() failed");
		return errno;
	}
	switch((pid = fork())) {
	case -1: 
		syserror("fork() failed");
		break;
	case 0:  /* child */
		close(pfd[0]);
		if (dup2(pfd[1], STDOUT_FILENO) < 0)
			perror("dup2(STDOUT_FILENO)");
		if (dup2(pfd[1], STDERR_FILENO) < 0)
			perror("dup2(STDERR_FILENO)");
		close(pfd[1]);
		execvp(cmd, myargv);
		perror("execv");
		_exit(255);
		break;
	default: /* parent */
		status = 0;
		close(pfd[1]);
		if (waitpid(pid, &status, 0) < 0 && errno != ECHILD) {
			syserror("waitpid() failed");
		} else if (WIFEXITED(status)) {
			cc = read(pfd[0], buf, BUFSIZ);
			if (cc > 0) { 
				if ((ch = strrchr(buf, '\n')) != NULL)
					*ch = '\0';
				errno = 0;
				syserror(buf);
			}
			close(pfd[0]);
		}
		break;
	}
	return errno;
}