aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/exec.c
blob: 0155b2209159be9129204184187a62e946cf2925 (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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "rc.h"

#define W0      shell->stack->words
// -----------------------------------------------------------------------
// helper functions

static
void
setstatus(char *s)
{
    setvar("status", newword(s, nil));
}

static
void
pushredir(int type, int from, int to)
{
    Redir *r;

    alloc(r);
    r->type = type;
    r->from = from;
    r->to   = to;
    r->link = shell->redir, shell->redir = r;
}

// -----------------------------------------------------------------------
// interpreter functions

void
Xerror(char *s)
{
    if(!strcmp(argv0, "rc")||!strcmp(argv0, "/bin/rc"))
        pfmt(errio, "rc: %s: %r\n", s);
    else
        pfmt(errio, "rc (%s): %s: %r\n", argv0, s);
    flush(&errio);

    setstatus("error");
    while(!shell->interactive)
        Xkill();
}

void
Xappend(void)
{
    int fd;
    char *path;

    switch(count(W0)) {
    default:
        Xerror(">> requires a singleton list");
        return;
    case 0:
        Xerror(">> requires one file");
        return;
    case 1:
        ;
    }

    path = shell->stack->words->word;
    if ((fd=open(path, 1))< 0 && (fd=creat(path, 0666L))<0) {
        pfmt(errio, "%s: ", path);
        Xerror("can't open");
        return;
    }
    lseek(fd, 0L, 2);
    pushredir(Fopen, fd, shell->ip++->i);
    poplist();
}

void
Xassign(void)
{
    Var *v;
    if(count(W0)!=1) {
        Xerror("variable name not singleton");
        return;
    }
    unglob(W0->word);
    v = vlookup(W0->word);
    poplist();
    globlist();
    freelist(v->val);

    v->val = W0;
    if(v->update)
        v->update(v);
    W0 = nil;
    poplist();
}

void
Xmark(void)
{
    pushlist();
}

void
Xword(void)
{
    pushword(shell->ip++->s);
}

void Xasync(void);
void Xcat(void);
void Xclose(void);
void Xcmdsub(void);
void Xcount(void);
void Xdol(void);
void Xdup(void);
void Xexit(void);
void Xfalse(void);
void Xflatten(void);
void Xfor(void);
void Xfunc(void);
void Xglob(void);
void Xif(void);
void Xjump(void);
void Xkill(void);
void Xlocal(void);
void Xmark(void);
void Xmatch(void);
void Xnegate(void);
void Xpipe(void);
void Xpipefd(void);
void Xpipewait(void);
void Xpop(void);
void Xpopredir(void);
void Xrdwr(void);
void Xread(void);
void Xsub(void);
void Xsimple(void);
void Xsubshell(void);
void Xtrue(void);
void Xunfunc(void);
void Xunlocal(void);
void Xword(void);
void Xwrite(void);