commit 20035ed43cfd67cddd01969e155794e1e057d9e6 from: Shenghou Ma date: Fri Feb 28 04:17:47 2014 UTC all: DragonFly port. Fix compilation problems, libdraw still doesn't work right yet. LGTM=rsc R=rsc https://codereview.appspot.com/67820046 commit - db800afb4e7b46df67feba70cda683f34110619b commit + 20035ed43cfd67cddd01969e155794e1e057d9e6 blob - 9c5592e11ebcedac12db488550cfd0bb0c10edb4 blob + f8b8587edbb9f9949be4da8f02e39f6abd2df2a4 --- INSTALL +++ INSTALL @@ -50,6 +50,12 @@ if [ `uname` = FreeBSD ]; then echo "LDFLAGS='-L/usr/local/lib'" >> $PLAN9/config fi +if [ `uname` = DragonFly ]; then + echo "* Running on DragonFly BSD, adjusting linker flags" + echo "LDFLAGS='-L/usr/local/lib -pthread'" >> $PLAN9/config + echo "CFLAGS='-pthread'" >> $PLAN9/config +fi + if [ `uname` = OpenBSD ]; then echo "* Running on OpenBSD, adjusting linker flags" echo "LDFLAGS='-L/usr/X11R6/lib -pthread'" >> $PLAN9/config blob - 78ce552f9ac92bb8e0fd89be2041be1c44a17a6a blob + 85aa0822a45f0dbe36abe6a8079606a262fb03b2 --- bin/9c +++ bin/9c @@ -77,7 +77,7 @@ tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}-${CC9: case "$tag" in *FreeBSD*gcc*) usegcc ;; *FreeBSD*clang*) useclang ;; -*BSD*) usegcc ;; +*DragonFly*|*BSD*) usegcc ;; *Darwin-x86_64*clang*) useclang cflags="$ngflags -g3 -m64" blob - 011da24398892e982fb672bc8194917f61ff11f5 blob + d07bd89292a5643d61d30f584c3c59ac99f6ed4f --- bin/9l +++ bin/9l @@ -24,7 +24,7 @@ case "$tag" in ;; esac ;; -*BSD*) +*DragonFly*|*BSD*) ld=${CC9:-gcc} userpath=true extralibs="$extralibs -lutil" blob - cd20570ce1a3ed2bdb1858e0c09fb82514a373de blob + 44fdc5124c09996755f9d75d15955d01abc629e5 --- src/cmd/9660srv/main.c +++ src/cmd/9660srv/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "dat.h" #include "fns.h" @@ -38,7 +39,6 @@ Fcall *rep; uchar mdata[Maxiosize]; char fdata[Maxfdata]; uchar statbuf[STATMAX]; -int errno; extern Xfsub *xsublist[]; blob - /dev/null blob + eec79c286b4360f3f20ac5f3478d7b949e150ddf (mode 644) --- /dev/null +++ src/cmd/9term/DragonFly.c @@ -0,0 +1 @@ +#include "bsdpty.c" blob - e1ef4d680593f83d84b10ee5a74944af39eb6748 blob + 4546d666e53045dbce884f0d58ca51dbf1f74f0e --- src/cmd/9term/mkfile +++ src/cmd/9term/mkfile @@ -10,7 +10,7 @@ HFILES=dat.h fns.h term.h <$PLAN9/src/mkmany -Darwin.$O Linux.$O FreeBSD.$O: bsdpty.c +Darwin.$O Linux.$O FreeBSD.$O DragonFly.$O: bsdpty.c $O.9term: data.$O scrl.$O time.$O util.$O wind.$O blob - /dev/null blob + ec9310447017e5215754d96967872b6d5a70f59b (mode 644) --- /dev/null +++ src/cmd/auxstats/DragonFly.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include "dat.h" + +void (*statfn[])(int) = +{ + 0 +}; + blob - 99a716bb36aec572cd430688e3f5b9d67350bc10 blob + 2eddb6d573314fbfd8a732461877702fbc902dfa --- src/cmd/eqn/lex.c +++ src/cmd/eqn/lex.c @@ -1,6 +1,7 @@ #include "e.h" #include "y.tab.h" #include +#include #define SSIZE 1000 char token[SSIZE]; @@ -19,7 +20,7 @@ yylex(void) register int c; tbl *tp; - begin: +begin: while ((c = input()) == ' ' || c == '\n' || c == '\t') ; yylval = c; @@ -236,7 +237,6 @@ void include(void) char name[100]; FILE *fin; int c; - extern int errno; while ((c = input()) == ' ') ; @@ -260,7 +260,7 @@ void delim(void) ERROR "Bizarre delimiters" FATAL; lefteq = token[0]; righteq = token[1]; - if (!isprint(lefteq) || !isprint(righteq)) + if (!isprint(lefteq) || !isprint(righteq)) ERROR "Bizarre delimiters" FATAL; if (lefteq == 'o' && righteq == 'f') lefteq = righteq = '\0'; blob - a5928ecedf65f7bbc112f95e9ca7619ff9b186a7 blob + 6885f650353df04c4e51d2a0e6b9f1bcd7992733 --- src/cmd/tpic/input.c +++ src/cmd/tpic/input.c @@ -428,8 +428,6 @@ pbstr(char *s) double errcheck(double x, char *s) { - extern int errno; - if (errno == EDOM) { errno = 0; ERROR "%s argument out of domain", s WARNING; blob - /dev/null blob + 0379cee8ed3b76815026163bc0a8bef9af345ba3 (mode 644) --- /dev/null +++ src/cmd/vbackup/mount-DragonFly.c @@ -0,0 +1 @@ +#include "mount-BSD.c" blob - 0e38db3e889fceb58682d54e283c44754c36ae96 blob + f977d15dc0ebbfd40a9b2c4c0b919f3b4d51a20b --- src/lib9/dirread.c +++ src/lib9/dirread.c @@ -25,7 +25,7 @@ mygetdents(int fd, struct dirent *buf, int n) long off; return getdirentries(fd, (void*)buf, n, &off); } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) static int mygetdents(int fd, struct dirent *buf, int n) { @@ -46,6 +46,12 @@ mygetdents(int fd, struct dirent *buf, int n) } #endif +#if defined(__DragonFly__) +static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); } +#else +static inline int d_reclen(struct dirent *de) { return de->d_reclen; } +#endif + static int countde(char *p, int n) { @@ -57,14 +63,14 @@ countde(char *p, int n) m = 0; while(p < e){ de = (struct dirent*)p; - if(de->d_reclen <= 4+2+2+1 || p+de->d_reclen > e) + if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e) break; if(de->d_name[0]=='.' && de->d_name[1]==0) de->d_name[0] = 0; else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0) de->d_name[0] = 0; m++; - p += de->d_reclen; + p += d_reclen(de); } return m; } @@ -104,7 +110,7 @@ dirpackage(int fd, char *buf, int n, Dir **dp) stat(de->d_name, &st); nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil); } - p += de->d_reclen; + p += d_reclen(de); } d = malloc(sizeof(Dir)*n+nstr); @@ -126,7 +132,7 @@ dirpackage(int fd, char *buf, int n, Dir **dp) stat(de->d_name, &st); _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr); } - p += de->d_reclen; + p += d_reclen(de); } fchdir(oldwd); blob - /dev/null blob + 8710a5fd530dec2ddbe9ceb3cce3e269fb0329cf (mode 644) --- /dev/null +++ src/libip/DragonFly.c @@ -0,0 +1 @@ +#include "BSD.c" blob - d0099289cb49d6966fd11f9977163b7b1ae3aa91 blob + 88b0fd991832bacd1e6fe61f4a69727c0de94369 --- src/libip/mkfile +++ src/libip/mkfile @@ -20,7 +20,7 @@ HFILES=\ <$PLAN9/src/mksyslib -Darwin.$O FreeBSD.$O: BSD.c +Darwin.$O FreeBSD.$O DragonFly.$O: BSD.c testreadipifc: testreadipifc.o $LIBDIR/$LIB $LD -o testreadipifc testreadipifc.o blob - /dev/null blob + 92ffdb925df0f73e28dde9e8bd735bb191b177e3 (mode 644) --- /dev/null +++ src/libmach/DragonFly.c @@ -0,0 +1,318 @@ +/* + * process interface for DragonFly BSD + * + * we could be a little more careful about not using + * ptrace unless absolutely necessary. this would let us + * look at processes without stopping them. + * + * I'd like to make this a bit more generic (there's too much + * duplication with Linux and presumably other systems), + * but ptrace is too damn system-specific. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ureg386.h" + +Mach *machcpu = &mach386; + +typedef struct PtraceRegs PtraceRegs; +struct PtraceRegs +{ + Regs r; + int pid; +}; + +static int ptracerw(Map*, Seg*, ulong, void*, uint, int); +static int ptraceregrw(Regs*, char*, ulong*, int); + +void +unmapproc(Map *map) +{ + int i; + + if(map == nil) + return; + for(i=0; inseg; i++) + while(inseg && map->seg[i].pid){ + map->nseg--; + memmove(&map->seg[i], &map->seg[i+1], + (map->nseg-i)*sizeof(map->seg[0])); + } +} + +int +mapproc(int pid, Map *map, Regs **rp) +{ + Seg s; + PtraceRegs *r; + + if(ptrace(PT_ATTACH, pid, 0, 0) < 0) + if(ptrace(PT_READ_I, pid, 0, 0)<0 && errno!=EINVAL) + if(ptrace(PT_ATTACH, pid, 0, 0) < 0){ + werrstr("ptrace attach %d: %r", pid); + return -1; + } + + if(ctlproc(pid, "waitanyway") < 0){ + ptrace(PT_DETACH, pid, 0, 0); + return -1; + } + + memset(&s, 0, sizeof s); + s.base = 0; + s.size = 0xFFFFFFFF; + s.offset = 0; + s.name = "data"; + s.file = nil; + s.rw = ptracerw; + s.pid = pid; + if(addseg(map, s) < 0) + return -1; + + if((r = mallocz(sizeof(PtraceRegs), 1)) == nil) + return -1; + r->r.rw = ptraceregrw; + r->pid = pid; + *rp = (Regs*)r; + return 0; +} + +int +detachproc(int pid) +{ + return ptrace(PT_DETACH, pid, 0, 0); +} + +static int +ptracerw(Map *map, Seg *seg, ulong addr, void *v, uint n, int isr) +{ + int i; + u32int u; + uchar buf[4]; + + addr += seg->base; + for(i=0; ipid, (char*)addr+i, 0); + if(errno) + goto ptraceerr; + if(n-i >= 4) + *(u32int*)((char*)v+i) = u; + else{ + *(u32int*)buf = u; + memmove((char*)v+i, buf, n-i); + } + }else{ + if(n-i >= 4) + u = *(u32int*)((char*)v+i); + else{ + errno = 0; + u = ptrace(PT_READ_D, seg->pid, (char*)addr+i, 0); + if(errno) + return -1; + *(u32int*)buf = u; + memmove(buf, (char*)v+i, n-i); + u = *(u32int*)buf; + } + if(ptrace(PT_WRITE_D, seg->pid, (char*)addr+i, u) < 0) + goto ptraceerr; + } + } + return 0; + +ptraceerr: + werrstr("ptrace: %r"); + return -1; +} + +static char *freebsdregs[] = { + "FS", + "ES", + "DS", + "DI", + "SI", + "BP", + "SP", + "BX", + "DX", + "CX", + "AX", + "TRAP", + "PC", + "CS", + "EFLAGS", + "SP", + "SS", + "GS", +}; + +static ulong +reg2freebsd(char *reg) +{ + int i; + + for(i=0; ipid; + if(ptrace(PT_GETREGS, pid, (char*)&mregs, 0) < 0) + return -1; + if(isr) + *val = *(u32int*)((char*)&mregs+addr); + else{ + *(u32int*)((char*)&mregs+addr) = *val; + if(ptrace(PT_SETREGS, pid, (char*)&mregs, 0) < 0) + return -1; + } + return 0; +} + +char* +proctextfile(int pid) +{ + static char buf[1024], pbuf[128]; + + snprint(pbuf, sizeof pbuf, "/proc/%d/file", pid); + if(readlink(pbuf, buf, sizeof buf) >= 0) + return buf; + if(access(pbuf, AEXIST) >= 0) + return pbuf; + return nil; +} + +/* + + status The process status. This file is read-only and returns a single + line containing multiple space-separated fields as follows: + + o command name + o process id + o parent process id + o process group id + o session id + o major,minor of the controlling terminal, or -1,-1 if there is + no controlling terminal. + o a list of process flags: ctty if there is a controlling ter- + minal, sldr if the process is a session leader, noflags if + neither of the other two flags are set. + o the process start time in seconds and microseconds, comma + separated. + o the user time in seconds and microseconds, comma separated. + o the system time in seconds and microseconds, comma separated. + o the wait channel message + o the process credentials consisting of the effective user id + and the list of groups (whose first member is the effective + group id) all comma separated. +*/ + +int +procnotes(int pid, char ***pnotes) +{ + /* figure out the set of pending notes - how? */ + *pnotes = nil; + return 0; +} + +static int +isstopped(int pid) +{ + char buf[1024], *f[12]; + int fd, n, nf; + + snprint(buf, sizeof buf, "/proc/%d/status", pid); + if((fd = open(buf, OREAD)) < 0) + return 0; + n = read(fd, buf, sizeof buf-1); + close(fd); + if(n <= 0) + return 0; + buf[n] = 0; + + if((nf = tokenize(buf, f, nelem(f))) < 11) + return 0; + if(strcmp(f[10], "nochan") == 0) + return 1; + return 0; +} + +#undef waitpid + +int +ctlproc(int pid, char *msg) +{ + int p, status; + + if(strcmp(msg, "hang") == 0){ + if(pid == getpid()) + return ptrace(PT_TRACE_ME, 0, 0, 0); + werrstr("can only hang self"); + return -1; + } + if(strcmp(msg, "kill") == 0) + return ptrace(PT_KILL, pid, 0, 0); + if(strcmp(msg, "startstop") == 0){ + if(ptrace(PT_CONTINUE, pid, 0, 0) < 0) + return -1; + goto waitstop; + } +/* + if(strcmp(msg, "sysstop") == 0){ + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) + return -1; + goto waitstop; + } +*/ + if(strcmp(msg, "stop") == 0){ + if(kill(pid, SIGSTOP) < 0) + return -1; + goto waitstop; + } + if(strcmp(msg, "waitanyway") == 0) + goto waitanyway; + if(strcmp(msg, "waitstop") == 0){ + waitstop: + if(isstopped(pid)) + return 0; + waitanyway: + for(;;){ + p = waitpid(pid, &status, WUNTRACED); + if(p <= 0) + return -1; + if(WIFEXITED(status) || WIFSTOPPED(status)) + return 0; + } + } + if(strcmp(msg, "start") == 0) + return ptrace(PT_CONTINUE, pid, 0, 0); + werrstr("unknown control message '%s'", msg); + return -1; +}