M gnot/chan.c => gnot/chan.c +4 -0
@@ 511,6 511,8 @@ namec(char *name, int amode, int omode, ulong perm)
c = nc;
Open:
c = (*devtab[c->type].open)(c, omode);
+ if(omode & OCEXEC)
+ c->flag |= CCEXEC;
break;
case Amount:
@@ 533,6 535,8 @@ namec(char *name, int amode, int omode, ulong perm)
if((c->flag&(CMOUNT|CCREATE)) == CMOUNT)
c = createdir(c);
(*devtab[c->type].create)(c, elem, omode, perm);
+ if(omode & OCEXEC)
+ c->flag |= CCEXEC;
break;
default:
M gnot/dat.h => gnot/dat.h +1 -0
@@ 491,6 491,7 @@ extern char *statename[];
#define COPEN 1 /* for i/o */
#define CMOUNT 2 /* is result of a mount/bind */
#define CCREATE 4 /* permits creation if CMOUNT */
+#define CCEXEC 8 /* close on exec */
/*
* Proc.time
M gnot/fns.h => gnot/fns.h +1 -0
@@ 42,6 42,7 @@ void envpgclose(Env *);
void error(Chan*, int);
void exit(void);
void fault(Ureg*, FFrame*);
+void fdclose(int);
Chan* fdtochan(int, int);
void firmware(void);
void flowctl(Queue*);
M gnot/l.s => gnot/l.s +11 -0
@@ 104,6 104,17 @@ TEXT tas(SB), $0
tas_1:
RTS
+TEXT rfnote(SB), $0
+
+ MOVL uregpp+0(FP), A0
+ MOVL (A0), A7
+ MOVL A7, -(A7)
+ MOVL ((1+8+8)*BY2WD)(A7), A0
+ MOVL A0, USP
+ MOVL ((1+8+6)*BY2WD)(A7), A6
+ ADDL $((1+8+8+1)*4), A7
+ RTE
+
TEXT illegal(SB), $0
SUBL $((8+8+1)*BY2WD), A7
M gnot/lib.h => gnot/lib.h +2 -0
@@ 71,6 71,8 @@ extern long end;
#define ORDWR 2 /* read and write */
#define OEXEC 3 /* execute, == read but check execute permission */
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
+#define OCEXEC 32 /* or'ed in, close on exec */
+#define ORCLOSE 64 /* or'ed in, remove on close */
typedef struct Error Error;
typedef struct Dir Dir;
M gnot/sysfile.c => gnot/sysfile.c +2 -2
@@ 44,10 44,10 @@ fdtochan(int fd, int mode)
int
openmode(ulong o)
{
- if(o >= (OTRUNC|OEXEC))
+ if(o >= (OTRUNC|OCEXEC|ORCLOSE|OEXEC))
Err:
error(0, Ebadarg);
- o &= ~OTRUNC;
+ o &= ~(OTRUNC|OCEXEC|ORCLOSE);
if(o > OEXEC)
goto Err;
if(o == OEXEC)
M gnot/sysproc.c => gnot/sysproc.c +10 -1
@@ 157,7 157,7 @@ sysexec(ulong *arg)
Seg *s;
ulong l, t, d, b, v;
int i;
- Chan *tc;
+ Chan *tc, *c;
Orig *o;
char **argv, **argp;
char *a, *charp, *file;
@@ 289,6 289,15 @@ sysexec(ulong *arg)
freesegs(ESEG);
/*
+ * Close on exec
+ */
+ for(i=0; i<=u->maxfd; i++)
+ if((c=u->fd[i]) && c->flag&CCEXEC){
+ close(c);
+ fdclose(i);
+ }
+
+ /*
* Text. Shared.
*/
s = &p->seg[TSEG];
M gnot/trap.c => gnot/trap.c +5 -9
@@ 156,8 156,7 @@ notify(Ureg *ur)
if(!u->notified){
if(!u->notify)
goto Die;
- #ifdef asdfasdf
- sp = ur->sp;
+ sp = ur->usp;
sp -= sizeof(Ureg);
u->ureg = (void*)sp;
memcpy((Ureg*)sp, ur, sizeof(Ureg));
@@ 167,13 166,11 @@ notify(Ureg *ur)
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */
*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* */
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
- ur->sp = sp;
+ ur->usp = sp;
ur->pc = (ulong)u->notify;
u->notified = 1;
u->nnote--;
memcpy(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
- #endif
- panic("notify");
}
unlock(&u->p->debug);
}
@@ 184,7 181,6 @@ notify(Ureg *ur)
void
noted(Ureg **urp)
{
- #ifdef asdfasdf
lock(&u->p->debug);
if(!u->notified){
unlock(&u->p->debug);
@@ 195,8 191,6 @@ noted(Ureg **urp)
unlock(&u->p->debug);
splhi();
rfnote(urp);
- #endif
- panic("noted");
}
#undef CHDIR /* BUG */
@@ 206,7 200,7 @@ typedef long Syscall(ulong*);
Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, syslasterr, syswait;
Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate, sysuserstr;
-Syscall sysbrk_, sysremove, syswstat, sysfwstat;
+Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted;
Syscall *systab[]={
sysr1,
@@ 237,6 231,8 @@ Syscall *systab[]={
sysremove,
syswstat,
sysfwstat,
+ sysnotify,
+ sysnoted,
};
long
M port/chan.c => port/chan.c +5 -1
@@ 447,7 447,7 @@ namec(char *name, int amode, int omode, ulong perm)
mntok = 0;
if(!((ulong)name & KZERO))
validaddr((ulong)(name+1), 2, 0);
- if(name[1]=='|' || ('A'<=name[1] && name[1]<='Z'))
+ if(name[1]=='|' || name[1]=='M')
error(0, Enonexist);
t = devno(name[1], 1);
if(t == -1)
@@ 511,6 511,8 @@ namec(char *name, int amode, int omode, ulong perm)
c = nc;
Open:
c = (*devtab[c->type].open)(c, omode);
+ if(omode & OCEXEC)
+ c->flag |= CCEXEC;
break;
case Amount:
@@ 533,6 535,8 @@ namec(char *name, int amode, int omode, ulong perm)
if((c->flag&(CMOUNT|CCREATE)) == CMOUNT)
c = createdir(c);
(*devtab[c->type].create)(c, elem, omode, perm);
+ if(omode & OCEXEC)
+ c->flag |= CCEXEC;
break;
default:
M port/lib.h => port/lib.h +2 -0
@@ 71,6 71,8 @@ extern long end;
#define ORDWR 2 /* read and write */
#define OEXEC 3 /* execute, == read but check execute permission */
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
+#define OCEXEC 32 /* or'ed in, close on exec */
+#define ORCLOSE 64 /* or'ed in, remove on close */
typedef struct Error Error;
typedef struct Dir Dir;
M port/sysfile.c => port/sysfile.c +2 -2
@@ 44,10 44,10 @@ fdtochan(int fd, int mode)
int
openmode(ulong o)
{
- if(o >= (OTRUNC|OEXEC))
+ if(o >= (OTRUNC|OCEXEC|ORCLOSE|OEXEC))
Err:
error(0, Ebadarg);
- o &= ~OTRUNC;
+ o &= ~(OTRUNC|OCEXEC|ORCLOSE);
if(o > OEXEC)
goto Err;
if(o == OEXEC)
M port/sysproc.c => port/sysproc.c +10 -1
@@ 157,7 157,7 @@ sysexec(ulong *arg)
Seg *s;
ulong l, t, d, b, v;
int i;
- Chan *tc;
+ Chan *tc, *c;
Orig *o;
char **argv, **argp;
char *a, *charp, *file;
@@ 289,6 289,15 @@ sysexec(ulong *arg)
freesegs(ESEG);
/*
+ * Close on exec
+ */
+ for(i=0; i<=u->maxfd; i++)
+ if((c=u->fd[i]) && c->flag&CCEXEC){
+ close(c);
+ fdclose(i);
+ }
+
+ /*
* Text. Shared.
*/
s = &p->seg[TSEG];
M power/dat.h => power/dat.h +1 -0
@@ 634,6 634,7 @@ extern char *statename[];
#define COPEN 1 /* for i/o */
#define CMOUNT 2 /* is result of a mount/bind */
#define CCREATE 4 /* permits creation if CMOUNT */
+#define CCEXEC 8 /* close on exec */
/*
* Proc.time
M power/devhs.c => power/devhs.c +0 -5
@@ 485,10 485,6 @@ hsvmekproc(void *arg)
}
/*
- * if we loop many times without finding a character, sleep
- */
- for(miss = 0; miss < 10; miss++){
- /*
* 0xFFFF means an empty fifo
*/
while ((c = addr->data) != 0xFFFF) {
@@ 517,7 513,6 @@ hsvmekproc(void *arg)
upstream(hp, 0);
}
}
- }
qunlock(hp);
/*
M power/fns.h => power/fns.h +1 -0
@@ 53,6 53,7 @@ void error(Chan*, int);
void evenaddr(ulong);
void exit(void);
void fault(Ureg*, int, int);
+void fdclose(int);
Chan* fdtochan(int, int);
void firmware(void);
void flowctl(Queue*);
M power/trap.c => power/trap.c +2 -2
@@ 342,7 342,7 @@ notify(Ureg *ur)
if(!u->notified){
if(!u->notify)
goto Die;
- sp = ur->sp;
+ sp = ur->usp;
sp -= sizeof(Ureg);
u->ureg = (void*)sp;
memcpy((Ureg*)sp, ur, sizeof(Ureg));
@@ 352,7 352,7 @@ notify(Ureg *ur)
*(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */
*(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* */
*(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */
- ur->sp = sp;
+ ur->usp = sp;
ur->pc = (ulong)u->notify;
u->notified = 1;
u->nnote--;