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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
/*
* TASK.H -- Each time a new task is run, a task struct is pushed onto the top
* of the control stack. The struct is popped off when the task dies.
* This allows recursive task calling.
*
* Each TASK directive creates a new ltask struct at the top of the
* dictionary and gets linked in at the head of the current package, curpack.
* Each PACKAGE directive creates a new package struct at the top of the
* dictionary and gets linked at pachead.
*
* ASSUMES config.h, param.h and stdio.h already include'd.
*/
extern struct task *firstask; /* pointer to original cl task */
extern struct task *newtask; /* new task being prepared for execing;
* not linked in to task list nor does it
* become currentask until run.
*/
extern struct task *currentask; /* the currently running task */
extern struct package *curpack; /* current package */
/* prevtask may be used as a pointer to the previous, ie, parent, task.
* exploiting c's ability to do pointer arithmetic, it is simple one
* task up from currentask on the control stack.
* this is used alot in the builtin commands to gain access to their parent.
* note that if currentask == firstask, prevtask will point beyond the
* control stack and should not be used.
*/
/* Added because tp++ will not always be the next task structure. (FJR).
* NOTE -- Must explicitly coerce to char pointer for correct byte arithmetic
* on word (rather than byte) addessed machines.
*/
#define next_task(tp) ((struct task *)((char *)tp + (TASKSIZ*BPI)))
#define prevtask next_task(currentask)
/* ----------
* info that is needed about a task as it appears on the control stack
* while it is running.
*/
struct task {
FILE *t_stdin, /* where xmit/xfer to stdin/out/err go */
*t_stdout,
*t_stderr,
*t_stdgraph, /* standard graphics streams */
*t_stdimage,
*t_stdplot;
FILE *t_in, /* pipe read and write connections */
*t_out;
char *ft_in; /* stdin file for foreign task */
char *ft_out; /* stdout file for foreign task */
char *ft_err; /* stderr file for foreign task */
struct ltask *t_ltp; /* link back to fostering ltask */
unsigned XINT
t_topd, /* topd when this task was last pushed */
t_pc, /* pc " */
t_topos, /* topos " */
t_basos, /* basos " */
t_topcs; /* topcs " */
XINT t_envp; /* environment stack pointer */
int t_pno; /* mark package load time in prcache */
struct package *t_curpack;/* curpack " */
unsigned t_bascode; /* base addr of currently running code */
int t_pid; /* process id of this ptask */
int t_scriptln; /* script line number while parsing */
struct param *t_modep; /* pointer to this task's `mode' param */
struct pfile *t_pfp; /* pointer to pfile */
int t_flags; /* see T_XXX flags below */
};
/* A leading underscore in the ltask name is used to flag tasks which
* should not appear in the menus.
*/
#define CH_INVIS '_'
/* t_flags */
#define T_SCRIPT 00000001 /* means t_ltp->lt_flags & LT_SCRIPT >0*/
#define T_CL 00000002 /* means that t_ltp == firstask->t_ltp */
#define T_INTERACTIVE 00000004 /* T_CL && t_stdio == real stdio */
#define T_BUILTIN 00000010 /* task is built in; see builtin.c */
#define T_FOREIGN 00000020 /* host task, a type of builtin */
#define T_PSET 00000040 /* pset (parameter set) task */
#define T_PKGCL 00000100 /* task is name of a loaded package */
#define T_CLEOF 00000200 /* cl() with EOF on current stream */
#define T_TIMEIT 00000400 /* print time consumed by task */
/* These flags are set by the opcodes that change a newtask's pseudofile,
* such as SETSTDOUT. Only when the flag is set will the file then be
* closed by a "bye" or eof from the ltask by clbye().
*/
#define T_MYOUT 00001000 /* t_stdout was set to exec this task */
#define T_MYIN 00002000 /* t_stdin " */
#define T_MYERR 00004000 /* t_stderr " */
#define T_MYSTDGRAPH 00010000 /* t_stdgraph " */
#define T_MYSTDIMAGE 00020000 /* t_stdimage " */
#define T_MYSTDPLOT 00040000 /* t_stdplot " */
#define T_IPCIO 00100000 /* t_stdout redirected to t_out */
#define T_STDINB 00200000 /* stdin is binary */
#define T_STDOUTB 00400000 /* stdout is binary */
#define T_APPEND 01000000 /* append output of foreign task */
/* This flag is set by execnewtask() when a task begins running, and is
* cleared by iofinish() when the task's i/o is closed down. Provided so
* that we can call iofinish at several points during error recovery without
* trying to close files more than once.
*/
#define T_RUNNING 02000000
/* When this bit is set we are running unattended as a background cl.
* Seeing this bit on will prevent pfile writes and all errors and signals
* will cause immediate io flushing and exit.
*/
#define T_BATCH 04000000
/* IPCIO definitions. */
#define IPCOUT "IPC$IPCIO-OUT"
#define IPCDONEMSG "# IPC$IPCIO-FINISHED\n"
/* Struct LTASK -- One of these is created at the top of the dictionary and
* gets linked in to its package by each ltask named (or implied) in a TASK
* directive. We need the name of the ltask, filename of the ptask, pointer
* to next in list of ltasks on this package, pointer to the parent package
* and misc flags.
* The pointer to the parent package is used to get the prefix for the
* ltask's param file when writing it out locally. Lname is built into the
* directionary right after the structure; pname is re-used if possible by
* looking to see if another ltask exists in the same package with the same
* name. This is more than a savings of core as its the way connect()
* decides if a new ltask is in the currently running ptask (by comparing
* currentask->t_ltp->lt_pname with newtask->t_ltp->lt_pname).
* Note that the ftprefix string cannot be included in the union lt_u as
* a foreign task is a builtin and the ltu_f field is already used to point
* to the builtin to be run to issue the host command.
*/
struct ltask {
char *lt_lname; /* name of this logical task */
union {
char *ltu_pname;/* name of this ltask's physical file */
void (*ltu_f)();/* function to run for this builtin */
} lt_u;
char *lt_ftprefix; /* OSCMD command prefix for foreign tsk */
struct ltask *lt_nlt; /* ptr to next ltask in this package */
struct package *lt_pkp;/* pointer to parent package */
int lt_flags; /* see LT_XXX flags below */
};
/* alias's for fields in union lt_u.
*/
#define lt_pname lt_u.ltu_pname
#define lt_f lt_u.ltu_f
/* lt_flags */
#define LT_SCRIPT 000001 /* this task is just a script and so is */
/* the only one in this ptask */
#define LT_PFILE 000002 /* this task has a pfile (some don't!). */
#define LT_STDINB 000004 /* set if task's stdin is binary stream */
#define LT_STDOUTB 000010 /* " stdout " */
#define LT_BUILTIN 000020 /* task is built into CL */
#define LT_FOREIGN 000040 /* host task, called with c_oscmd() */
#define LT_PSET 000100 /* pset (parameter set) task */
#define LT_INVIS 000200 /* don't show this task in menu */
#define LT_PACCL 000400 /* changing packages; see callnewtask() */
#define LT_CL 001000 /* task is some variant of cl() */
#define LT_CLEOF 002000 /* task is cl with EOF (cleof()) */
#define LT_DEFPCK 004000 /* the task def'd a pkg with same name */
#define LT_UPFOK 010000 /* user pfile exists and is valid */
/* ----------
* A package consists of its name, a pointer to next package (maintained in
* a LIFO fashion off pachead), pointer to first in a list of ltasks in
* this package, pointer to its in-core pfile, and misc flags (not used so far).
* the name string is built into the dictionary directly after the struct.
*/
struct package {
char *pk_name; /* name of package */
char *pk_bin; /* package BIN directory */
struct package *pk_npk; /* ptr to next package */
struct ltask *pk_ltp; /* ptr to first ltask in pkg */
struct pfile *pk_pfp; /* ptr to pkg pfile, if loaded */
int pk_flags; /* package flags */
};
/* pk_flags */
/* none at present */
/* ----------
* size of of the task, ltask, and package structs IN INTS.
* this is to properly increment pointers within dictionary.
*/
#define TASKSIZ btoi (sizeof (struct task))
#define LTASKSIZ btoi (sizeof (struct ltask))
#define PACKAGESIZ btoi (sizeof (struct package))
struct package *newpac(), *pacfind();
struct ltask *addltask(), *newltask(), *ltaskfind(), *cmdsrch();
struct ltask *ltasksrch(), *_ltasksrch();
struct task *pushtask(), *poptask();
int deftask(), defpac();
|