ref: 1e72ca9a502a78a97523c2b79aa558e16ed4d8bd
parent: 4b6f2aacec7b4a9105e1725b7a1b7c9345225607
author: halfwit <michaelmisch1985@gmail.com>
date: Fri Feb 23 10:12:25 PST 2024
More RC work, use our libc where we can
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@
libauth/libauth.a\
libauthsrv/libauthsrv.a\
libsec/libsec.a\
+ librc/librc.a\
libmp/libmp.a\
libmemdraw/libmemdraw.a\
libmemlayer/libmemlayer.a\
@@ -24,7 +25,6 @@
gui-$(GUI)/libgui.a\
libc/libc.a\
libip/libip.a\
- #librc/librc.a\
# stupid gcc
LIBS=$(LIBS1) $(LIBS1) $(LIBS1) libmachdep.a
@@ -54,11 +54,11 @@
libmp/libmp.a:
(cd libmp; $(MAKE))
-libsec/libsec.a:
- (cd libsec; $(MAKE))
-
librc/librc.a:
(cd librc; $(MAKE))
+
+libsec/libsec.a:
+ (cd libsec; $(MAKE))
libmemdraw/libmemdraw.a:
(cd libmemdraw; $(MAKE))
--- a/drawcpu.h
+++ b/drawcpu.h
@@ -6,6 +6,5 @@
extern int dialfactotum(void);
extern char *getuser(void);
extern int session(int);
-extern char *estrdup(char*);
extern int aanclient(char*, int);
extern int dbg;
\ No newline at end of file
--- /dev/null
+++ b/include/rc.h
@@ -1,0 +1,159 @@
+/*
+ * Plan9 is defined for plan 9
+ * otherwise its UNIX.
+ * Please don't litter the code with ifdefs. The three below (and one in
+ * getflags) should be enough.
+ */
+#ifdef Plan9
+#include <u.h>
+#include <libc.h>
+#define NSIG 32
+#define SIGINT 2
+#define SIGQUIT 3
+#else
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#ifndef NSIG
+#define NSIG 32
+#endif
+#endif
+
+#define YYMAXDEPTH 500
+typedef struct tree tree;
+typedef struct word word;
+typedef struct io io;
+typedef union code code;
+typedef struct var var;
+typedef struct list list;
+typedef struct lexer lexer;
+typedef struct redir redir;
+typedef struct thread thread;
+typedef struct builtin builtin;
+
+struct tree{
+ int type;
+ int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */
+ int line;
+ char glob; /* 0=string, 1=glob, 2=pattern see globprop() and noglobs() */
+ char quoted;
+ char iskw;
+ char *str;
+ tree *child[3];
+ tree *next;
+};
+tree *newtree(void);
+tree *token(char*, int), *klook(char*), *tree1(int, tree*);
+tree *tree2(int, tree*, tree*), *tree3(int, tree*, tree*, tree*);
+tree *mung1(tree*, tree*), *mung2(tree*, tree*, tree*);
+tree *mung3(tree*, tree*, tree*, tree*), *epimung(tree*, tree*);
+tree *simplemung(tree*);
+tree *globprop(tree*);
+char *fnstr(tree*);
+void runscript(int, int, char**);
+/*
+ * The first word of any code vector is a reference count
+ * and the second word is a string for srcfile().
+ * Code starts at pc 2. The last code word must be a zero
+ * terminator for codefree().
+ * Always create a new reference to a code vector by calling codecopy(.).
+ * Always call codefree(.) when deleting a reference.
+ */
+union code{
+ void (*f)(void);
+ int i;
+ char *s;
+};
+
+#define NTOK 8192
+
+struct lexer{
+ io *input;
+ char *file;
+ int line;
+
+ char *prolog;
+ char *epilog;
+
+ int peekc;
+ int future;
+ int lastc;
+
+ char eof;
+ char inquote;
+ char incomm;
+ char lastword; /* was the last token read a word or compound word terminator? */
+ char lastdol; /* was the last token read '$' or '$#' or '"'? */
+ char iflast; /* static `if not' checking */
+
+ char qflag;
+
+ char tok[NTOK];
+};
+extern lexer *lex; /* current lexer */
+lexer *newlexer(io*, char*);
+void freelexer(lexer*);
+
+#define APPEND 1
+#define WRITE 2
+#define READ 3
+#define HERE 4
+#define DUPFD 5
+#define CLOSE 6
+#define RDWR 7
+
+struct var{
+ var *next; /* next on hash or local list */
+ word *val; /* value */
+ code *fn; /* pointer to function's code vector */
+ int pc; /* pc of start of function */
+ char fnchanged;
+ char changed;
+ char name[];
+};
+var *vlook(char*), *gvlook(char*), *newvar(char*, var*);
+void setvar(char*, word*), freevar(var*);
+
+#define NVAR 521
+extern var *gvar[NVAR]; /* hash for globals */
+
+#define new(type) ((type *)emalloc(sizeof(type)))
+
+void *emalloc(long);
+void *erealloc(void *, long);
+
+/*
+ * Glob character escape in strings:
+ * In a string, GLOB must be followed by *?[ or GLOB.
+ * GLOB* matches any string
+ * GLOB? matches any single character
+ * GLOB[...] matches anything in the brackets
+ * GLOBGLOB matches GLOB
+ */
+#define GLOB ((char)0x01)
+/*
+ * Is c the first character of a utf sequence?
+ */
+#define onebyte(c) (((c)&0x80)==0x00)
+#define twobyte(c) (((c)&0xe0)==0xc0)
+#define threebyte(c) (((c)&0xf0)==0xe0)
+#define fourbyte(c) (((c)&0xf8)==0xf0)
+#define xbyte(c) (((c)&0xc0)==0x80)
+
+extern char *argv0;
+extern int nerror; /* number of errors encountered during compilation */
+extern int doprompt; /* is it time for a prompt? */
+extern io *err;
+
+/*
+ * Which fds are the reading/writing end of a pipe?
+ * Unfortunately, this can vary from system to system.
+ * 9th edition Unix doesn't care, the following defines
+ * work on plan 9.
+ */
+#define PRD 0
+#define PWR 1
+extern char Rcmain[], Fdprefix[];
+extern char *Signame[];
--- a/include/user.h
+++ b/include/user.h
@@ -85,6 +85,7 @@
extern void setmalloctag(void*, uintptr);
extern void setrealloctag(void*, uintptr);
extern int errstr(char*, uint);
+extern char *estrdup(char*);
extern int rerrstr(char*, uint);
extern int encrypt(void*, void*, int);
extern int decrypt(void*, void*, int);
--- a/librc/Makefile
+++ b/librc/Makefile
@@ -1,7 +1,7 @@
ROOT=..
include ../Make.config
-
LIB=librc.a
+
OFILES=\
code.$O\
exec.$O\
@@ -18,13 +18,14 @@
tree.$O\
var.$O\
havefork.$O\
- unix.$O\
- y.tab.c
+ drawcpu.$O\
+ y.tab.$O\
default: $(LIB)
-$(LIB): $(OFILES) $(YFILES)
- $(AR) r $(LIB) $(OFILES) $(YFILES)
+$(LIB): $(OFILES)
+ $(AR) r $(LIB) $(OFILES)
$(RANLIB) $(LIB)
%.$O: %.c
$(CC) $(CFLAGS) $*.c
+
\ No newline at end of file
--- a/librc/code.c
+++ b/librc/code.c
@@ -1,8 +1,11 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
#include "io.h"
#include "exec.h"
#include "fns.h"
#include "getflags.h"
+#include "y.tab.h"
#define c0 t->child[0]
#define c1 t->child[1]
#define c2 t->child[2]
--- /dev/null
+++ b/librc/drawcpu.c
@@ -1,0 +1,275 @@
+/*
+ * Unix versions of system-specific functions
+ * By convention, exported routines herein have names beginning with an
+ * upper case letter.
+ */
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
+#include <errno.h>
+#include <string.h>
+#include "exec.h"
+#include "io.h"
+#include "fns.h"
+#include "getflags.h"
+
+static void execfinit(void);
+
+// TODO: add bind, mount, etc
+builtin Builtin[] = {
+ "cd", execcd,
+ "whatis", execwhatis,
+ "eval", execeval,
+ "exec", execexec, /* but with popword first */
+ "exit", execexit,
+ "shift", execshift,
+ "wait", execwait,
+ ".", execdot,
+ "flag", execflag,
+ "finit", execfinit,
+ 0
+};
+
+char Rcmain[] = "./librc/rcmain.drawcpu";
+char Fdprefix[] = "/dev/fd/";
+char *Signame[] = {
+ "sigexit", "sighup", "sigint", "sigquit",
+ "sigalrm", "sigkill", "sigfpe", "sigterm",
+ 0
+};
+
+/*
+ * finit could be removed but is kept for
+ * backwards compatibility, see: rcmain.plan9
+ */
+static void
+execfinit(void)
+{
+ char *cmds = estrdup("for(i in '/env/fn#'*){. -bq $i}\n");
+ int line = runq->line;
+ poplist();
+ execcmds(openiocore(cmds, strlen(cmds)), estrdup(srcfile(runq)), runq->local, runq->redir);
+ runq->lex->line = line;
+ runq->lex->qflag = 1;
+}
+
+char*
+Env(char *name, int fn)
+{
+ static char buf[128];
+
+ strcpy(buf, "/env/");
+ if(fn) strcat(buf, "fn#");
+ return strncat(buf, name, sizeof(buf)-1);
+}
+/* TODO: Proper env read
+void
+Vinit(void)
+{
+ int dir, fd, i, n;
+ Dir *ent;
+
+ dir = open(Env("", 0), 0);
+ if(dir<0){
+ pfmt(err, "%s: can't open: %s\n", argv0, strerror(errno));
+ return;
+ }
+ for(;;){
+ ent = 0;
+ n = devdirread(dir, ent, sizeof ent);
+ if(n <= 0)
+ break;
+ for(i = 0; i<n; i++){
+ if(ent[i].length<=0 || strncmp(ent[i].name, "fn#", 3)==0)
+ continue;
+ if((fd = open(Env(ent[i].name, 0), 0))>=0){
+ io *f = openiofd(fd);
+ word *w = 0, **wp = &w;
+ char *s;
+ while((s = rstr(f, "")) != 0){
+ *wp = Newword(s, (word*)0);
+ wp = &(*wp)->next;
+ }
+ closeio(f);
+ setvar(ent[i].name, w);
+ vlook(ent[i].name)->changed = 0;
+ }
+ }
+ free(ent);
+ }
+ close(dir);
+}
+*/
+
+int
+Waitfor(int pid)
+{
+ thread *p;
+ Waitmsg *w;
+
+ if(pid >= 0 && !havewaitpid(pid))
+ return 0;
+
+ while((w = wait(pid)) != nil){
+ delwaitpid(w->pid);
+ if(w->pid==pid){
+ setstatus(w->msg);
+ free(w);
+ return 0;
+ }
+ for(p = runq->ret;p;p = p->ret)
+ if(p->pid==w->pid){
+ p->pid=-1;
+ p->status = estrdup(w->msg);
+ break;
+ }
+ free(w);
+ }
+
+ if(strcmp(strerror(errno), "interrupted")==0) return -1;
+ return 0;
+}
+
+// TODO: /dev/env integration
+static void
+addenv(var *v)
+{
+ word *w;
+ int fd;
+ io *f;
+
+ if(v->changed){
+ v->changed = 0;
+ if((fd = create(Env(v->name, 0), ORDWR, 0644))<0)
+ pfmt(err, "%s: can't open: %s\n", argv0, strerror(errno));
+ else{
+ f = openiofd(fd);
+ for(w = v->val;w;w = w->next){
+ pstr(f, w->word);
+ pchr(f, '\0');
+ }
+ flushio(f);
+ closeio(f);
+ }
+ }
+ if(v->fnchanged){
+ v->fnchanged = 0;
+ if((fd = create(Env(v->name, 1), ORDWR, 0644))<0)
+ pfmt(err, "%s: can't open: %s\n", argv0, strerror(errno));
+ else{
+ f = openiofd(fd);
+ if(v->fn)
+ pfmt(f, "fn %q %s\n", v->name, v->fn[v->pc-1].s);
+ flushio(f);
+ closeio(f);
+ }
+ }
+}
+
+static void
+updenvlocal(var *v)
+{
+ if(v){
+ updenvlocal(v->next);
+ addenv(v);
+ }
+}
+
+void
+Updenv(void)
+{
+ var *v, **h;
+ for(h = gvar;h!=&gvar[NVAR];h++)
+ for(v=*h;v;v = v->next)
+ addenv(v);
+ if(runq)
+ updenvlocal(runq->local);
+ if(err)
+ flushio(err);
+}
+
+typedef struct rdir rdir;
+struct rdir {
+ Dir *dbuf;
+ int i, n;
+ int fd;
+};
+
+static int
+trimdirs(Dir *d, int nd)
+{
+ int r, w;
+
+ for(r=w=0; r<nd; r++)
+ if(d[r].mode&DMDIR)
+ d[w++] = d[r];
+ return w;
+}
+
+static int interrupted = 0;
+static char *syssigname[] = {
+ "exit", /* can't happen */
+ "hangup",
+ "interrupt",
+ "quit", /* can't happen */
+ "alarm",
+ "kill",
+ "sys: fp: ",
+ "term",
+ 0
+};
+
+void
+notifyf(void* q, char *s)
+{
+ int i;
+ USED(q);
+ for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
+ if(strncmp(s, "sys: ", 5)!=0) interrupted = 1;
+ goto Out;
+ }
+ // TODO: Handle notes
+ //noted(NDFLT);
+ return;
+Out:
+ if(strcmp(s, "interrupt")!=0 || trap[i]==0){
+ trap[i]++;
+ ntrap++;
+ }
+ // TODO: Handle notes
+ //noted(NCONT);
+}
+
+int
+Executable(char *file)
+{
+ Dir *statbuf;
+ int ret;
+
+ statbuf = dirstat(file);
+ if(statbuf == nil)
+ return 0;
+ ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
+ free(statbuf);
+ return ret;
+}
+
+void
+Noerror(void)
+{
+ interrupted = 0;
+}
+
+int
+Isatty(int fd)
+{
+ isatty(fd);
+}
+
+void
+Prompt(char *s)
+{
+ pstr(err, s);
+ flushio(err);
+}
+
\ No newline at end of file
--- a/librc/exec.c
+++ b/librc/exec.c
@@ -1,4 +1,7 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
+#include <errno.h>
#include "getflags.h"
#include "exec.h"
#include "io.h"
@@ -222,12 +225,11 @@
* start interpreting code
*/
void
-rcmain(int argc, char *argv[])
+runscript(int fd, int argc, char **argv)
{
code bootstrap[20];
char num[12];
char *rcmain=Rcmain;
-
int i;
argv0 = argv[0];
argc = getflags(argc, argv, "srdiIlxebpvVc:1m:1[command]", 1);
@@ -241,8 +243,8 @@
if(flag['m']) rcmain = flag['m'][0];
err = openiofd(2);
kinit();
- Trapinit();
- Vinit();
+ notify(notifyf);
+ // Vinit();
inttoascii(num, mypid = getpid());
setvar("pid", newword(num, (word *)0));
setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
@@ -346,11 +348,11 @@
break;
}
file = runq->argv->words->word;
- if((fd = Open(file, 1))<0 && (fd = Creat(file))<0){
- Xerror3(">> can't open", file, Errstr());
+ if((fd = open(file, 1))<0 && (fd = create(file, ORDWR, 0644))<0){
+ Xerror3(">> can't open", file, strerror(errno));
return;
}
- Seek(fd, 0L, 2);
+ seek(fd, 0L, 2);
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
poplist();
}
@@ -401,7 +403,7 @@
return;
}
}
- Exit();
+ _exit(0);
}
void
@@ -468,7 +470,7 @@
}
s++;
for(i='a'; i<'z'; i++){
- if(access(tmp, 0)!=0 && (fd = Creat(tmp))>=0)
+ if(access(tmp, 0)!=0 && (fd = create(tmp, ORDWR, 0644))>=0)
return fd;
*s = i;
}
@@ -483,7 +485,7 @@
io *io;
if((fd = herefile(file))<0){
- Xerror3("<< can't get temp file", file, Errstr());
+ Xerror3("<< can't get temp file", file, strerror(errno));
return;
}
io = openiofd(fd);
@@ -492,8 +494,8 @@
closeio(io);
/* open for reading and unlink */
- if((fd = Open(file, 3))<0){
- Xerror3("<< can't open", file, Errstr());
+ if((fd = open(file, 3))<0){
+ Xerror3("<< can't open", file, strerror(errno));
return;
}
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
@@ -506,16 +508,16 @@
int fd;
if((fd = herefile(file))<0){
- Xerror3("<< can't get temp file", file, Errstr());
+ Xerror3("<< can't get temp file", file, strerror(errno));
return;
}
body = runq->code[runq->pc++].s;
- Write(fd, body, strlen(body));
- Close(fd);
+ write(fd, body, strlen(body));
+ close(fd);
/* open for reading and unlink */
- if((fd = Open(file, 3))<0){
- Xerror3("<< can't open", file, Errstr());
+ if((fd = open(file, 3))<0){
+ Xerror3("<< can't open", file, strerror(errno));
return;
}
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
@@ -538,8 +540,8 @@
break;
}
file = runq->argv->words->word;
- if((fd = Open(file, 0))<0){
- Xerror3("< can't open", file, Errstr());
+ if((fd = open(file, 0))<0){
+ Xerror3("< can't open", file, strerror(errno));
return;
}
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
@@ -563,8 +565,8 @@
break;
}
file = runq->argv->words->word;
- if((fd = Open(file, 2))<0){
- Xerror3("<> can't open", file, Errstr());
+ if((fd = open(file, 2))<0){
+ Xerror3("<> can't open", file, strerror(errno));
return;
}
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
@@ -580,7 +582,7 @@
panic("Xpopredir null!", 0);
runq->redir = rp->next;
if(rp->type==ROPEN)
- Close(rp->from);
+ close(rp->from);
free(rp);
}
@@ -591,7 +593,7 @@
Xpopredir();
popthread();
if(runq==0)
- Exit();
+ _exit(0);
}
void
@@ -638,8 +640,8 @@
break;
}
file = runq->argv->words->word;
- if((fd = Creat(file))<0){
- Xerror3("> can't create", file, Errstr());
+ if((fd = create(file, ORDWR, 0644))<0){
+ Xerror3("> can't create", file, strerror(errno));
return;
}
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
@@ -1020,8 +1022,8 @@
Noerror();
nerror = 0;
if(yyparse()){
- if(p->iflag && (!lex->eof || Eintr())){
- if(Eintr()){
+ if(p->iflag && (!lex->eof || errno == EINTR)){
+ if(errno == EINTR){
pchr(err, '\n');
lex->eof = 0;
}
--- a/librc/fns.h
+++ b/librc/fns.h
@@ -1,35 +1,17 @@
-void Abort(void);
-int Chdir(char*);
-void Close(int);
-void Closedir(void*);
-int Creat(char*);
-int Dup(int, int);
-int Dup1(int);
-int Eintr(void);
+
int Executable(char*);
-void Exec(char**);
-void Exit(void);
-char* Errstr(void);
char* Freeword(word*);
-int Fork(void);
char* Getstatus(void);
int Isatty(int);
word* Newword(char*,word*);
void Noerror(void);
-int Open(char*, int);
-void* Opendir(char*);
word* Poplist(void);
char* Popword(void);
word* Pushword(char*);
-long Read(int, void*, long);
-char* Readdir(void*, int);
-long Seek(int, long, long);
void Setstatus(char*);
-void Trapinit(void);
void Updenv(void);
void Vinit(void);
int Waitfor(int);
-long Write(int, void*, long);
void addwaitpid(int);
void clearwaitpids(void);
void codefree(code*);
@@ -39,6 +21,7 @@
void delwaitpid(int);
void dotrap(void);
void freenodes(void);
+void notifyf(void*, char*);
void freewords(word*);
void globword(word*);
int havewaitpid(int);
@@ -47,8 +30,7 @@
void kinit(void);
int mapfd(int);
int match(char*, char*, int);
-char* makepath(char*, char*);
-void panic(char*, int);
+char* rcmakepath(char*, char*);
void pfln(io*, char*, int);
void poplist(void);
void popword(void);
@@ -58,7 +40,6 @@
void pushlist(void);
void pushredir(int, int, int);
word* pushword(char*);
-void rcmain(int, char*[]);
void readhere(io*);
void heredoc(tree*);
void setstatus(char*);
@@ -70,3 +51,4 @@
void yyerror(char*);
int yylex(void);
int yyparse(void);
+#define notify(x)
\ No newline at end of file
--- a/librc/getflags.c
+++ b/librc/getflags.c
@@ -1,4 +1,4 @@
-#include "rc.h"
+#include <rc.h>
#include "getflags.h"
#include "fns.h"
char *flagset[] = {"<flag>"};
@@ -206,7 +206,7 @@
}
errs("\n");
setstatus("bad flags");
- Exit();
+ _exit(0);
}
static void
@@ -228,7 +228,7 @@
{
*bufp++=c;
if(bufp==&buf[NBUF] || c=='\n'){
- Write(2, buf, bufp-buf);
+ write(2, buf, bufp-buf);
bufp = buf;
}
}
--- a/librc/glob.c
+++ b/librc/glob.c
@@ -1,4 +1,7 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <dirent.h>
+#include <rc.h>
#include "exec.h"
#include "fns.h"
@@ -59,11 +62,21 @@
static void
pappend(char **pdir, char *name)
{
- char *path = makepath(*pdir, name);
+ char *path = rcmakepath(*pdir, name);
free(*pdir);
*pdir = path;
}
+char*
+nextdirent(void *arg)
+{
+ DIR *rd = arg;
+ struct dirent *ent = readdir(rd);
+ if(ent == NULL)
+ return 0;
+ return ent->d_name;
+}
+
static word*
globdir(word *list, char *pattern, char *name)
{
@@ -71,7 +84,7 @@
void *dir;
#ifdef Plan9
- /* append slashes, Readdir() already filtered directories */
+ /* append slashes, readdir() already filtered directories */
while(*pattern=='/'){
pappend(&name, "/");
pattern++;
@@ -102,15 +115,15 @@
*glob=GLOB;
/* read the directory and recur for any entry that matches */
- dir = Opendir(name[0]?name:".");
+ dir = opendir(name[0]?name:".");
if(dir==0)
goto out;
slash=strchr(glob, '/');
- while((entry=Readdir(dir, slash!=0)) != 0){
+ while((entry=nextdirent(dir)) != 0){
if(matchfn(entry, pattern))
- list = globdir(list, slash?slash:"", makepath(name, entry));
+ list = globdir(list, slash?slash:"", rcmakepath(name, entry));
}
- Closedir(dir);
+ closedir(dir);
out:
free(name);
return list;
--- a/librc/havefork.c
+++ b/librc/havefork.c
@@ -1,4 +1,7 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
+#include <errno.h>
#include "getflags.h"
#include "exec.h"
#include "io.h"
@@ -48,9 +51,9 @@
int pid;
char npid[10];
- switch(pid = Fork()){
+ switch(pid = fork()){
case -1:
- Xerror2("try again", Errstr());
+ Xerror2("try again", strerror(errno));
break;
case 0:
clearwaitpids();
@@ -76,16 +79,16 @@
int pfd[2];
if(pipe(pfd)<0){
- Xerror2("can't get pipe", Errstr());
+ Xerror2("can't get pipe", strerror(errno));
return;
}
- switch(pid = Fork()){
+ switch(pid = fork()){
case -1:
- Xerror2("try again", Errstr());
+ Xerror2("try again", strerror(errno));
break;
case 0:
clearwaitpids();
- Close(pfd[PRD]);
+ close(pfd[PRD]);
start(p->code, pc+2, runq->local, runq->redir);
runq->ret = 0;
pushredir(ROPEN, pfd[PWR], lfd);
@@ -92,7 +95,7 @@
break;
default:
addwaitpid(pid);
- Close(pfd[PWR]);
+ close(pfd[PWR]);
start(p->code, p->code[pc].i, runq->local, runq->redir);
pushredir(ROPEN, pfd[PRD], rfd);
p->pc = p->code[pc+1].i;
@@ -114,24 +117,24 @@
io *f;
if(pipe(pfd)<0){
- Xerror2("can't make pipe", Errstr());
+ Xerror2("can't make pipe", strerror(errno));
return;
}
- switch(pid = Fork()){
+ switch(pid = fork()){
case -1:
- Xerror2("try again", Errstr());
- Close(pfd[PRD]);
- Close(pfd[PWR]);
+ Xerror2("try again", strerror(errno));
+ close(pfd[PRD]);
+ close(pfd[PWR]);
return;
case 0:
clearwaitpids();
- Close(pfd[PRD]);
+ close(pfd[PRD]);
start(runq->code, runq->pc+1, runq->local, runq->redir);
pushredir(ROPEN, pfd[PWR], 1);
return;
default:
addwaitpid(pid);
- Close(pfd[PWR]);
+ close(pfd[PWR]);
split = Popword();
poplist();
@@ -163,7 +166,7 @@
int sidefd, mainfd;
if(pipe(pfd)<0){
- Xerror2("can't get pipe", Errstr());
+ Xerror2("can't get pipe", strerror(errno));
return;
}
if(p->code[pc].i==READ){
@@ -174,13 +177,13 @@
sidefd = pfd[PRD];
mainfd = pfd[PWR];
}
- switch(pid = Fork()){
+ switch(pid = fork()){
case -1:
- Xerror2("try again", Errstr());
+ Xerror2("try again", strerror(errno));
break;
case 0:
clearwaitpids();
- Close(mainfd);
+ close(mainfd);
start(p->code, pc+2, runq->local, runq->redir);
pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
runq->ret = 0;
@@ -187,7 +190,7 @@
break;
default:
addwaitpid(pid);
- Close(sidefd);
+ close(sidefd);
pushredir(ROPEN, mainfd, mainfd);
shuffleredir(); /* shuffle redir to bottom of stack for Xpopredir() */
strcpy(name, Fdprefix);
@@ -203,9 +206,9 @@
{
int pid;
- switch(pid = Fork()){
+ switch(pid = fork()){
case -1:
- Xerror2("try again", Errstr());
+ Xerror2("try again", strerror(errno));
break;
case 0:
clearwaitpids();
@@ -226,7 +229,7 @@
{
int pid;
- switch(pid = Fork()){
+ switch(pid = fork()){
case -1:
return -1;
case 0:
--- a/librc/here.c
+++ b/librc/here.c
@@ -1,7 +1,8 @@
-#include "rc.h"
+#include <rc.h>
#include "exec.h"
#include "io.h"
#include "fns.h"
+#include "y.tab.h"
void psubst(io*, unsigned char*);
void pstrs(io*, word*);
--- a/librc/io.c
+++ b/librc/io.c
@@ -1,4 +1,6 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
#include "exec.h"
#include "io.h"
#include "fns.h"
@@ -148,10 +150,10 @@
pptr(io *f, void *p)
{
static char hex[] = "0123456789ABCDEF";
- unsigned long long v;
+ unsigned long v;
int n;
- v = (unsigned long long)p;
+ v = (unsigned long)p;
if(sizeof(v) == sizeof(p) && v>>32)
for(n = 60;n>=32;n-=4) pchr(f, hex[(v>>n)&0xF]);
for(n = 28;n>=0;n-=4) pchr(f, hex[(v>>n)&0xF]);
@@ -274,8 +276,8 @@
}
else{
n = f->bufp - f->buf;
- if(n && Write(f->fd, f->buf, n) != n){
- Write(2, "Write error\n", 12);
+ if(n && write(f->fd, f->buf, n) != n){
+ write(2, "Write error\n", 12);
if(ntrap)
dotrap();
}
@@ -287,7 +289,7 @@
void
closeio(io *f)
{
- if(f->fd>=0) Close(f->fd);
+ if(f->fd>=0) close(f->fd);
free(closeiostr(f));
}
@@ -295,7 +297,7 @@
emptyiobuf(io *f)
{
int n;
- if(f->fd<0 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
+ if(f->fd<0 || (n = read(f->fd, f->buf, NBUF))<=0) return EOF;
f->bufp = f->buf;
f->ebuf = f->buf + n;
return *f->bufp++;
--- a/librc/lex.c
+++ b/librc/lex.c
@@ -1,7 +1,8 @@
-#include "rc.h"
+#include <rc.h>
#include "io.h"
#include "getflags.h"
#include "fns.h"
+#include "y.tab.h"
lexer *lex;
--- a/librc/mkfile
+++ /dev/null
@@ -1,46 +1,0 @@
-</$objtype/mkfile
-
-TARG=rc
-OFILES=\
- code.$O\
- exec.$O\
- getflags.$O\
- glob.$O\
- here.$O\
- io.$O\
- lex.$O\
- pcmd.$O\
- pfnc.$O\
- simple.$O\
- subr.$O\
- trap.$O\
- tree.$O\
- var.$O\
- havefork.$O\
- plan9.$O\
- y.tab.$O\
-
-HFILES=rc.h\
- y.tab.h\
- io.h\
- exec.h\
- fns.h\
- getflags.h\
-
-YFILES=syn.y
-
-BIN=/$objtype/bin
-
-UPDATE=\
- mkfile\
- $HFILES\
- ${OFILES:%.$O=%.c}\
- $YFILES\
- ${TARG:%=/386/bin/%}\
-
-CFLAGS=$CFLAGS -DPlan9
-
-</sys/src/cmd/mkone
-
-clean:V:
- rm -f [$OS].out *.[$OS] y.tab.? y.debug $TARG
--- a/librc/pcmd.c
+++ b/librc/pcmd.c
@@ -1,6 +1,7 @@
-#include "rc.h"
+#include <rc.h>
#include "io.h"
#include "fns.h"
+#include "y.tab.h"
#define c0 t->child[0]
#define c1 t->child[1]
--- a/librc/pfnc.c
+++ b/librc/pfnc.c
@@ -1,4 +1,4 @@
-#include "rc.h"
+#include <rc.h>
#include "exec.h"
#include "io.h"
#include "fns.h"
--- a/librc/plan9.c
+++ /dev/null
@@ -1,494 +1,0 @@
-/*
- * Plan 9 versions of system-specific functions
- * By convention, exported routines herein have names beginning with an
- * upper case letter.
- */
-#include "rc.h"
-#include "exec.h"
-#include "io.h"
-#include "fns.h"
-#include "getflags.h"
-
-static void execrfork(void);
-static void execfinit(void);
-
-builtin Builtin[] = {
- "cd", execcd,
- "whatis", execwhatis,
- "eval", execeval,
- "exec", execexec, /* but with popword first */
- "exit", execexit,
- "shift", execshift,
- "wait", execwait,
- ".", execdot,
- "flag", execflag,
- "finit", execfinit,
- "rfork", execrfork,
- 0
-};
-
-char Rcmain[]="/rc/lib/rcmain";
-char Fdprefix[]="/fd/";
-
-char *Signame[] = {
- "sigexit", "sighup", "sigint", "sigquit",
- "sigalrm", "sigkill", "sigfpe", "sigterm",
- 0
-};
-static char *syssigname[] = {
- "exit", /* can't happen */
- "hangup",
- "interrupt",
- "quit", /* can't happen */
- "alarm",
- "kill",
- "sys: fp: ",
- "term",
- 0
-};
-
-/*
- * finit could be removed but is kept for
- * backwards compatibility, see: rcmain.plan9
- */
-static void
-execfinit(void)
-{
- char *cmds = estrdup("for(i in '/env/fn#'*){. -bq $i}\n");
- int line = runq->line;
- poplist();
- execcmds(openiocore(cmds, strlen(cmds)), estrdup(srcfile(runq)), runq->local, runq->redir);
- runq->lex->line = line;
- runq->lex->qflag = 1;
-}
-
-static void
-execrfork(void)
-{
- int arg;
- char *s;
-
- switch(count(runq->argv->words)){
- case 1:
- arg = RFENVG|RFNAMEG|RFNOTEG;
- break;
- case 2:
- arg = 0;
- for(s = runq->argv->words->next->word;*s;s++) switch(*s){
- default:
- goto Usage;
- case 'n':
- arg|=RFNAMEG; break;
- case 'N':
- arg|=RFCNAMEG;
- break;
- case 'm':
- arg|=RFNOMNT; break;
- case 'e':
- arg|=RFENVG; break;
- case 'E':
- arg|=RFCENVG; break;
- case 's':
- arg|=RFNOTEG; break;
- case 'f':
- arg|=RFFDG; break;
- case 'F':
- arg|=RFCFDG; break;
- }
- break;
- default:
- Usage:
- pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word);
- setstatus("rfork usage");
- poplist();
- return;
- }
- if(rfork(arg)==-1){
- pfmt(err, "%s: %s failed\n", argv0, runq->argv->words->word);
- setstatus("rfork failed");
- } else {
- if(arg & RFCFDG){
- redir *rp;
- for(rp = runq->redir; rp; rp = rp->next)
- rp->type = 0;
- }
- setstatus("");
- }
- poplist();
-}
-
-char*
-Env(char *name, int fn)
-{
- static char buf[128];
-
- strcpy(buf, "/env/");
- if(fn) strcat(buf, "fn#");
- return strncat(buf, name, sizeof(buf)-1);
-}
-
-void
-Vinit(void)
-{
- int dir, fd, i, n;
- Dir *ent;
-
- dir = Open(Env("", 0), 0);
- if(dir<0){
- pfmt(err, "%s: can't open: %s\n", argv0, Errstr());
- return;
- }
- for(;;){
- ent = 0;
- n = dirread(dir, &ent);
- if(n <= 0)
- break;
- for(i = 0; i<n; i++){
- if(ent[i].length<=0 || strncmp(ent[i].name, "fn#", 3)==0)
- continue;
- if((fd = Open(Env(ent[i].name, 0), 0))>=0){
- io *f = openiofd(fd);
- word *w = 0, **wp = &w;
- char *s;
- while((s = rstr(f, "")) != 0){
- *wp = Newword(s, (word*)0);
- wp = &(*wp)->next;
- }
- closeio(f);
- setvar(ent[i].name, w);
- vlook(ent[i].name)->changed = 0;
- }
- }
- free(ent);
- }
- Close(dir);
-}
-
-char*
-Errstr(void)
-{
- static char err[ERRMAX];
- rerrstr(err, sizeof err);
- return err;
-}
-
-int
-Waitfor(int pid)
-{
- thread *p;
- Waitmsg *w;
-
- if(pid >= 0 && !havewaitpid(pid))
- return 0;
-
- while((w = wait()) != nil){
- delwaitpid(w->pid);
- if(w->pid==pid){
- setstatus(w->msg);
- free(w);
- return 0;
- }
- for(p = runq->ret;p;p = p->ret)
- if(p->pid==w->pid){
- p->pid=-1;
- p->status = estrdup(w->msg);
- break;
- }
- free(w);
- }
-
- if(strcmp(Errstr(), "interrupted")==0) return -1;
- return 0;
-}
-
-static void
-addenv(var *v)
-{
- word *w;
- int fd;
- io *f;
-
- if(v->changed){
- v->changed = 0;
- if((fd = Creat(Env(v->name, 0)))<0)
- pfmt(err, "%s: can't open: %s\n", argv0, Errstr());
- else{
- f = openiofd(fd);
- for(w = v->val;w;w = w->next){
- pstr(f, w->word);
- pchr(f, '\0');
- }
- flushio(f);
- closeio(f);
- }
- }
- if(v->fnchanged){
- v->fnchanged = 0;
- if((fd = Creat(Env(v->name, 1)))<0)
- pfmt(err, "%s: can't open: %s\n", argv0, Errstr());
- else{
- f = openiofd(fd);
- if(v->fn)
- pfmt(f, "fn %q %s\n", v->name, v->fn[v->pc-1].s);
- flushio(f);
- closeio(f);
- }
- }
-}
-
-static void
-updenvlocal(var *v)
-{
- if(v){
- updenvlocal(v->next);
- addenv(v);
- }
-}
-
-void
-Updenv(void)
-{
- var *v, **h;
- for(h = gvar;h!=&gvar[NVAR];h++)
- for(v=*h;v;v = v->next)
- addenv(v);
- if(runq)
- updenvlocal(runq->local);
- if(err)
- flushio(err);
-}
-
-void
-Exec(char **argv)
-{
- exec(argv[0], argv+1);
-}
-
-int
-Fork(void)
-{
- Updenv();
- return rfork(RFPROC|RFFDG|RFREND);
-}
-
-
-typedef struct readdir readdir;
-struct readdir {
- Dir *dbuf;
- int i, n;
- int fd;
-};
-
-void*
-Opendir(char *name)
-{
- readdir *rd;
- int fd;
- if((fd = Open(name, 0))<0)
- return 0;
- rd = new(readdir);
- rd->dbuf = 0;
- rd->i = 0;
- rd->n = 0;
- rd->fd = fd;
- return rd;
-}
-
-static int
-trimdirs(Dir *d, int nd)
-{
- int r, w;
-
- for(r=w=0; r<nd; r++)
- if(d[r].mode&DMDIR)
- d[w++] = d[r];
- return w;
-}
-
-char*
-Readdir(void *arg, int onlydirs)
-{
- readdir *rd = arg;
- int n;
-Again:
- if(rd->i>=rd->n){ /* read */
- free(rd->dbuf);
- rd->dbuf = 0;
- n = dirread(rd->fd, &rd->dbuf);
- if(n>0){
- if(onlydirs){
- n = trimdirs(rd->dbuf, n);
- if(n == 0)
- goto Again;
- }
- rd->n = n;
- }else
- rd->n = 0;
- rd->i = 0;
- }
- if(rd->i>=rd->n)
- return 0;
- return rd->dbuf[rd->i++].name;
-}
-
-void
-Closedir(void *arg)
-{
- readdir *rd = arg;
- Close(rd->fd);
- free(rd->dbuf);
- free(rd);
-}
-
-static int interrupted = 0;
-
-static void
-notifyf(void*, char *s)
-{
- int i;
-
- for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
- if(strncmp(s, "sys: ", 5)!=0) interrupted = 1;
- goto Out;
- }
- noted(NDFLT);
- return;
-Out:
- if(strcmp(s, "interrupt")!=0 || trap[i]==0){
- trap[i]++;
- ntrap++;
- }
- noted(NCONT);
-}
-
-void
-Trapinit(void)
-{
- notify(notifyf);
-}
-
-long
-Write(int fd, void *buf, long cnt)
-{
- return write(fd, buf, cnt);
-}
-
-long
-Read(int fd, void *buf, long cnt)
-{
- return read(fd, buf, cnt);
-}
-
-long
-Seek(int fd, long cnt, long whence)
-{
- return seek(fd, cnt, whence);
-}
-
-int
-Executable(char *file)
-{
- Dir *statbuf;
- int ret;
-
- statbuf = dirstat(file);
- if(statbuf == nil)
- return 0;
- ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
- free(statbuf);
- return ret;
-}
-
-int
-Open(char *file, int mode)
-{
- static int tab[] = {OREAD,OWRITE,ORDWR,OREAD|ORCLOSE};
- return open(file, tab[mode&3]);
-}
-
-void
-Close(int fd)
-{
- close(fd);
-}
-
-int
-Creat(char *file)
-{
- return create(file, OWRITE, 0666L);
-}
-
-int
-Dup(int a, int b)
-{
- return dup(a, b);
-}
-
-int
-Dup1(int a)
-{
- return dup(a, -1);
-}
-
-void
-Exit(void)
-{
- Updenv();
- exits(truestatus()?"":getstatus());
-}
-
-int
-Eintr(void)
-{
- return interrupted;
-}
-
-void
-Noerror(void)
-{
- interrupted = 0;
-}
-
-int
-Isatty(int fd)
-{
- char buf[64];
-
- if(fd2path(fd, buf, sizeof buf) != 0)
- return 0;
- /* might be /mnt/term/dev/cons */
- return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0;
-}
-
-void
-Abort(void)
-{
- abort();
-}
-
-static int newwdir;
-
-int
-Chdir(char *dir)
-{
- newwdir = 1;
- return chdir(dir);
-}
-
-void
-Prompt(char *s)
-{
- pstr(err, s);
- flushio(err);
-
- if(newwdir){
- char dir[4096];
- int fd;
- if((fd=Creat("/dev/wdir"))>=0){
- getwd(dir, sizeof(dir));
- Write(fd, dir, strlen(dir));
- Close(fd);
- }
- newwdir = 0;
- }
-}
--- a/librc/rc.h
+++ /dev/null
@@ -1,166 +1,0 @@
-/*
- * Plan9 is defined for plan 9
- * otherwise its UNIX.
- * Please don't litter the code with ifdefs. The three below (and one in
- * getflags) should be enough.
- */
-#ifdef Plan9
-#include <u.h>
-#include <libc.h>
-#define NSIG 32
-#define SIGINT 2
-#define SIGQUIT 3
-#else
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#ifndef NSIG
-#define NSIG 32
-#endif
-#endif
-
-#define YYMAXDEPTH 500
-#ifndef PAREN
-#include "y.tab.h"
-#endif
-typedef struct tree tree;
-typedef struct word word;
-typedef struct io io;
-typedef union code code;
-typedef struct var var;
-typedef struct list list;
-typedef struct lexer lexer;
-typedef struct redir redir;
-typedef struct thread thread;
-typedef struct builtin builtin;
-
-#pragma incomplete word
-#pragma incomplete io
-
-struct tree{
- int type;
- int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */
- int line;
- char glob; /* 0=string, 1=glob, 2=pattern see globprop() and noglobs() */
- char quoted;
- char iskw;
- char *str;
- tree *child[3];
- tree *next;
-};
-tree *newtree(void);
-tree *token(char*, int), *klook(char*), *tree1(int, tree*);
-tree *tree2(int, tree*, tree*), *tree3(int, tree*, tree*, tree*);
-tree *mung1(tree*, tree*), *mung2(tree*, tree*, tree*);
-tree *mung3(tree*, tree*, tree*, tree*), *epimung(tree*, tree*);
-tree *simplemung(tree*);
-tree *globprop(tree*);
-char *fnstr(tree*);
-
-/*
- * The first word of any code vector is a reference count
- * and the second word is a string for srcfile().
- * Code starts at pc 2. The last code word must be a zero
- * terminator for codefree().
- * Always create a new reference to a code vector by calling codecopy(.).
- * Always call codefree(.) when deleting a reference.
- */
-union code{
- void (*f)(void);
- int i;
- char *s;
-};
-
-#define NTOK 8192
-
-struct lexer{
- io *input;
- char *file;
- int line;
-
- char *prolog;
- char *epilog;
-
- int peekc;
- int future;
- int lastc;
-
- char eof;
- char inquote;
- char incomm;
- char lastword; /* was the last token read a word or compound word terminator? */
- char lastdol; /* was the last token read '$' or '$#' or '"'? */
- char iflast; /* static `if not' checking */
-
- char qflag;
-
- char tok[NTOK];
-};
-extern lexer *lex; /* current lexer */
-lexer *newlexer(io*, char*);
-void freelexer(lexer*);
-
-#define APPEND 1
-#define WRITE 2
-#define READ 3
-#define HERE 4
-#define DUPFD 5
-#define CLOSE 6
-#define RDWR 7
-
-struct var{
- var *next; /* next on hash or local list */
- word *val; /* value */
- code *fn; /* pointer to function's code vector */
- int pc; /* pc of start of function */
- char fnchanged;
- char changed;
- char name[];
-};
-var *vlook(char*), *gvlook(char*), *newvar(char*, var*);
-void setvar(char*, word*), freevar(var*);
-
-#define NVAR 521
-extern var *gvar[NVAR]; /* hash for globals */
-
-#define new(type) ((type *)emalloc(sizeof(type)))
-
-void *emalloc(long);
-void *erealloc(void *, long);
-char *estrdup(char*);
-
-/*
- * Glob character escape in strings:
- * In a string, GLOB must be followed by *?[ or GLOB.
- * GLOB* matches any string
- * GLOB? matches any single character
- * GLOB[...] matches anything in the brackets
- * GLOBGLOB matches GLOB
- */
-#define GLOB ((char)0x01)
-/*
- * Is c the first character of a utf sequence?
- */
-#define onebyte(c) (((c)&0x80)==0x00)
-#define twobyte(c) (((c)&0xe0)==0xc0)
-#define threebyte(c) (((c)&0xf0)==0xe0)
-#define fourbyte(c) (((c)&0xf8)==0xf0)
-#define xbyte(c) (((c)&0xc0)==0x80)
-
-extern char *argv0;
-extern int nerror; /* number of errors encountered during compilation */
-extern int doprompt; /* is it time for a prompt? */
-extern io *err;
-
-/*
- * Which fds are the reading/writing end of a pipe?
- * Unfortunately, this can vary from system to system.
- * 9th edition Unix doesn't care, the following defines
- * work on plan 9.
- */
-#define PRD 0
-#define PWR 1
-extern char Rcmain[], Fdprefix[];
-extern char *Signame[];
--- /dev/null
+++ b/librc/rcmain.drawcpu
@@ -1,0 +1,38 @@
+# rcmain: drawcpu version
+if(~ $#home 0) home=$HOME
+if(~ $#ifs 0) ifs='
+'
+profile=$home/.rcrc
+switch($#prompt){
+case 0
+ prompt=('% ' ' ')
+case 1
+ prompt=($prompt ' ')
+}
+if(~ $rcname ?.out) prompt=('broken! ' ' ')
+if(flag p) path=/bin
+if not {
+ finit
+ if(~ $#path 0) path=(. /bin /usr/bin /usr/local/bin)
+}
+fn sigexit
+if(! ~ $#cflag 0){
+ if(flag l) {
+ . -q $profile
+ }
+ status=''
+ eval $cflag
+}
+if not if(flag i){
+ if(flag l) {
+ . -q $profile
+ }
+ status=''
+ if(! ~ $#* 0) . $*
+ . -i /dev/fd/0
+}
+if not if(~ $#* 0) . /dev/fd/0
+if not{
+ status=''
+ . $*
+}
--- a/librc/rcmain.plan9
+++ /dev/null
@@ -1,41 +1,0 @@
-# rcmain: Plan 9 version
-if(~ $#home 0) home=/
-if(~ $#ifs 0) ifs='
-'
-switch($#prompt){
-case 0
- prompt=('% ' ' ')
-case 1
- prompt=($prompt ' ')
-}
-if(~ $rcname ?.out) prompt=('broken! ' ' ')
-if(flag p) path=/bin
-if not{
- for(i in '/env/fn#'*){
- . -bq $i
- }
- if(~ $#path 0) path=(/bin .)
-}
-fn sigexit
-if(! ~ $#cflag 0){
- if(flag l){
- . -q /rc/lib/rcmain.local
- . -q $home/lib/profile
- }
- status=''
- eval $cflag
-}
-if not if(flag i){
- if(flag l){
- . -q /rc/lib/rcmain.local
- . -q $home/lib/profile
- }
- status=''
- if(! ~ $#* 0) . $*
- . -i '#d/0'
-}
-if not if(~ $#* 0) . '#d/0'
-if not{
- status=''
- . $*
-}
--- a/librc/rcmain.unix
+++ /dev/null
@@ -1,38 +1,0 @@
-# rcmain: unix version
-if(~ $#home 0) home=$HOME
-if(~ $#ifs 0) ifs='
-'
-profile=$home/.rcrc
-switch($#prompt){
-case 0
- prompt=('% ' ' ')
-case 1
- prompt=($prompt ' ')
-}
-if(~ $rcname ?.out) prompt=('broken! ' ' ')
-if(flag p) path=/bin
-if not {
- finit
- if(~ $#path 0) path=(. /bin /usr/bin /usr/local/bin)
-}
-fn sigexit
-if(! ~ $#cflag 0){
- if(flag l) {
- . -q $profile
- }
- status=''
- eval $cflag
-}
-if not if(flag i){
- if(flag l) {
- . -q $profile
- }
- status=''
- if(! ~ $#* 0) . $*
- . -i /dev/fd/0
-}
-if not if(~ $#* 0) . /dev/fd/0
-if not{
- status=''
- . $*
-}
--- a/librc/simple.c
+++ b/librc/simple.c
@@ -1,7 +1,10 @@
/*
* Maybe `simple' is a misnomer.
*/
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
+#include <errno.h>
#include "getflags.h"
#include "exec.h"
#include "io.h"
@@ -94,7 +97,7 @@
}
else{
if((pid = execforkexec()) < 0){
- Xerror2("try again", Errstr());
+ Xerror2("try again", strerror(errno));
return;
}
poplist();
@@ -114,15 +117,15 @@
switch(rp->type){
case ROPEN:
if(rp->from!=rp->to){
- Dup(rp->from, rp->to);
- Close(rp->from);
+ dup2(rp->from, rp->to);
+ close(rp->from);
}
break;
case RDUP:
- Dup(rp->from, rp->to);
+ dup2(rp->from, rp->to);
break;
case RCLOSE:
- Close(rp->from);
+ close(rp->from);
break;
}
}
@@ -144,7 +147,7 @@
}
char*
-makepath(char *dir, char *file)
+rcmakepath(char *dir, char *file)
{
char *path;
int m, n = strlen(dir);
@@ -184,10 +187,11 @@
Updenv();
doredir(runq->redir);
for(path = searchpath(argv[1], "path"); path; path = path->next){
- argv[0] = makepath(path->word, argv[1]);
- Exec(argv);
+ argv[0] = rcmakepath(path->word, argv[1]);
+ // TODO: execve + env from our fs
+ execv(argv[0], argv+1);
}
- setstatus(Errstr());
+ setstatus(strerror(errno));
pfln(err, srcfile(runq), runq->line);
pfmt(err, ": %s: %s\n", argv[1], getstatus());
Xexit();
@@ -215,8 +219,8 @@
case 2:
a = a->next;
for(cdpath = searchpath(a->word, "cdpath"); cdpath; cdpath = cdpath->next){
- dir = makepath(cdpath->word, a->word);
- if(Chdir(dir)>=0){
+ dir = rcmakepath(cdpath->word, a->word);
+ if(chdir(dir)>=0){
if(cdpath->word[0] != '\0' && strcmp(cdpath->word, ".") != 0)
pfmt(err, "%s\n", dir);
free(dir);
@@ -226,15 +230,15 @@
free(dir);
}
if(cdpath==0)
- pfmt(err, "Can't cd %s: %s\n", a->word, Errstr());
+ pfmt(err, "Can't cd %s: %s\n", a->word, strerror(errno));
break;
case 1:
a = vlook("home")->val;
if(a){
- if(Chdir(a->word)>=0)
+ if(chdir(a->word)>=0)
setstatus("");
else
- pfmt(err, "Can't cd %s: %s\n", a->word, Errstr());
+ pfmt(err, "Can't cd %s: %s\n", a->word, strerror(errno));
}
else
pfmt(err, "Can't cd -- $home empty\n");
@@ -394,20 +398,15 @@
file = 0;
fd = -1;
for(path = searchpath(argv->word, "path"); path; path = path->next){
- file = makepath(path->word, argv->word);
- fd = Open(file, 0);
+ file = rcmakepath(path->word, argv->word);
+ fd = open(file, 0);
if(fd >= 0)
break;
- if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */
- fd = Dup1(0);
- if(fd>=0)
- break;
- }
free(file);
}
if(fd<0){
if(!qflag)
- Xerror3(". can't open", argv->word, Errstr());
+ Xerror3(". can't open", argv->word, strerror(errno));
freewords(argv);
return;
}
@@ -501,7 +500,7 @@
pfmt(out, "builtin %s\n", a->word);
else {
for(path = searchpath(a->word, "path"); path; path = path->next){
- file = makepath(path->word, a->word);
+ file = rcmakepath(path->word, a->word);
if(Executable(file)){
pfmt(out, "%s\n", file);
free(file);
--- a/librc/subr.c
+++ b/librc/subr.c
@@ -1,4 +1,6 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
#include "io.h"
#include "fns.h"
@@ -20,15 +22,6 @@
return p;
}
-char*
-estrdup(char *s)
-{
- int n = strlen(s)+1;
- char *d = emalloc(n);
- memmove(d, s, n);
- return d;
-}
-
void
pfln(io *fd, char *file, int line)
{
@@ -60,15 +53,4 @@
bp = s;
iacvt(n);
*bp='\0';
-}
-
-void
-panic(char *s, int n)
-{
- pfmt(err, "%s: ", argv0);
- pfmt(err, s, n);
- pchr(err, '\n');
- flushio(err);
-
- Abort();
}
--- /dev/null
+++ b/librc/syn.y
@@ -1,0 +1,92 @@
+%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN
+%term WORD REDIR DUP PIPE SUB
+%term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
+/* operator priorities -- lowest first */
+%left IF WHILE FOR SWITCH ')' NOT
+%left ANDAND OROR
+%left BANG SUBSHELL
+%left PIPE
+%left '^'
+%right '$' COUNT '"'
+%left SUB
+%{
+#include <rc.h>
+#include "fns.h"
+%}
+%union{
+ struct tree *tree;
+};
+%type<tree> line paren brace body cmdsa cmdsan assign epilog redir
+%type<tree> cmd simple first word comword keyword words
+%type<tree> NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN
+%type<tree> WORD REDIR DUP PIPE
+%%
+rc: { return 1;}
+| line '\n' {readhere(lex->input); return !compile($1);}
+line: cmd
+| cmdsa line {$$=tree2(';', $1, $2);}
+body: cmd
+| cmdsan body {$$=tree2(';', $1, $2);}
+cmdsa: cmd ';'
+| cmd '&' {$$=tree1('&', $1);}
+cmdsan: cmdsa
+| cmd '\n' {readhere(lex->input);}
+brace: '{' body '}' {$$=tree1(BRACE, $2);}
+paren: '(' body ')' {$$=tree1(PCMD, $2);}
+assign: first '=' word {$$=tree2('=', $1, $3);}
+epilog: {$$=0;}
+| redir epilog {$$=mung2($1, $1->child[0], $2);}
+redir: REDIR word {$$=mung1($1, $2); if($$->rtype==HERE) heredoc($$);}
+| DUP
+cmd: {$$=0;}
+| brace epilog {$$=epimung($1, $2);}
+| IF paren {skipnl();} cmd
+ {$$=mung2($1, $2, $4);}
+| IF NOT {skipnl();} cmd {$$=mung1($2, $4);}
+| FOR '(' word IN words ')' {skipnl();} cmd
+ /*
+ * if ``words'' is nil, we need a tree element to distinguish between
+ * for(i in ) and for(i), the former being a loop over the empty set
+ * and the latter being the implicit argument loop. so if $5 is nil
+ * (the empty set), we represent it as "()". don't parenthesize non-nil
+ * functions, to avoid growing parentheses every time we reread the
+ * definition.
+ */
+ {$$=mung3($1, $3, $5 ? $5 : tree1(PAREN, $5), $8);}
+| FOR '(' word ')' {skipnl();} cmd
+ {$$=mung3($1, $3, (tree*)0, $6);}
+| WHILE paren {skipnl();} cmd
+ {$$=mung2($1, $2, $4);}
+| SWITCH word {skipnl();} brace
+ {$$=tree2(SWITCH, $2, $4);}
+| simple {$$=simplemung($1);}
+| TWIDDLE word words {$$=mung2($1, $2, $3);}
+| cmd ANDAND cmd {$$=tree2(ANDAND, $1, $3);}
+| cmd OROR cmd {$$=tree2(OROR, $1, $3);}
+| cmd PIPE cmd {$$=mung2($2, $1, $3);}
+| redir cmd %prec BANG {$$=mung2($1, $1->child[0], $2);}
+| assign cmd %prec BANG {$$=mung3($1, $1->child[0], $1->child[1], $2);}
+| BANG cmd {$$=mung1($1, $2);}
+| SUBSHELL cmd {$$=mung1($1, $2);}
+| FN words brace {$$=tree2(FN, $2, $3);}
+| FN words {$$=tree1(FN, $2);}
+simple: first
+| simple word {$$=globprop(tree2(ARGLIST, $1, $2));}
+| simple redir {$$=globprop(tree2(ARGLIST, $1, $2));}
+first: comword
+| first '^' word {$$=globprop(tree2('^', $1, $3));}
+word: keyword {lex->lastword=1; $1->type=WORD;}
+| comword
+| word '^' word {$$=globprop(tree2('^', $1, $3));}
+comword: '$' word {$$=tree1('$', $2);}
+| '$' word SUB words ')' {$$=tree2(SUB, $2, $4);}
+| '"' word {$$=tree1('"', $2);}
+| COUNT word {$$=tree1(COUNT, $2);}
+| WORD
+| '`' brace {$$=tree2('`', (tree*)0, $2);}
+| '`' word brace {$$=tree2('`', $2, $3);}
+| '(' words ')' {$$=globprop(tree1(PAREN, $2));}
+| REDIR brace {$$=mung1($1, $2); $$->type=PIPEFD;}
+keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN
+words: {$$=(tree*)0;}
+| words word {$$=tree2(WORDS, $1, $2);}
--- a/librc/trap.c
+++ b/librc/trap.c
@@ -1,7 +1,8 @@
-#include "rc.h"
+#include <rc.h>
#include "exec.h"
#include "fns.h"
#include "io.h"
+#include "y.tab.h"
int ntrap;
int trap[NSIG];
@@ -16,7 +17,7 @@
while(ntrap) for(i = 0;i<NSIG;i++) while(trap[i]){
--trap[i];
--ntrap;
- if(getpid()!=mypid) Exit();
+ if(getpid()!=mypid) _exit(0);
trapreq = vlook(Signame[i]);
if(trapreq->fn)
startfunc(trapreq, copywords(starval, (word*)0), (var*)0, (redir*)0);
@@ -29,6 +30,6 @@
*/
while(!runq->iflag) Xreturn();
}
- else Exit();
+ else _exit(0);
}
}
--- a/librc/tree.c
+++ b/librc/tree.c
@@ -1,7 +1,9 @@
-#include "rc.h"
+#include <u.h>
+#include <libc.h>
+#include <rc.h>
#include "io.h"
#include "fns.h"
-
+#include "y.tab.h"
/*
* create and clear a new tree node, and add it
* to the node list.
--- a/librc/unix.c
+++ /dev/null
@@ -1,420 +1,0 @@
-/*
- * Unix versions of system-specific functions
- * By convention, exported routines herein have names beginning with an
- * upper case letter.
- */
-#include "rc.h"
-#include "exec.h"
-#include "io.h"
-#include "fns.h"
-#include "getflags.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/wait.h>
-
-static void execfinit(void);
-
-builtin Builtin[] = {
- "cd", execcd,
- "whatis", execwhatis,
- "eval", execeval,
- "exec", execexec, /* but with popword first */
- "exit", execexit,
- "shift", execshift,
- "wait", execwait,
- ".", execdot,
- "flag", execflag,
- "finit", execfinit,
- 0
-};
-
-char Rcmain[] = PREFIX "/lib/rcmain";
-char Fdprefix[] = "/dev/fd/";
-
-char *Signame[NSIG];
-
-#define SEP '\1'
-extern char **environ;
-static char **envp;
-
-static void
-Xrdfn(void)
-{
- char *s;
- int len;
-
- for(;*envp;envp++){
- for(s=*envp;*s && *s!='(' && *s!='=';s++);
- switch(*s){
- case '(': /* Bourne again */
- if(strncmp(s, "()fn ", 5)!=0)
- continue;
- s=estrdup(s+2);
- len=strlen(s);
- s[len++]='\n';
- envp++;
- runq->pc--; /* re-execute */
- execcmds(openiocore(s, len), estrdup("*environ*"), runq->local, runq->redir);
- runq->lex->qflag = 1;
- return;
- default:
- continue;
- }
- }
-}
-
-static void
-execfinit(void)
-{
- static union code rdfns[5];
- if(rdfns[0].i==0){
- rdfns[0].i = 1;
- rdfns[1].s = "*rdfns*";
- rdfns[2].f = Xrdfn;
- rdfns[3].f = Xreturn;
- rdfns[4].f = 0;
- }
- poplist();
- envp=environ;
- start(rdfns, 2, runq->local, runq->redir);
-}
-
-static int
-cmpenv(const void *aa, const void *ab)
-{
- return strcmp(*(char**)aa, *(char**)ab);
-}
-
-static char**
-mkenv(void)
-{
- char **env, **ep, *p, *q;
- struct var **h, *v;
- struct word *a;
- int nvar = 0, nchr = 0, sep;
-
- /*
- * Slightly kludgy loops look at locals then globals.
- * locals no longer exist - geoff
- */
- for(h = gvar-1; h != &gvar[NVAR]; h++)
- for(v = h >= gvar? *h: runq->local; v ;v = v->next){
- if((v==vlook(v->name)) && v->val){
- nvar++;
- nchr+=strlen(v->name)+1;
- for(a = v->val;a;a = a->next)
- nchr+=strlen(a->word)+1;
- }
- if(v->fn){
- nvar++;
- nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
- }
- }
- env = (char **)emalloc((nvar+1)*sizeof(char *)+nchr);
- ep = env;
- p = (char *)&env[nvar+1];
- for(h = gvar-1; h != &gvar[NVAR]; h++)
- for(v = h >= gvar? *h: runq->local;v;v = v->next){
- if((v==vlook(v->name)) && v->val){
- *ep++=p;
- q = v->name;
- while(*q) *p++=*q++;
- sep='=';
- for(a = v->val;a;a = a->next){
- *p++=sep;
- sep = SEP;
- q = a->word;
- while(*q) *p++=*q++;
- }
- *p++='\0';
- }
- if(v->fn){
- *ep++=p;
- *p++='#'; *p++='('; *p++=')'; /* to fool Bourne */
- *p++='f'; *p++='n'; *p++=' ';
- q = v->name;
- while(*q) *p++=*q++;
- *p++=' ';
- q = v->fn[v->pc-1].s;
- while(*q) *p++=*q++;
- *p++='\0';
- }
- }
- *ep = 0;
- qsort((void *)env, nvar, sizeof ep[0], cmpenv);
- return env;
-}
-
-static word*
-envval(char *s)
-{
- char *t, c;
- word *v;
- for(t=s;*t&&*t!=SEP;t++);
- c=*t;
- *t='\0';
- v=newword(s, c=='\0'?(word*)0:envval(t+1));
- *t=c;
- return v;
-}
-
-void
-Vinit(void)
-{
- char *s;
-
- for(envp=environ;*envp;envp++){
- for(s=*envp;*s && *s!='(' && *s!='=';s++);
- switch(*s){
- case '=':
- *s='\0';
- setvar(*envp, envval(s+1));
- *s='=';
- break;
- default: continue;
- }
- }
-}
-
-static void
-sighandler(int sig)
-{
- trap[sig]++;
- ntrap++;
-}
-
-void
-Trapinit(void)
-{
- int i;
-
- Signame[0] = "sigexit";
-
-#ifdef SIGINT
- Signame[SIGINT] = "sigint";
-#endif
-#ifdef SIGTERM
- Signame[SIGTERM] = "sigterm";
-#endif
-#ifdef SIGHUP
- Signame[SIGHUP] = "sighup";
-#endif
-#ifdef SIGQUIT
- Signame[SIGQUIT] = "sigquit";
-#endif
-#ifdef SIGPIPE
- Signame[SIGPIPE] = "sigpipe";
-#endif
-#ifdef SIGUSR1
- Signame[SIGUSR1] = "sigusr1";
-#endif
-#ifdef SIGUSR2
- Signame[SIGUSR2] = "sigusr2";
-#endif
-#ifdef SIGBUS
- Signame[SIGBUS] = "sigbus";
-#endif
-#ifdef SIGWINCH
- Signame[SIGWINCH] = "sigwinch";
-#endif
-
- for(i=1; i<NSIG; i++) if(Signame[i]){
-#ifdef SA_RESTART
- struct sigaction a;
-
- sigaction(i, NULL, &a);
- a.sa_flags &= ~SA_RESTART;
- a.sa_handler = sighandler;
- sigaction(i, &a, NULL);
-#else
- signal(i, sighandler);
-#endif
- }
-}
-
-char*
-Errstr(void)
-{
- return strerror(errno);
-}
-
-int
-Waitfor(int pid)
-{
- thread *p;
- char num[12];
- int wpid, status;
-
- if(pid >= 0 && !havewaitpid(pid))
- return 0;
- while((wpid = wait(&status))!=-1){
- delwaitpid(wpid);
- inttoascii(num, WIFSIGNALED(status)?WTERMSIG(status)+1000:WEXITSTATUS(status));
- if(wpid==pid){
- setstatus(num);
- return 0;
- }
- for(p = runq->ret;p;p = p->ret)
- if(p->pid==wpid){
- p->pid=-1;
- p->status = estrdup(num);
- break;
- }
- }
- if(Eintr()) return -1;
- return 0;
-}
-
-static char **nextenv;
-
-void
-Updenv(void)
-{
- if(nextenv){
- free(nextenv);
- nextenv = NULL;
- }
- if(err)
- flushio(err);
-}
-
-void
-Exec(char **argv)
-{
- if(nextenv==NULL) nextenv=mkenv();
- execve(argv[0], argv+1, nextenv);
-}
-
-int
-Fork(void)
-{
- Updenv();
- return fork();
-}
-
-void*
-Opendir(char *name)
-{
- return opendir(name);
-}
-
-char*
-Readdir(void *arg, int onlydirs)
-{
- DIR *rd = arg;
- struct dirent *ent = readdir(rd);
- if(ent == NULL)
- return 0;
- return ent->d_name;
-}
-
-void
-Closedir(void *arg)
-{
- DIR *rd = arg;
- closedir(rd);
-}
-
-long
-Write(int fd, void *buf, long cnt)
-{
- return write(fd, buf, cnt);
-}
-
-long
-Read(int fd, void *buf, long cnt)
-{
- return read(fd, buf, cnt);
-}
-
-long
-Seek(int fd, long cnt, long whence)
-{
- return lseek(fd, cnt, whence);
-}
-
-int
-Executable(char *file)
-{
- return access(file, 01)==0;
-}
-
-int
-Open(char *file, int mode)
-{
- static int tab[] = {O_RDONLY,O_WRONLY,O_RDWR,O_RDONLY};
- int fd = open(file, tab[mode&3]);
- if(fd >= 0 && mode == 3)
- unlink(file);
- return fd;
-}
-
-void
-Close(int fd)
-{
- close(fd);
-}
-
-int
-Creat(char *file)
-{
- return creat(file, 0666L);
-}
-
-int
-Dup(int a, int b)
-{
- return dup2(a, b);
-}
-
-int
-Dup1(int a)
-{
- return dup(a);
-}
-
-void
-Exit(void)
-{
- Updenv();
- exit(truestatus()?0:1);
-}
-
-int
-Eintr(void)
-{
- return errno==EINTR;
-}
-
-void
-Noerror(void)
-{
- errno=0;
-}
-
-int
-Isatty(int fd)
-{
- return isatty(fd);
-}
-
-void
-Abort(void)
-{
- abort();
-}
-
-int
-Chdir(char *dir)
-{
- return chdir(dir);
-}
-
-void
-Prompt(char *s)
-{
- pstr(err, s);
- flushio(err);
-}
--- a/librc/var.c
+++ b/librc/var.c
@@ -1,6 +1,7 @@
-#include "rc.h"
+#include <rc.h>
#include "exec.h"
#include "fns.h"
+#include "y.tab.h"
var *gvar[NVAR];
--- a/librc/y.tab.c
+++ b/librc/y.tab.c
@@ -126,7 +126,7 @@
/* Copy the first part of user declarations. */
#line 12 "syn.y"
-#include "rc.h"
+#include <rc.h>
#include "fns.h"
--- a/libsec/x509.c
+++ b/libsec/x509.c
@@ -168,19 +168,6 @@
return p;
}
-static char*
-estrdup(char *s)
-{
- char *d;
- int n;
-
- n = strlen(s)+1;
- d = emalloc(n);
- memmove(d, s, n);
- return d;
-}
-
-
/*
* Decode a[0..len] as a BER encoding of an ASN1 type.
* The return value is one of ASN_OK, etc.
--- a/main.c
+++ b/main.c
@@ -9,6 +9,7 @@
char *argv0;
char *authserver = "";
+char *dbgfile = "./debug.log";
void
sizebug(void)
@@ -72,7 +73,9 @@
bind("#N", "/dev", MAFTER);
bind("#C", "/", MAFTER);
+ /* TODO: flag for debug */
fd = open("/dev/cons", ORDWR);
+ dbg = open(dbgfile, OWRITE);
if(session(fd) < 0)
fprint(dbg, "session failed: %r\n");
close(fd);
--- a/session.c
+++ b/session.c
@@ -1,10 +1,6 @@
#include <u.h>
#include <libc.h>
-#include <auth.h>
-#include <fcall.h>
-#include <authsrv.h>
-#include <libsec.h>
-#include "drawcpu.h"
+#include <rc.h>
// TODO: aanserver
static void
@@ -18,13 +14,14 @@
int
session(int fd)
{
- int n;
char buf[1024];
- //while (1) {
- n = read(fd, buf, sizeof buf);
-
- //}
- //return rcmain(buf, fd);
- // sed out any line that says 'service=cpu' and put 'service=unix'
+ read(fd, buf, sizeof buf);
+ char *cmd[] = {
+ "rc",
+ "-c",
+ buf
+ };
+
+ runscript(fd, 1, cmd);
return -1;
}