2 f08fdedc 2003-11-23 devnull * Plan 9 versions of system-specific functions
3 f08fdedc 2003-11-23 devnull * By convention, exported routines herein have names beginning with an
4 f08fdedc 2003-11-23 devnull * upper case letter.
6 f08fdedc 2003-11-23 devnull #include "rc.h"
7 f08fdedc 2003-11-23 devnull #include "exec.h"
8 f08fdedc 2003-11-23 devnull #include "io.h"
9 f08fdedc 2003-11-23 devnull #include "fns.h"
10 f08fdedc 2003-11-23 devnull #include "getflags.h"
11 f08fdedc 2003-11-23 devnull char *Signame[]={
12 f08fdedc 2003-11-23 devnull "sigexit", "sighup", "sigint", "sigquit",
13 f08fdedc 2003-11-23 devnull "sigalrm", "sigkill", "sigfpe", "sigterm",
16 f08fdedc 2003-11-23 devnull char *syssigname[]={
17 f08fdedc 2003-11-23 devnull "exit", /* can't happen */
18 f08fdedc 2003-11-23 devnull "hangup",
19 f08fdedc 2003-11-23 devnull "interrupt",
20 f08fdedc 2003-11-23 devnull "quit", /* can't happen */
23 f08fdedc 2003-11-23 devnull "sys: fp: ",
28 f08fdedc 2003-11-23 devnull Rcmain(void)
30 8ad51794 2004-03-25 devnull return unsharp("#9/rcmain");
33 8ad51794 2004-03-25 devnull char Fdprefix[]="/dev/fd/";
34 f08fdedc 2003-11-23 devnull void execfinit(void);
35 f08fdedc 2003-11-23 devnull void execbind(void);
36 f08fdedc 2003-11-23 devnull void execmount(void);
37 f08fdedc 2003-11-23 devnull builtin Builtin[]={
38 f08fdedc 2003-11-23 devnull "cd", execcd,
39 f08fdedc 2003-11-23 devnull "whatis", execwhatis,
40 f08fdedc 2003-11-23 devnull "eval", execeval,
41 f08fdedc 2003-11-23 devnull "exec", execexec, /* but with popword first */
42 f08fdedc 2003-11-23 devnull "exit", execexit,
43 f08fdedc 2003-11-23 devnull "shift", execshift,
44 f08fdedc 2003-11-23 devnull "wait", execwait,
45 f08fdedc 2003-11-23 devnull ".", execdot,
46 f08fdedc 2003-11-23 devnull "finit", execfinit,
47 f08fdedc 2003-11-23 devnull "flag", execflag,
50 f08fdedc 2003-11-23 devnull #define SEP '\1'
51 f08fdedc 2003-11-23 devnull char **environp;
52 f08fdedc 2003-11-23 devnull struct word *enval(s)
53 f08fdedc 2003-11-23 devnull register char *s;
55 f08fdedc 2003-11-23 devnull register char *t, c;
56 f08fdedc 2003-11-23 devnull register struct word *v;
57 f08fdedc 2003-11-23 devnull for(t=s;*t && *t!=SEP;t++);
60 f08fdedc 2003-11-23 devnull v=newword(s, c=='\0'?(struct word *)0:enval(t+1));
62 f08fdedc 2003-11-23 devnull return v;
64 f08fdedc 2003-11-23 devnull void Vinit(void){
65 f08fdedc 2003-11-23 devnull extern char **environ;
66 f08fdedc 2003-11-23 devnull register char *s;
67 f08fdedc 2003-11-23 devnull register char **env=environ;
68 f08fdedc 2003-11-23 devnull environp=env;
69 f08fdedc 2003-11-23 devnull for(;*env;env++){
70 f08fdedc 2003-11-23 devnull for(s=*env;*s && *s!='(' && *s!='=';s++);
71 f08fdedc 2003-11-23 devnull switch(*s){
72 f08fdedc 2003-11-23 devnull case '\0':
73 c4097c29 2004-05-11 devnull // pfmt(err, "rc: odd environment %q?\n", *env);
75 f08fdedc 2003-11-23 devnull case '=':
77 f08fdedc 2003-11-23 devnull setvar(*env, enval(s+1));
80 f08fdedc 2003-11-23 devnull case '(': /* ignore functions for now */
85 f08fdedc 2003-11-23 devnull char **envp;
86 f08fdedc 2003-11-23 devnull void Xrdfn(void){
88 f08fdedc 2003-11-23 devnull register char *s;
89 f08fdedc 2003-11-23 devnull register int len;
90 f08fdedc 2003-11-23 devnull for(;*envp;envp++){
91 f08fdedc 2003-11-23 devnull s = *envp;
92 f08fdedc 2003-11-23 devnull if(strncmp(s, "fn#", 3) == 0){
93 f08fdedc 2003-11-23 devnull p = strchr(s, '=');
94 f08fdedc 2003-11-23 devnull if(p == nil)
95 f08fdedc 2003-11-23 devnull continue;
96 f08fdedc 2003-11-23 devnull *p = ' ';
97 f08fdedc 2003-11-23 devnull s[2] = ' ';
98 f08fdedc 2003-11-23 devnull len = strlen(s);
99 f08fdedc 2003-11-23 devnull execcmds(opencore(s, len));
100 f08fdedc 2003-11-23 devnull s[len] = '\0';
104 f08fdedc 2003-11-23 devnull for(s=*envp;*s && *s!='(' && *s!='=';s++);
105 f08fdedc 2003-11-23 devnull switch(*s){
106 f08fdedc 2003-11-23 devnull case '\0':
107 f08fdedc 2003-11-23 devnull pfmt(err, "environment %q?\n", *envp);
109 f08fdedc 2003-11-23 devnull case '=': /* ignore variables */
111 f08fdedc 2003-11-23 devnull case '(': /* Bourne again */
112 f08fdedc 2003-11-23 devnull s=*envp+3;
114 f08fdedc 2003-11-23 devnull len=strlen(s);
115 f08fdedc 2003-11-23 devnull s[len]='\n';
116 f08fdedc 2003-11-23 devnull execcmds(opencore(s, len+1));
117 f08fdedc 2003-11-23 devnull s[len]='\0';
122 f08fdedc 2003-11-23 devnull Xreturn();
124 f08fdedc 2003-11-23 devnull union code rdfns[4];
125 f08fdedc 2003-11-23 devnull void execfinit(void){
126 f08fdedc 2003-11-23 devnull static int first=1;
127 f08fdedc 2003-11-23 devnull if(first){
128 f08fdedc 2003-11-23 devnull rdfns[0].i=1;
129 f08fdedc 2003-11-23 devnull rdfns[1].f=Xrdfn;
130 f08fdedc 2003-11-23 devnull rdfns[2].f=Xjump;
131 f08fdedc 2003-11-23 devnull rdfns[3].i=1;
132 f08fdedc 2003-11-23 devnull first=0;
134 f08fdedc 2003-11-23 devnull Xpopm();
135 f08fdedc 2003-11-23 devnull envp=environp;
136 f08fdedc 2003-11-23 devnull start(rdfns, 1, runq->local);
138 f08fdedc 2003-11-23 devnull int Waitfor(int pid, int unused0){
139 f08fdedc 2003-11-23 devnull thread *p;
140 f08fdedc 2003-11-23 devnull Waitmsg *w;
141 f08fdedc 2003-11-23 devnull char errbuf[ERRMAX];
143 f08fdedc 2003-11-23 devnull while((w = wait()) != nil){
144 f08fdedc 2003-11-23 devnull if(w->pid==pid){
145 f08fdedc 2003-11-23 devnull setstatus(w->msg);
146 f08fdedc 2003-11-23 devnull free(w);
147 f08fdedc 2003-11-23 devnull return 0;
149 f08fdedc 2003-11-23 devnull for(p=runq->ret;p;p=p->ret)
150 f08fdedc 2003-11-23 devnull if(p->pid==w->pid){
151 f08fdedc 2003-11-23 devnull p->pid=-1;
152 f08fdedc 2003-11-23 devnull strcpy(p->status, w->msg);
154 f08fdedc 2003-11-23 devnull free(w);
157 f08fdedc 2003-11-23 devnull errstr(errbuf, sizeof errbuf);
158 f08fdedc 2003-11-23 devnull if(strcmp(errbuf, "interrupted")==0) return -1;
159 f08fdedc 2003-11-23 devnull return 0;
161 f08fdedc 2003-11-23 devnull char **mkargv(word *a)
163 f08fdedc 2003-11-23 devnull char **argv=(char **)emalloc((count(a)+2)*sizeof(char *));
164 f08fdedc 2003-11-23 devnull char **argp=argv+1; /* leave one at front for runcoms */
165 f08fdedc 2003-11-23 devnull for(;a;a=a->next) *argp++=a->word;
166 f08fdedc 2003-11-23 devnull *argp=0;
167 f08fdedc 2003-11-23 devnull return argv;
170 f08fdedc 2003-11-23 devnull void addenv(var *v)
172 f08fdedc 2003-11-23 devnull char envname[256];
173 f08fdedc 2003-11-23 devnull word *w;
176 f08fdedc 2003-11-23 devnull if(v->changed){
177 f08fdedc 2003-11-23 devnull v->changed=0;
178 f08fdedc 2003-11-23 devnull snprint(envname, sizeof envname, "/env/%s", v->name);
179 f08fdedc 2003-11-23 devnull if((f=Creat(envname))<0)
180 f08fdedc 2003-11-23 devnull pfmt(err, "rc: can't open %s: %r\n", envname);
182 f08fdedc 2003-11-23 devnull for(w=v->val;w;w=w->next)
183 f08fdedc 2003-11-23 devnull write(f, w->word, strlen(w->word)+1L);
184 f08fdedc 2003-11-23 devnull close(f);
187 f08fdedc 2003-11-23 devnull if(v->fnchanged){
188 f08fdedc 2003-11-23 devnull v->fnchanged=0;
189 f08fdedc 2003-11-23 devnull snprint(envname, sizeof envname, "/env/fn#%s", v->name);
190 f08fdedc 2003-11-23 devnull if((f=Creat(envname))<0)
191 f08fdedc 2003-11-23 devnull pfmt(err, "rc: can't open %s: %r\n", envname);
193 f08fdedc 2003-11-23 devnull if(v->fn){
194 f08fdedc 2003-11-23 devnull fd=openfd(f);
195 f08fdedc 2003-11-23 devnull pfmt(fd, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
196 f08fdedc 2003-11-23 devnull closeio(fd);
198 f08fdedc 2003-11-23 devnull close(f);
202 f08fdedc 2003-11-23 devnull void updenvlocal(var *v)
205 f08fdedc 2003-11-23 devnull updenvlocal(v->next);
206 f08fdedc 2003-11-23 devnull addenv(v);
209 f08fdedc 2003-11-23 devnull void Updenv(void){
210 f08fdedc 2003-11-23 devnull var *v, **h;
211 f08fdedc 2003-11-23 devnull for(h=gvar;h!=&gvar[NVAR];h++)
212 f08fdedc 2003-11-23 devnull for(v=*h;v;v=v->next)
213 f08fdedc 2003-11-23 devnull addenv(v);
214 f08fdedc 2003-11-23 devnull if(runq) updenvlocal(runq->local);
218 be22ae2d 2004-03-26 devnull cmpenv(const void *a, const void *b)
220 be22ae2d 2004-03-26 devnull return strcmp(*(char**)a, *(char**)b);
222 f08fdedc 2003-11-23 devnull char **mkenv(){
223 f08fdedc 2003-11-23 devnull register char **env, **ep, *p, *q;
224 f08fdedc 2003-11-23 devnull register struct var **h, *v;
225 f08fdedc 2003-11-23 devnull register struct word *a;
226 f08fdedc 2003-11-23 devnull register int nvar=0, nchr=0, sep;
228 f08fdedc 2003-11-23 devnull * Slightly kludgy loops look at locals then globals
230 f08fdedc 2003-11-23 devnull for(h=gvar-1;h!=&gvar[NVAR];h++) for(v=h>=gvar?*h:runq->local;v;v=v->next){
231 f08fdedc 2003-11-23 devnull if((v==vlook(v->name)) && v->val){
233 f08fdedc 2003-11-23 devnull nchr+=strlen(v->name)+1;
234 f08fdedc 2003-11-23 devnull for(a=v->val;a;a=a->next)
235 f08fdedc 2003-11-23 devnull nchr+=strlen(a->word)+1;
237 f08fdedc 2003-11-23 devnull if(v->fn){
239 f08fdedc 2003-11-23 devnull nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
242 f08fdedc 2003-11-23 devnull env=(char **)emalloc((nvar+1)*sizeof(char *)+nchr);
244 f08fdedc 2003-11-23 devnull p=(char *)&env[nvar+1];
245 f08fdedc 2003-11-23 devnull for(h=gvar-1;h!=&gvar[NVAR];h++) for(v=h>=gvar?*h:runq->local;v;v=v->next){
246 f08fdedc 2003-11-23 devnull if((v==vlook(v->name)) && v->val){
247 f08fdedc 2003-11-23 devnull *ep++=p;
248 f08fdedc 2003-11-23 devnull q=v->name;
249 f08fdedc 2003-11-23 devnull while(*q) *p++=*q++;
250 f08fdedc 2003-11-23 devnull sep='=';
251 f08fdedc 2003-11-23 devnull for(a=v->val;a;a=a->next){
252 f08fdedc 2003-11-23 devnull *p++=sep;
253 f08fdedc 2003-11-23 devnull sep=SEP;
254 f08fdedc 2003-11-23 devnull q=a->word;
255 f08fdedc 2003-11-23 devnull while(*q) *p++=*q++;
257 f08fdedc 2003-11-23 devnull *p++='\0';
259 f08fdedc 2003-11-23 devnull if(v->fn){
260 f08fdedc 2003-11-23 devnull *ep++=p;
262 f08fdedc 2003-11-23 devnull *p++='#'; *p++='('; *p++=')'; /* to fool Bourne */
263 f08fdedc 2003-11-23 devnull *p++='f'; *p++='n'; *p++=' ';
264 f08fdedc 2003-11-23 devnull q=v->name;
265 f08fdedc 2003-11-23 devnull while(*q) *p++=*q++;
266 f08fdedc 2003-11-23 devnull *p++=' ';
268 f08fdedc 2003-11-23 devnull *p++='f'; *p++='n'; *p++='#';
269 f08fdedc 2003-11-23 devnull q=v->name;
270 f08fdedc 2003-11-23 devnull while(*q) *p++=*q++;
271 f08fdedc 2003-11-23 devnull *p++='=';
272 f08fdedc 2003-11-23 devnull q=v->fn[v->pc-1].s;
273 f08fdedc 2003-11-23 devnull while(*q) *p++=*q++;
274 f08fdedc 2003-11-23 devnull *p++='\n';
275 f08fdedc 2003-11-23 devnull *p++='\0';
279 f08fdedc 2003-11-23 devnull qsort((char *)env, nvar, sizeof ep[0], cmpenv);
280 f08fdedc 2003-11-23 devnull return env;
282 f08fdedc 2003-11-23 devnull void Updenv(void){}
283 f08fdedc 2003-11-23 devnull void Execute(word *args, word *path)
285 f08fdedc 2003-11-23 devnull char **argv=mkargv(args);
286 f08fdedc 2003-11-23 devnull char **env=mkenv();
287 f08fdedc 2003-11-23 devnull char file[1024];
289 f08fdedc 2003-11-23 devnull Updenv();
290 f08fdedc 2003-11-23 devnull for(;path;path=path->next){
291 f08fdedc 2003-11-23 devnull nc=strlen(path->word);
292 f08fdedc 2003-11-23 devnull if(nc<1024){
293 f08fdedc 2003-11-23 devnull strcpy(file, path->word);
294 f08fdedc 2003-11-23 devnull if(file[0]){
295 f08fdedc 2003-11-23 devnull strcat(file, "/");
298 f08fdedc 2003-11-23 devnull if(nc+strlen(argv[1])<1024){
299 f08fdedc 2003-11-23 devnull strcat(file, argv[1]);
300 f08fdedc 2003-11-23 devnull execve(file, argv+1, env);
302 f08fdedc 2003-11-23 devnull else werrstr("command name too long");
305 f08fdedc 2003-11-23 devnull rerrstr(file, sizeof file);
306 f08fdedc 2003-11-23 devnull pfmt(err, "%s: %s\n", argv[1], file);
307 f08fdedc 2003-11-23 devnull efree((char *)argv);
309 f08fdedc 2003-11-23 devnull #define NDIR 256 /* shoud be a better way */
310 f08fdedc 2003-11-23 devnull int Globsize(char *p)
312 f08fdedc 2003-11-23 devnull ulong isglob=0, globlen=NDIR+1;
313 f08fdedc 2003-11-23 devnull for(;*p;p++){
314 f08fdedc 2003-11-23 devnull if(*p==GLOB){
316 f08fdedc 2003-11-23 devnull if(*p!=GLOB) isglob++;
317 f08fdedc 2003-11-23 devnull globlen+=*p=='*'?NDIR:1;
320 f08fdedc 2003-11-23 devnull globlen++;
322 f08fdedc 2003-11-23 devnull return isglob?globlen:0;
324 f08fdedc 2003-11-23 devnull #define NFD 50
325 f08fdedc 2003-11-23 devnull #define NDBUF 32
327 f08fdedc 2003-11-23 devnull Dir *dbuf;
330 f08fdedc 2003-11-23 devnull }dir[NFD];
331 f08fdedc 2003-11-23 devnull int Opendir(char *name)
333 f08fdedc 2003-11-23 devnull Dir *db;
335 f08fdedc 2003-11-23 devnull f=open(name, 0);
336 f08fdedc 2003-11-23 devnull if(f==-1)
337 f08fdedc 2003-11-23 devnull return f;
338 f08fdedc 2003-11-23 devnull db = dirfstat(f);
339 f08fdedc 2003-11-23 devnull if(db!=nil && (db->mode&DMDIR)){
340 f08fdedc 2003-11-23 devnull if(f<NFD){
341 f08fdedc 2003-11-23 devnull dir[f].i=0;
342 f08fdedc 2003-11-23 devnull dir[f].n=0;
344 f08fdedc 2003-11-23 devnull free(db);
345 f08fdedc 2003-11-23 devnull return f;
347 f08fdedc 2003-11-23 devnull free(db);
348 f08fdedc 2003-11-23 devnull close(f);
349 f08fdedc 2003-11-23 devnull return -1;
351 f08fdedc 2003-11-23 devnull int Readdir(int f, char *p)
354 f08fdedc 2003-11-23 devnull if(f<0 || f>=NFD)
355 f08fdedc 2003-11-23 devnull return 0;
356 f08fdedc 2003-11-23 devnull if(dir[f].i==dir[f].n){ /* read */
357 f08fdedc 2003-11-23 devnull free(dir[f].dbuf);
358 f08fdedc 2003-11-23 devnull dir[f].dbuf=0;
359 f08fdedc 2003-11-23 devnull n=dirread(f, &dir[f].dbuf);
360 f08fdedc 2003-11-23 devnull if(n>=0)
361 f08fdedc 2003-11-23 devnull dir[f].n=n;
363 f08fdedc 2003-11-23 devnull dir[f].n=0;
364 f08fdedc 2003-11-23 devnull dir[f].i=0;
366 f08fdedc 2003-11-23 devnull if(dir[f].i==dir[f].n)
367 f08fdedc 2003-11-23 devnull return 0;
368 f08fdedc 2003-11-23 devnull strcpy(p, dir[f].dbuf[dir[f].i].name);
369 f08fdedc 2003-11-23 devnull dir[f].i++;
370 f08fdedc 2003-11-23 devnull return 1;
372 f08fdedc 2003-11-23 devnull void Closedir(int f){
373 f08fdedc 2003-11-23 devnull if(f>=0 && f<NFD){
374 f08fdedc 2003-11-23 devnull free(dir[f].dbuf);
375 f08fdedc 2003-11-23 devnull dir[f].i=0;
376 f08fdedc 2003-11-23 devnull dir[f].n=0;
377 f08fdedc 2003-11-23 devnull dir[f].dbuf=0;
379 f08fdedc 2003-11-23 devnull close(f);
381 f08fdedc 2003-11-23 devnull int interrupted = 0;
383 f08fdedc 2003-11-23 devnull notifyf(void *unused0, char *s)
386 669250d1 2003-12-03 devnull for(i=0;syssigname[i];i++)
387 669250d1 2003-12-03 devnull if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
388 69ab5d3d 2004-03-26 devnull if(strncmp(s, "sys: ", 5)!=0){
389 69ab5d3d 2004-03-26 devnull if(kidpid && !interrupted){
390 69ab5d3d 2004-03-26 devnull interrupted=1;
391 69ab5d3d 2004-03-26 devnull postnote(PNGROUP, kidpid, s);
393 69ab5d3d 2004-03-26 devnull interrupted = 1;
395 669250d1 2003-12-03 devnull goto Out;
397 0b917997 2004-03-04 devnull if(strcmp(s, "sys: child") != 0)
398 0b917997 2004-03-04 devnull pfmt(err, "rc: note: %s\n", s);
399 f08fdedc 2003-11-23 devnull noted(NDFLT);
402 f08fdedc 2003-11-23 devnull if(strcmp(s, "interrupt")!=0 || trap[i]==0){
403 f08fdedc 2003-11-23 devnull trap[i]++;
404 f08fdedc 2003-11-23 devnull ntrap++;
406 f08fdedc 2003-11-23 devnull if(ntrap>=32){ /* rc is probably in a trap loop */
407 f08fdedc 2003-11-23 devnull pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
408 f08fdedc 2003-11-23 devnull abort();
410 f08fdedc 2003-11-23 devnull noted(NCONT);
412 f08fdedc 2003-11-23 devnull void Trapinit(void){
413 f08fdedc 2003-11-23 devnull notify(notifyf);
415 f08fdedc 2003-11-23 devnull void Unlink(char *name)
417 f08fdedc 2003-11-23 devnull remove(name);
419 f08fdedc 2003-11-23 devnull long Write(int fd, char *buf, long cnt)
421 f08fdedc 2003-11-23 devnull return write(fd, buf, (long)cnt);
423 f08fdedc 2003-11-23 devnull long Read(int fd, char *buf, long cnt)
427 669250d1 2003-12-03 devnull i = read(fd, buf, cnt);
428 669250d1 2003-12-03 devnull if(ntrap) dotrap();
429 669250d1 2003-12-03 devnull return i;
431 f08fdedc 2003-11-23 devnull long Seek(int fd, long cnt, long whence)
433 f08fdedc 2003-11-23 devnull return seek(fd, cnt, whence);
435 f08fdedc 2003-11-23 devnull int Executable(char *file)
437 f08fdedc 2003-11-23 devnull Dir *statbuf;
438 f08fdedc 2003-11-23 devnull int ret;
440 f08fdedc 2003-11-23 devnull statbuf = dirstat(file);
441 f08fdedc 2003-11-23 devnull if(statbuf == nil) return 0;
442 f08fdedc 2003-11-23 devnull ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
443 f08fdedc 2003-11-23 devnull free(statbuf);
444 f08fdedc 2003-11-23 devnull return ret;
446 f08fdedc 2003-11-23 devnull int Creat(char *file)
448 f08fdedc 2003-11-23 devnull return create(file, 1, 0666L);
450 f08fdedc 2003-11-23 devnull int Dup(int a, int b){
451 f08fdedc 2003-11-23 devnull return dup(a, b);
453 f08fdedc 2003-11-23 devnull int Dup1(int unused0){
454 f08fdedc 2003-11-23 devnull return -1;
456 f08fdedc 2003-11-23 devnull void Exit(char *stat)
458 f08fdedc 2003-11-23 devnull Updenv();
459 f08fdedc 2003-11-23 devnull setstatus(stat);
460 f08fdedc 2003-11-23 devnull exits(truestatus()?"":getstatus());
462 f08fdedc 2003-11-23 devnull int Eintr(void){
463 f08fdedc 2003-11-23 devnull return interrupted;
465 f08fdedc 2003-11-23 devnull void Noerror(void){
466 f08fdedc 2003-11-23 devnull interrupted=0;
469 be22ae2d 2004-03-26 devnull Isatty(int fd){
470 f08fdedc 2003-11-23 devnull return isatty(fd);
472 f08fdedc 2003-11-23 devnull void Abort(void){
473 f08fdedc 2003-11-23 devnull pfmt(err, "aborting\n");
474 f08fdedc 2003-11-23 devnull flush(err);
475 f08fdedc 2003-11-23 devnull Exit("aborting");
477 f08fdedc 2003-11-23 devnull void Memcpy(char *a, char *b, long n)
479 f08fdedc 2003-11-23 devnull memmove(a, b, (long)n);
481 f08fdedc 2003-11-23 devnull void *Malloc(ulong n){
482 f08fdedc 2003-11-23 devnull return malloc(n);