aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShenghou Ma <minux.ma@gmail.com>2014-02-27 23:17:47 -0500
committerShenghou Ma <minux.ma@gmail.com>2014-02-27 23:17:47 -0500
commit20035ed43cfd67cddd01969e155794e1e057d9e6 (patch)
treeb8d840938e7f506f433ff6abc0b816e0b7cf3206
parentdb800afb4e7b46df67feba70cda683f34110619b (diff)
downloadplan9port-20035ed43cfd67cddd01969e155794e1e057d9e6.tar.gz
plan9port-20035ed43cfd67cddd01969e155794e1e057d9e6.tar.bz2
plan9port-20035ed43cfd67cddd01969e155794e1e057d9e6.zip
all: DragonFly port.
Fix compilation problems, libdraw still doesn't work right yet. LGTM=rsc R=rsc https://codereview.appspot.com/67820046
-rwxr-xr-xINSTALL6
-rwxr-xr-xbin/9c2
-rwxr-xr-xbin/9l2
-rw-r--r--src/cmd/9660srv/main.c2
-rw-r--r--src/cmd/9term/DragonFly.c1
-rw-r--r--src/cmd/9term/mkfile2
-rw-r--r--src/cmd/auxstats/DragonFly.c10
-rw-r--r--src/cmd/eqn/lex.c6
-rw-r--r--src/cmd/tpic/input.c2
-rw-r--r--src/cmd/vbackup/mount-DragonFly.c1
-rw-r--r--src/lib9/dirread.c16
-rw-r--r--src/libip/DragonFly.c1
-rw-r--r--src/libip/mkfile2
-rw-r--r--src/libmach/DragonFly.c318
14 files changed, 356 insertions, 15 deletions
diff --git a/INSTALL b/INSTALL
index 9c5592e1..f8b8587e 100755
--- a/INSTALL
+++ b/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
diff --git a/bin/9c b/bin/9c
index 78ce552f..85aa0822 100755
--- a/bin/9c
+++ b/bin/9c
@@ -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
index 011da243..d07bd892 100755
--- a/bin/9l
+++ b/bin/9l
@@ -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
index cd20570c..44fdc512 100644
--- a/src/cmd/9660srv/main.c
+++ b/src/cmd/9660srv/main.c
@@ -2,6 +2,7 @@
#include <libc.h>
#include <auth.h>
#include <fcall.h>
+#include <errno.h>
#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[];
diff --git a/src/cmd/9term/DragonFly.c b/src/cmd/9term/DragonFly.c
new file mode 100644
index 00000000..eec79c28
--- /dev/null
+++ b/src/cmd/9term/DragonFly.c
@@ -0,0 +1 @@
+#include "bsdpty.c"
diff --git a/src/cmd/9term/mkfile b/src/cmd/9term/mkfile
index e1ef4d68..4546d666 100644
--- a/src/cmd/9term/mkfile
+++ b/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
diff --git a/src/cmd/auxstats/DragonFly.c b/src/cmd/auxstats/DragonFly.c
new file mode 100644
index 00000000..ec931044
--- /dev/null
+++ b/src/cmd/auxstats/DragonFly.c
@@ -0,0 +1,10 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "dat.h"
+
+void (*statfn[])(int) =
+{
+ 0
+};
+
diff --git a/src/cmd/eqn/lex.c b/src/cmd/eqn/lex.c
index 99a716bb..2eddb6d5 100644
--- a/src/cmd/eqn/lex.c
+++ b/src/cmd/eqn/lex.c
@@ -1,6 +1,7 @@
#include "e.h"
#include "y.tab.h"
#include <ctype.h>
+#include <errno.h>
#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';
diff --git a/src/cmd/tpic/input.c b/src/cmd/tpic/input.c
index a5928ece..6885f650 100644
--- a/src/cmd/tpic/input.c
+++ b/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;
diff --git a/src/cmd/vbackup/mount-DragonFly.c b/src/cmd/vbackup/mount-DragonFly.c
new file mode 100644
index 00000000..0379cee8
--- /dev/null
+++ b/src/cmd/vbackup/mount-DragonFly.c
@@ -0,0 +1 @@
+#include "mount-BSD.c"
diff --git a/src/lib9/dirread.c b/src/lib9/dirread.c
index 0e38db3e..f977d15d 100644
--- a/src/lib9/dirread.c
+++ b/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);
diff --git a/src/libip/DragonFly.c b/src/libip/DragonFly.c
new file mode 100644
index 00000000..8710a5fd
--- /dev/null
+++ b/src/libip/DragonFly.c
@@ -0,0 +1 @@
+#include "BSD.c"
diff --git a/src/libip/mkfile b/src/libip/mkfile
index d0099289..88b0fd99 100644
--- a/src/libip/mkfile
+++ b/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
diff --git a/src/libmach/DragonFly.c b/src/libmach/DragonFly.c
new file mode 100644
index 00000000..92ffdb92
--- /dev/null
+++ b/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 <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;
+}