~ubuntu-branches/ubuntu/natty/9base/natty

« back to all changes in this revision

Viewing changes to sam/shell.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2010-06-04 17:22:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20100604172203-ei85j0da495sr8ut
Tags: 1:6-1
* Adding Kai as co-maintainer.
* Merging upstream version 6.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "sam.h"
 
2
#include "parse.h"
 
3
 
 
4
extern  jmp_buf mainloop;
 
5
 
 
6
char    errfile[64];
 
7
String  plan9cmd;       /* null terminated */
 
8
Buffer  plan9buf;
 
9
void    checkerrs(void);
 
10
 
 
11
void
 
12
setname(File *f)
 
13
{
 
14
        char buf[1024];
 
15
        if(f)
 
16
                snprint(buf, sizeof buf, "%.*S", f->name.n, f->name.s);
 
17
        else
 
18
                buf[0] = 0;
 
19
        putenv("samfile", buf);
 
20
}
 
21
 
 
22
int
 
23
plan9(File *f, int type, String *s, int nest)
 
24
{
 
25
        long l;
 
26
        int m;
 
27
        int volatile pid;
 
28
        int fd;
 
29
        int retcode;
 
30
        int pipe1[2], pipe2[2];
 
31
 
 
32
        if(s->s[0]==0 && plan9cmd.s[0]==0)
 
33
                error(Enocmd);
 
34
        else if(s->s[0])
 
35
                Strduplstr(&plan9cmd, s);
 
36
        if(downloaded){
 
37
                samerr(errfile);
 
38
                remove(errfile);
 
39
        }
 
40
        if(type!='!' && pipe(pipe1)==-1)
 
41
                error(Epipe);
 
42
        if(type=='|')
 
43
                snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
 
44
        if((pid=fork()) == 0){
 
45
                setname(f);
 
46
                if(downloaded){ /* also put nasty fd's into errfile */
 
47
                        fd = create(errfile, 1, 0666L);
 
48
                        if(fd < 0)
 
49
                                fd = create("/dev/null", 1, 0666L);
 
50
                        dup(fd, 2);
 
51
                        close(fd);
 
52
                        /* 2 now points at err file */
 
53
                        if(type == '>')
 
54
                                dup(2, 1);
 
55
                        else if(type=='!'){
 
56
                                dup(2, 1);
 
57
                                fd = open("/dev/null", 0);
 
58
                                dup(fd, 0);
 
59
                                close(fd);
 
60
                        }
 
61
                }
 
62
                if(type != '!') {
 
63
                        if(type=='<' || type=='|')
 
64
                                dup(pipe1[1], 1);
 
65
                        else if(type == '>')
 
66
                                dup(pipe1[0], 0);
 
67
                        close(pipe1[0]);
 
68
                        close(pipe1[1]);
 
69
                }
 
70
                if(type == '|'){
 
71
                        if(pipe(pipe2) == -1)
 
72
                                exits("pipe");
 
73
                        if((pid = fork())==0){
 
74
                                /*
 
75
                                 * It's ok if we get SIGPIPE here
 
76
                                 */
 
77
                                close(pipe2[0]);
 
78
                                io = pipe2[1];
 
79
                                if(retcode=!setjmp(mainloop)){  /* assignment = */
 
80
                                        char *c;
 
81
                                        for(l = 0; l<plan9buf.nc; l+=m){
 
82
                                                m = plan9buf.nc-l;
 
83
                                                if(m>BLOCKSIZE-1)
 
84
                                                        m = BLOCKSIZE-1;
 
85
                                                bufread(&plan9buf, l, genbuf, m);
 
86
                                                genbuf[m] = 0;
 
87
                                                c = Strtoc(tmprstr(genbuf, m+1));
 
88
                                                Write(pipe2[1], c, strlen(c));
 
89
                                                free(c);
 
90
                                        }
 
91
                                }
 
92
                                exits(retcode? "error" : 0);
 
93
                        }
 
94
                        if(pid==-1){
 
95
                                fprint(2, "Can't fork?!\n");
 
96
                                exits("fork");
 
97
                        }
 
98
                        dup(pipe2[0], 0);
 
99
                        close(pipe2[0]);
 
100
                        close(pipe2[1]);
 
101
                }
 
102
                if(type=='<'){
 
103
                        close(0);       /* so it won't read from terminal */
 
104
                        open("/dev/null", 0);
 
105
                }
 
106
                execl(SHPATH, SH, "-c", Strtoc(&plan9cmd), (char *)0);
 
107
                exits("exec");
 
108
        }
 
109
        if(pid == -1)
 
110
                error(Efork);
 
111
        if(type=='<' || type=='|'){
 
112
                int nulls;
 
113
                if(downloaded && addr.r.p1 != addr.r.p2)
 
114
                        outTl(Hsnarflen, addr.r.p2-addr.r.p1);
 
115
                snarf(f, addr.r.p1, addr.r.p2, &snarfbuf, 0);
 
116
                logdelete(f, addr.r.p1, addr.r.p2);
 
117
                close(pipe1[1]);
 
118
                io = pipe1[0];
 
119
                f->tdot.p1 = -1;
 
120
                f->ndot.r.p2 = addr.r.p2+readio(f, &nulls, 0, FALSE);
 
121
                f->ndot.r.p1 = addr.r.p2;
 
122
                closeio((Posn)-1);
 
123
        }else if(type=='>'){
 
124
                close(pipe1[0]);
 
125
                io = pipe1[1];
 
126
                bpipeok = 1;
 
127
                writeio(f);
 
128
                bpipeok = 0;
 
129
                closeio((Posn)-1);
 
130
        }
 
131
        retcode = waitfor(pid);
 
132
        if(type=='|' || type=='<')
 
133
                if(retcode!=0)
 
134
                        warn(Wbadstatus);
 
135
        if(downloaded)
 
136
                checkerrs();
 
137
        if(!nest)
 
138
                dprint("!\n");
 
139
        return retcode;
 
140
}
 
141
 
 
142
void
 
143
checkerrs(void)
 
144
{
 
145
        char buf[BLOCKSIZE-10];
 
146
        int f, n, nl;
 
147
        char *p;
 
148
        long l;
 
149
 
 
150
        if(statfile(errfile, 0, 0, 0, &l, 0) > 0 && l != 0){
 
151
                if((f=open(errfile, 0)) != -1){
 
152
                        if((n=read(f, buf, sizeof buf-1)) > 0){
 
153
                                for(nl=0,p=buf; nl<25 && p<&buf[n]; p++)
 
154
                                        if(*p=='\n')
 
155
                                                nl++;
 
156
                                *p = 0;
 
157
                                dprint("%s", buf);
 
158
                                if(p-buf < l-1)
 
159
                                        dprint("(sam: more in %s)\n", errfile);
 
160
                        }
 
161
                        close(f);
 
162
                }
 
163
        }else
 
164
                remove(errfile);
 
165
}