ia64/xen-unstable

view tools/x2d2/util.c @ 3697:0156bb4ae3d7

bitkeeper revision 1.1159.212.112 (4207b382VvZgSA3Pg79SQESssYJbHQ)

More x86_64 fixes.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Mon Feb 07 18:29:22 2005 +0000 (2005-02-07)
parents 2b25e0010db8
children 0a4b76b6b5a0
line source
1 #define _GNU_SOURCE
3 #include <sys/types.h>
4 #include <sys/wait.h>
5 #include <assert.h>
6 #include <err.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <unistd.h>
15 void *
16 xmalloc(size_t s)
17 {
18 void *x;
20 x = malloc(s);
21 if (x == NULL)
22 err(1, "allocating memory");
23 memset(x, 0, s);
24 return x;
25 }
27 void *
28 xrealloc(void *x, size_t s)
29 {
30 void *y;
31 y = realloc(x, s);
32 if (y == NULL)
33 err(1, "allocating more memory");
34 return y;
35 }
37 char *
38 xstrdup(const char *s)
39 {
40 char *x = strdup(s);
41 if (x == NULL)
42 err(1, "duplicating %s", s);
43 return x;
44 }
46 /* Slightly less stupid implementation of system(). We return
47 negative iff there is an error executing the shell; otherwise, we
48 return the wait status as reported by waitpid(). Also, we support
49 printf-style escapes. We don't handle setting the SIGCHLD handler
50 to SIGIGN, though: in that case, we have a race. */
51 int
52 our_system(const char *fmt, ...)
53 {
54 char *cmd = NULL;
55 int r;
56 va_list ap;
57 pid_t child = -1;
58 int pip[2] = {-1, -1};
59 int e;
60 fd_set fds;
61 struct timeval to;
62 int res;
63 pid_t c;
64 unsigned status;
66 va_start(ap, fmt);
67 r = vasprintf(&cmd, fmt, ap);
68 va_end(ap);
69 if (r < 0)
70 return r;
71 r = pipe(pip);
72 if (r < 0) {
73 res = r;
74 goto out;
75 }
76 child = fork();
77 if (child < 0) {
78 res = child;
79 goto out;
80 }
81 if (child == 0) {
82 close(pip[0]);
83 fcntl(pip[1], F_SETFD, 1);
84 r = execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
85 /* Uh oh, exec failed */
86 write(pip[1], &r, sizeof(r));
87 _exit(1);
88 }
90 close(pip[1]);
91 pip[1] = -1;
93 c = waitpid(child, &status, 0);
94 if (c < 0) {
95 res = c;
96 goto out;
97 }
98 assert(c == child);
99 child = -1;
101 /* Check execl result */
102 FD_ZERO(&fds);
103 FD_SET(pip[0], &fds);
104 memset(&to, 0, sizeof(to));
105 r = select(pip[0]+1, &fds, NULL, NULL, &to);
106 if (r == 0) {
107 res = status;
108 } else {
109 assert(FD_ISSET(pip[0], &fds));
110 r = read(pip[0], &res, sizeof(res));
111 if (r != sizeof(res))
112 res = status;
113 }
114 close(pip[0]);
115 pip[0] = -1;
117 out:
118 e = errno;
119 if (child >= 0) {
120 /* Not obvious what the correct thing to do here is. */
121 /* Don't want to kill the child; that will create a
122 zombie. */
123 // kill(child, 9);
124 }
125 if (pip[0] >= 0)
126 close(pip[0]);
127 if (pip[1] >= 0)
128 close(pip[1]);
129 free(cmd);
130 errno = e;
131 return res;
132 }