tall: DragonFly port. Fix compilation problems, libdraw still doesn't work right yet. - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
commit 20035ed43cfd67cddd01969e155794e1e057d9e6
parent db800afb4e7b46df67feba70cda683f34110619b
Author: Shenghou Ma 
Date:   Thu, 27 Feb 2014 23:17:47 -0500

all: DragonFly port.
Fix compilation problems, libdraw still doesn't work right yet.

LGTM=rsc
R=rsc
https://codereview.appspot.com/67820046

Diffstat:
  M INSTALL                             |       6 ++++++
  M bin/9c                              |       2 +-
  M bin/9l                              |       2 +-
  M src/cmd/9660srv/main.c              |       2 +-
  A src/cmd/9term/DragonFly.c           |       1 +
  M src/cmd/9term/mkfile                |       2 +-
  A src/cmd/auxstats/DragonFly.c        |      10 ++++++++++
  M src/cmd/eqn/lex.c                   |       6 +++---
  M src/cmd/tpic/input.c                |       2 --
  A src/cmd/vbackup/mount-DragonFly.c   |       1 +
  M src/lib9/dirread.c                  |      16 +++++++++++-----
  A src/libip/DragonFly.c               |       1 +
  M src/libip/mkfile                    |       2 +-
  A src/libmach/DragonFly.c             |     318 +++++++++++++++++++++++++++++++

14 files changed, 356 insertions(+), 15 deletions(-)
---
diff --git a/INSTALL b/INSTALL
t@@ -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
diff --git a/bin/9c b/bin/9c
t@@ -77,7 +77,7 @@ tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}-${CC9:-cc}"
 case "$tag" in
 *FreeBSD*gcc*)        usegcc ;;
 *FreeBSD*clang*)        useclang ;;
-*BSD*)        usegcc ;;
+*DragonFly*|*BSD*)        usegcc ;;
 *Darwin-x86_64*clang*)
                 useclang
                 cflags="$ngflags -g3 -m64"
diff --git a/bin/9l b/bin/9l
t@@ -24,7 +24,7 @@ case "$tag" in
                 ;;
         esac
         ;;
-*BSD*)
+*DragonFly*|*BSD*)
         ld=${CC9:-gcc}
         userpath=true
         extralibs="$extralibs -lutil"
diff --git a/src/cmd/9660srv/main.c b/src/cmd/9660srv/main.c
t@@ -2,6 +2,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dat.h"
 #include "fns.h"
 
t@@ -38,7 +39,6 @@ Fcall *rep;
 uchar mdata[Maxiosize];
 char fdata[Maxfdata];
 uchar statbuf[STATMAX];
-int errno;
 
 
 extern Xfsub        *xsublist[];
diff --git a/src/cmd/9term/DragonFly.c b/src/cmd/9term/DragonFly.c
t@@ -0,0 +1 @@
+#include "bsdpty.c"
diff --git a/src/cmd/9term/mkfile b/src/cmd/9term/mkfile
t@@ -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
 
diff --git a/src/cmd/auxstats/DragonFly.c b/src/cmd/auxstats/DragonFly.c
t@@ -0,0 +1,10 @@
+#include 
+#include 
+#include 
+#include "dat.h"
+
+void (*statfn[])(int) = 
+{
+        0
+};
+
diff --git a/src/cmd/eqn/lex.c b/src/cmd/eqn/lex.c
t@@ -1,6 +1,7 @@
 #include "e.h"
 #include "y.tab.h"
 #include 
+#include 
 
 #define        SSIZE        1000
 char        token[SSIZE];
t@@ -19,7 +20,7 @@ yylex(void)
         register int c;
         tbl *tp;
 
-  begin:
+begin:
         while ((c = input()) == ' ' || c == '\n' || c == '\t')
                 ;
         yylval = c;
t@@ -236,7 +237,6 @@ void include(void)
         char name[100];
         FILE *fin;
         int c;
-        extern int errno;
 
         while ((c = input()) == ' ')
                 ;
t@@ -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';
diff --git a/src/cmd/tpic/input.c b/src/cmd/tpic/input.c
t@@ -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;
diff --git a/src/cmd/vbackup/mount-DragonFly.c b/src/cmd/vbackup/mount-DragonFly.c
t@@ -0,0 +1 @@
+#include "mount-BSD.c"
diff --git a/src/lib9/dirread.c b/src/lib9/dirread.c
t@@ -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)
 {
t@@ -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)
 {
t@@ -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;
 }
t@@ -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);
t@@ -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);
diff --git a/src/libip/DragonFly.c b/src/libip/DragonFly.c
t@@ -0,0 +1 @@
+#include "BSD.c"
diff --git a/src/libip/mkfile b/src/libip/mkfile
t@@ -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
diff --git a/src/libmach/DragonFly.c b/src/libmach/DragonFly.c
t@@ -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;
+}