| #include "sam.h" |
| |
| Rune samname[] = L"~~sam~~"; |
| |
| Rune *left[]= { |
| L"{[(<«", |
| L"\n", |
| L"'\"`", |
| 0 |
| }; |
| Rune *right[]= { |
| L"}])>»", |
| L"\n", |
| L"'\"`", |
| 0 |
| }; |
| |
| char RSAM[] = "sam"; |
| char SAMTERM[] = "/bin/aux/samterm"; |
| char HOME[] = "HOME"; |
| char TMPDIR[] = "/tmp"; |
| char SH[] = "rc"; |
| char SHPATH[] = "/bin/rc"; |
| char RX[] = "rx"; |
| char RXPATH[] = "/bin/rx"; |
| char SAMSAVECMD[] = "/bin/rc\n/sys/lib/samsave"; |
| |
| void |
| dprint(char *z, ...) |
| { |
| char buf[BLOCKSIZE]; |
| va_list arg; |
| |
| va_start(arg, z); |
| vseprint(buf, &buf[BLOCKSIZE], z, arg); |
| va_end(arg); |
| termwrite(buf); |
| } |
| |
| void |
| print_ss(char *s, String *a, String *b) |
| { |
| dprint("?warning: %s: `%.*S' and `%.*S'\n", s, a->n, a->s, b->n, b->s); |
| } |
| |
| void |
| print_s(char *s, String *a) |
| { |
| dprint("?warning: %s `%.*S'\n", s, a->n, a->s); |
| } |
| |
| char* |
| getuser(void) |
| { |
| static char user[64]; |
| int fd; |
| |
| if(user[0] == 0){ |
| fd = open("/dev/user", 0); |
| if(fd<0 || read(fd, user, sizeof user-1)<=0) |
| strcpy(user, "none"); |
| close(fd); |
| } |
| return user; |
| } |
| |
| int |
| statfile(char *name, ulong *dev, uvlong *id, long *time, long *length, long *appendonly) |
| { |
| Dir *dirb; |
| |
| dirb = dirstat(name); |
| if(dirb == nil) |
| return -1; |
| if(dev) |
| *dev = dirb->type|(dirb->dev<<16); |
| if(id) |
| *id = dirb->qid.path; |
| if(time) |
| *time = dirb->mtime; |
| if(length) |
| *length = dirb->length; |
| if(appendonly) |
| *appendonly = dirb->mode & DMAPPEND; |
| free(dirb); |
| return 1; |
| } |
| |
| int |
| statfd(int fd, ulong *dev, uvlong *id, long *time, long *length, long *appendonly) |
| { |
| Dir *dirb; |
| |
| dirb = dirfstat(fd); |
| if(dirb == nil) |
| return -1; |
| if(dev) |
| *dev = dirb->type|(dirb->dev<<16); |
| if(id) |
| *id = dirb->qid.path; |
| if(time) |
| *time = dirb->mtime; |
| if(length) |
| *length = dirb->length; |
| if(appendonly) |
| *appendonly = dirb->mode & DMAPPEND; |
| free(dirb); |
| return 1; |
| } |
| |
| void |
| notifyf(void *a, char *s) |
| { |
| USED(a); |
| if(bpipeok && strcmp(s, "sys: write on closed pipe") == 0) |
| noted(NCONT); |
| if(strcmp(s, "interrupt") == 0) |
| noted(NCONT); |
| panicking = 1; |
| rescue(); |
| noted(NDFLT); |
| } |
| |
| int |
| newtmp(int num) |
| { |
| int i, fd; |
| static char tempnam[30]; |
| |
| i = getpid(); |
| do |
| snprint(tempnam, sizeof tempnam, "%s/%d%.4s%dsam", TMPDIR, num, getuser(), i++); |
| while(access(tempnam, 0) == 0); |
| fd = create(tempnam, ORDWR|OCEXEC|ORCLOSE, 0000); |
| if(fd < 0){ |
| remove(tempnam); |
| fd = create(tempnam, ORDWR|OCEXEC|ORCLOSE, 0000); |
| } |
| return fd; |
| } |
| |
| int |
| waitfor(int pid) |
| { |
| int msg; |
| Waitmsg *w; |
| |
| while((w = wait()) != nil){ |
| if(w->pid != pid){ |
| free(w); |
| continue; |
| } |
| msg = (w->msg[0] != '\0'); |
| free(w); |
| return msg; |
| } |
| return -1; |
| } |
| |
| void |
| samerr(char *buf) |
| { |
| sprint(buf, "%s/sam.err", TMPDIR); |
| } |
| |
| void* |
| emalloc(ulong n) |
| { |
| void *p; |
| |
| p = malloc(n); |
| if(p == 0) |
| panic("malloc fails"); |
| memset(p, 0, n); |
| return p; |
| } |
| |
| void* |
| erealloc(void *p, ulong n) |
| { |
| p = realloc(p, n); |
| if(p == 0) |
| panic("realloc fails"); |
| return p; |
| } |