URI: 
       tall: DragonFly port. Fix compilation problems, libdraw still doesn't work right yet. - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 20035ed43cfd67cddd01969e155794e1e057d9e6
   DIR parent db800afb4e7b46df67feba70cda683f34110619b
  HTML Author: Shenghou Ma <minux.ma@gmail.com>
       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(-)
       ---
   DIR 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
   DIR 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"
   DIR 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"
   DIR diff --git a/src/cmd/9660srv/main.c b/src/cmd/9660srv/main.c
       t@@ -2,6 +2,7 @@
        #include <libc.h>
        #include <auth.h>
        #include <fcall.h>
       +#include <errno.h>
        #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[];
   DIR diff --git a/src/cmd/9term/DragonFly.c b/src/cmd/9term/DragonFly.c
       t@@ -0,0 +1 @@
       +#include "bsdpty.c"
   DIR 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
        
   DIR diff --git a/src/cmd/auxstats/DragonFly.c b/src/cmd/auxstats/DragonFly.c
       t@@ -0,0 +1,10 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include "dat.h"
       +
       +void (*statfn[])(int) = 
       +{
       +        0
       +};
       +
   DIR 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 <ctype.h>
       +#include <errno.h>
        
        #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';
   DIR 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;
   DIR diff --git a/src/cmd/vbackup/mount-DragonFly.c b/src/cmd/vbackup/mount-DragonFly.c
       t@@ -0,0 +1 @@
       +#include "mount-BSD.c"
   DIR 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);
   DIR diff --git a/src/libip/DragonFly.c b/src/libip/DragonFly.c
       t@@ -0,0 +1 @@
       +#include "BSD.c"
   DIR 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
   DIR 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 <u.h>
       +#include <sys/ptrace.h>
       +#include <sys/types.h>
       +#include <sys/wait.h>
       +#include <machine/reg.h>
       +#include <signal.h>
       +#include <errno.h>
       +#include <libc.h>
       +#include <mach.h>
       +#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; i<map->nseg; i++)
       +                while(i<map->nseg && 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; i<n; i+=4){
       +                if(isr){
       +                        errno = 0;
       +                        u = ptrace(PT_READ_D, seg->pid, (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; i<nelem(freebsdregs); i++)
       +                if(strcmp(freebsdregs[i], reg) == 0)
       +                        return 4*i;
       +        return ~(ulong)0;
       +}
       +
       +static int
       +ptraceregrw(Regs *regs, char *name, ulong *val, int isr)
       +{
       +        int pid;
       +        ulong addr;
       +        struct reg mregs;
       +
       +        addr = reg2freebsd(name);
       +        if(~addr == 0){
       +                if(isr){
       +                        *val = ~(ulong)0;
       +                        return 0;
       +                }
       +                werrstr("register not available");
       +                return -1;
       +        }
       +
       +        pid = ((PtraceRegs*)regs)->pid;
       +        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;
       +}