~ubuntu-branches/ubuntu/precise/9base/precise

« back to all changes in this revision

Viewing changes to mk/unix.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-08-20 17:34:06 UTC
  • mfrom: (6.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090820173406-xpwqa9ruyevvc0ut
Tags: 1:3-3
* Updating maintainer field.
* Updating vcs fields.
* Updating package to standards version 3.8.3.
* Updatin variables writing in rules to consistent style.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define NOPLAN9DEFINES
2
 
#include        "mk.h"
3
 
#include        <sys/wait.h>
4
 
#include        <signal.h>
5
 
#include        <sys/stat.h>
6
 
#include        <sys/time.h>
7
 
 
8
 
char    *shell = "/bin/sh";
9
 
char    *shellname = "sh";
10
 
 
11
 
extern char **environ;
12
 
 
13
 
static void
14
 
mkperror(char *s)
15
 
{
16
 
        fprint(2, "%s: %r\n", s);
17
 
}
18
 
 
19
 
void
20
 
readenv(void)
21
 
{
22
 
        char **p, *s;
23
 
        Word *w;
24
 
 
25
 
        for(p = environ; *p; p++){
26
 
/* rsc 5/5/2004 -- This misparses fn#cd={whatever} 
27
 
                s = shname(*p);
28
 
                if(*s == '=') {
29
 
                        *s = 0;
30
 
                        w = newword(s+1);
31
 
                } else
32
 
                        w = newword("");
33
 
*/
34
 
                s = strchr(*p, '=');
35
 
                if(s){
36
 
                        *s = 0;
37
 
                        w = newword(s+1);
38
 
                } else
39
 
                        w = newword("");
40
 
                if (symlook(*p, S_INTERNAL, 0))
41
 
                        continue;
42
 
                s = strdup(*p);
43
 
                setvar(s, (void *)w);
44
 
                symlook(s, S_EXPORTED, (void*)"")->value = (void*)"";
45
 
        }
46
 
}
47
 
 
48
 
/*
49
 
 *      done on child side of fork, so parent's env is not affected
50
 
 *      and we don't care about freeing memory because we're going
51
 
 *      to exec immediately after this.
52
 
 */
53
 
void
54
 
exportenv(Envy *e, Shell *sh)
55
 
{
56
 
        int i;
57
 
        char **p;
58
 
        static char buf[16384];
59
 
 
60
 
        p = 0;
61
 
        for(i = 0; e->name; e++, i++) {
62
 
                p = (char**) Realloc(p, (i+2)*sizeof(char*));
63
 
                if(e->values)
64
 
                        snprint(buf, sizeof buf, "%s=%s", e->name,  wtos(e->values, sh->iws));
65
 
                else
66
 
                        snprint(buf, sizeof buf, "%s=", e->name);
67
 
                p[i] = strdup(buf);
68
 
        }
69
 
        p[i] = 0;
70
 
        environ = p;
71
 
}
72
 
 
73
 
int
74
 
waitfor(char *msg)
75
 
{
76
 
        int status;
77
 
        int pid;
78
 
 
79
 
        *msg = 0;
80
 
        pid = wait(&status);
81
 
        if(pid > 0) {
82
 
                if(status&0x7f) {
83
 
                        if(status&0x80)
84
 
                                snprint(msg, ERRMAX, "signal %d, core dumped", status&0x7f);
85
 
                        else
86
 
                                snprint(msg, ERRMAX, "signal %d", status&0x7f);
87
 
                } else if(status&0xff00)
88
 
                        snprint(msg, ERRMAX, "exit(%d)", (status>>8)&0xff);
89
 
        }
90
 
        return pid;
91
 
}
92
 
 
93
 
void
94
 
expunge(int pid, char *msg)
95
 
{
96
 
        if(strcmp(msg, "interrupt"))
97
 
                kill(pid, SIGINT);
98
 
        else
99
 
                kill(pid, SIGHUP);
100
 
}
101
 
 
102
 
int mypid;
103
 
 
104
 
int
105
 
shargv(Word *cmd, int extra, char ***pargv)
106
 
{
107
 
        char **argv;
108
 
        int i, n;
109
 
        Word *w;
110
 
 
111
 
        n = 0;
112
 
        for(w=cmd; w; w=w->next)
113
 
                n++;
114
 
        
115
 
        argv = Malloc((n+extra+1)*sizeof(argv[0]));
116
 
        i = 0;
117
 
        for(w=cmd; w; w=w->next)
118
 
                argv[i++] = w->s;
119
 
        argv[n] = 0;
120
 
        *pargv = argv;
121
 
        return n;
122
 
}       
123
 
 
124
 
int
125
 
execsh(char *args, char *cmd, Bufblock *buf, Envy *e, Shell *sh, Word *shellcmd)
126
 
{
127
 
        char *p, **argv;
128
 
        int tot, n, pid, in[2], out[2];
129
 
 
130
 
        if(buf && pipe(out) < 0){
131
 
                mkperror("pipe");
132
 
                Exit();
133
 
        }
134
 
        pid = fork();
135
 
        mypid = getpid();
136
 
        if(pid < 0){
137
 
                mkperror("mk fork");
138
 
                Exit();
139
 
        }
140
 
        if(pid == 0){
141
 
                if(buf)
142
 
                        close(out[0]);
143
 
                if(pipe(in) < 0){
144
 
                        mkperror("pipe");
145
 
                        Exit();
146
 
                }
147
 
                pid = fork();
148
 
                if(pid < 0){
149
 
                        mkperror("mk fork");
150
 
                        Exit();
151
 
                }
152
 
                if(pid != 0){
153
 
                        dup2(in[0], 0);
154
 
                        if(buf){
155
 
                                dup2(out[1], 1);
156
 
                                close(out[1]);
157
 
                        }
158
 
                        close(in[0]);
159
 
                        close(in[1]);
160
 
                        if (e)
161
 
                                exportenv(e, sh);
162
 
                        n = shargv(shellcmd, 1, &argv);
163
 
                        argv[n++] = args;
164
 
                        argv[n] = 0;
165
 
                        execvp(argv[0], argv);
166
 
                        mkperror(shell);
167
 
                        _exit(1);
168
 
                }
169
 
                close(out[1]);
170
 
                close(in[0]);
171
 
                if(DEBUG(D_EXEC))
172
 
                        fprint(1, "starting: %s\n", cmd);
173
 
                p = cmd+strlen(cmd);
174
 
                while(cmd < p){
175
 
                        n = write(in[1], cmd, p-cmd);
176
 
                        if(n < 0)
177
 
                                break;
178
 
                        cmd += n;
179
 
                }
180
 
                close(in[1]);
181
 
                _exit(0);
182
 
        }
183
 
        if(buf){
184
 
                close(out[1]);
185
 
                tot = 0;
186
 
                for(;;){
187
 
                        if (buf->current >= buf->end)
188
 
                                growbuf(buf);
189
 
                        n = read(out[0], buf->current, buf->end-buf->current);
190
 
                        if(n <= 0)
191
 
                                break;
192
 
                        buf->current += n;
193
 
                        tot += n;
194
 
                }
195
 
                if (tot && buf->current[-1] == '\n')
196
 
                        buf->current--;
197
 
                close(out[0]);
198
 
        }
199
 
        return pid;
200
 
}
201
 
 
202
 
int
203
 
pipecmd(char *cmd, Envy *e, int *fd, Shell *sh, Word *shellcmd)
204
 
{
205
 
        int pid, pfd[2];
206
 
        int n;
207
 
        char **argv;
208
 
 
209
 
        if(DEBUG(D_EXEC))
210
 
                fprint(1, "pipecmd='%s'\n", cmd);/**/
211
 
 
212
 
        if(fd && pipe(pfd) < 0){
213
 
                mkperror("pipe");
214
 
                Exit();
215
 
        }
216
 
        pid = fork();
217
 
        if(pid < 0){
218
 
                mkperror("mk fork");
219
 
                Exit();
220
 
        }
221
 
        if(pid == 0){
222
 
                if(fd){
223
 
                        close(pfd[0]);
224
 
                        dup2(pfd[1], 1);
225
 
                        close(pfd[1]);
226
 
                }
227
 
                if(e)
228
 
                        exportenv(e, sh);
229
 
                n = shargv(shellcmd, 2, &argv);
230
 
                argv[n++] = "-c";
231
 
                argv[n++] = cmd;
232
 
                argv[n] = 0;
233
 
                execvp(argv[0], argv);
234
 
                mkperror(shell);
235
 
                _exit(1);
236
 
        }
237
 
        if(fd){
238
 
                close(pfd[1]);
239
 
                *fd = pfd[0];
240
 
        }
241
 
        return pid;
242
 
}
243
 
 
244
 
void
245
 
Exit(void)
246
 
{
247
 
        while(wait(0) >= 0)
248
 
                ;
249
 
        exits("error");
250
 
}
251
 
 
252
 
static  struct
253
 
{
254
 
        int     sig;
255
 
        char    *msg;
256
 
}       sigmsgs[] =
257
 
{
258
 
        SIGALRM,        "alarm",
259
 
        SIGFPE,         "sys: fp: fptrap",
260
 
        SIGPIPE,        "sys: write on closed pipe",
261
 
        SIGILL,         "sys: trap: illegal instruction",
262
 
//      SIGSEGV,        "sys: segmentation violation",
263
 
        0,              0
264
 
};
265
 
 
266
 
static void
267
 
notifyf(int sig)
268
 
{
269
 
        int i;
270
 
 
271
 
        for(i = 0; sigmsgs[i].msg; i++)
272
 
                if(sigmsgs[i].sig == sig)
273
 
                        killchildren(sigmsgs[i].msg);
274
 
 
275
 
        /* should never happen */
276
 
        signal(sig, SIG_DFL);
277
 
        kill(getpid(), sig);
278
 
}
279
 
 
280
 
void
281
 
catchnotes(void)
282
 
{
283
 
        int i;
284
 
 
285
 
        for(i = 0; sigmsgs[i].msg; i++)
286
 
                signal(sigmsgs[i].sig, notifyf);
287
 
}
288
 
 
289
 
char*
290
 
maketmp(int *pfd)
291
 
{
292
 
        static char temp[] = "/tmp/mkargXXXXXX";
293
 
        static char buf[100];
294
 
        int fd;
295
 
 
296
 
        strcpy(buf, temp);
297
 
        fd = mkstemp(buf);
298
 
        if(fd < 0)
299
 
                return 0;
300
 
        *pfd = fd;
301
 
        return buf;
302
 
}
303
 
 
304
 
int
305
 
chgtime(char *name)
306
 
{
307
 
        if(access(name, 0) >= 0)
308
 
                return utimes(name, 0);
309
 
        return close(creat(name, 0666));
310
 
}
311
 
 
312
 
void
313
 
rcopy(char **to, Resub *match, int n)
314
 
{
315
 
        int c;
316
 
        char *p;
317
 
 
318
 
        *to = match->s.sp;              /* stem0 matches complete target */
319
 
        for(to++, match++; --n > 0; to++, match++){
320
 
                if(match->s.sp && match->e.ep){
321
 
                        p = match->e.ep;
322
 
                        c = *p;
323
 
                        *p = 0;
324
 
                        *to = strdup(match->s.sp);
325
 
                        *p = c;
326
 
                }
327
 
                else
328
 
                        *to = 0;
329
 
        }
330
 
}
331
 
 
332
 
unsigned long
333
 
mkmtime(char *name)
334
 
{
335
 
        struct stat st;
336
 
 
337
 
        if(stat(name, &st) < 0)
338
 
                return 0;
339
 
 
340
 
        return st.st_mtime;
341
 
}