mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
all: DragonFly port.
Fix compilation problems, libdraw still doesn't work right yet. LGTM=rsc R=rsc https://codereview.appspot.com/67820046
This commit is contained in:
parent
db800afb4e
commit
20035ed43c
14 changed files with 356 additions and 15 deletions
6
INSTALL
6
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
|
||||
|
|
2
bin/9c
2
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"
|
||||
|
|
2
bin/9l
2
bin/9l
|
@ -24,7 +24,7 @@ case "$tag" in
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
*BSD*)
|
||||
*DragonFly*|*BSD*)
|
||||
ld=${CC9:-gcc}
|
||||
userpath=true
|
||||
extralibs="$extralibs -lutil"
|
||||
|
|
|
@ -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[];
|
||||
|
|
1
src/cmd/9term/DragonFly.c
Normal file
1
src/cmd/9term/DragonFly.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "bsdpty.c"
|
|
@ -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
|
||||
|
||||
|
|
10
src/cmd/auxstats/DragonFly.c
Normal file
10
src/cmd/auxstats/DragonFly.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include "dat.h"
|
||||
|
||||
void (*statfn[])(int) =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
1
src/cmd/vbackup/mount-DragonFly.c
Normal file
1
src/cmd/vbackup/mount-DragonFly.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "mount-BSD.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);
|
||||
|
|
1
src/libip/DragonFly.c
Normal file
1
src/libip/DragonFly.c
Normal file
|
@ -0,0 +1 @@
|
|||
#include "BSD.c"
|
|
@ -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
|
||||
|
|
318
src/libmach/DragonFly.c
Normal file
318
src/libmach/DragonFly.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue