acme: split win into winfs and rc script, get rid of lib9p leavefdsopen hack

split the acme win command into a winfs fileserver which
handles /dev/cons emulation and a rc script responsible
for launching the command.

with these changes, the fd fiddling is not neccesary anymore
and we can get rid of the leavefdsopen hack.
This commit is contained in:
cinap_lenrek 2020-03-07 20:06:55 +01:00
parent 022087cdcd
commit e1cdcfdb17
7 changed files with 57 additions and 127 deletions

View file

@ -65,7 +65,6 @@ extern void winclean(Window*);
extern int winselect(Window*, char*, int); extern int winselect(Window*, char*, int);
extern int winsetaddr(Window*, char*, int); extern int winsetaddr(Window*, char*, int);
extern void windormant(Window*); extern void windormant(Window*);
extern void winsetdump(Window*, char*, char*);
extern void winsetdir(Window*, char*, char*); extern void winsetdir(Window*, char*, char*);
extern void ctlprint(int, char*, ...); extern void ctlprint(int, char*, ...);
@ -80,7 +79,7 @@ extern void startpipe(void);
extern void sendit(char*); extern void sendit(char*);
extern void execevent(Window *w, Event *e, int (*)(Window*, char*)); extern void execevent(Window *w, Event *e, int (*)(Window*, char*));
extern void mountcons(void); extern void mountcons(void*);
extern void fsloop(void*); extern void fsloop(void*);
extern int newpipewin(int, char*); extern int newpipewin(int, char*);

View file

@ -163,17 +163,24 @@ fsdestroyfid(Fid *fid)
free(fid->aux); free(fid->aux);
} }
void
fsstart(Srv *srv)
{
proccreate(fsloop, srv->aux, STACK);
}
Srv fs = { Srv fs = {
.read= fsread, .read= fsread,
.write= fswrite, .write= fswrite,
.flush= fsflush, .flush= fsflush,
.destroyfid= fsdestroyfid, .destroyfid= fsdestroyfid,
.leavefdsopen= 1, .start = fsstart,
}; };
void void
mountcons(void) mountcons(void *arg)
{ {
fs.aux = arg;
fschan = chancreate(sizeof(Fsevent), 0); fschan = chancreate(sizeof(Fsevent), 0);
writechan = chancreate(sizeof(void*), 0); writechan = chancreate(sizeof(void*), 0);
fs.tree = alloctree("win", "win", DMDIR|0555, nil); fs.tree = alloctree("win", "win", DMDIR|0555, nil);

View file

@ -8,33 +8,29 @@
#include "dat.h" #include "dat.h"
void mainctl(void*); void mainctl(void*);
void startcmd(char *[], int*);
void stdout2body(void*);
int debug; int debug;
int notepg;
int eraseinput; int eraseinput;
int notepg = -1;
int dirty = 0; int dirty = 0;
char *wname;
char *wdir; char *wdir;
char *wname;
Window *win; /* the main window */ Window *win; /* the main window */
void void
usage(void) usage(void)
{ {
fprint(2, "usage: win [command]\n"); fprint(2, "usage: %s [-Dde] [windowname]\n", argv0);
threadexitsall("usage"); threadexitsall("usage");
} }
void void
threadmain(int argc, char *argv[]) threadmain(int argc, char *argv[])
{ {
int i, j; char buf[1024], *s;
char buf[1024], **av;
quotefmtinstall(); quotefmtinstall();
rfork(RFNAMEG);
ARGBEGIN{ ARGBEGIN{
case 'd': case 'd':
debug = 1; debug = 1;
@ -49,44 +45,39 @@ threadmain(int argc, char *argv[])
} }
}ARGEND }ARGEND
if(argc == 0){ if(argc == 0)
av = emalloc(3*sizeof(char*)); wname = argv0;
av[0] = "rc";
av[1] = "-i";
}else{
av = argv;
}
wname = utfrrune(av[0], '/');
if(wname)
wname++;
else else
wname = av[0]; wname = argv[0];
s = utfrrune(wname, '/');
if(s != nil)
wname = s+1;
if(getwd(buf, sizeof buf) == 0) if(getwd(buf, sizeof buf) == 0)
wdir = "/"; wdir = "/";
else else
wdir = buf; wdir = buf;
wdir = estrdup(wdir); wdir = estrdup(wdir);
win = newwindow(); win = newwindow();
snprint(buf, sizeof buf, "%d", win->id);
putenv("winid", buf);
winsetdir(win, wdir, wname); winsetdir(win, wdir, wname);
wintagwrite(win, "Send Noscroll", 5+8); wintagwrite(win, "Send Noscroll", 5+8);
threadcreate(mainctl, win, STACK);
mountcons();
threadcreate(fsloop, nil, STACK);
startpipe();
startcmd(av, &notepg);
strcpy(buf, "win");
j = 3;
for(i=0; i<argc && j+1+strlen(argv[i])+1<sizeof buf; i++){
strcpy(buf+j, " ");
strcpy(buf+j+1, argv[i]);
j += 1+strlen(argv[i]);
}
ctlprint(win->ctl, "scroll"); ctlprint(win->ctl, "scroll");
winsetdump(win, wdir, buf);
snprint(buf, sizeof(buf), "/proc/%d/notepg", getpid());
notepg = open(buf, OWRITE);
mountcons(win);
snprint(buf, sizeof buf, "%d", win->id);
putenv("winid", buf);
snprint(buf, sizeof(buf), "/mnt/wsys/%d", win->id);
bind(buf, "/dev/acme", MREPL);
bind("/dev/acme/body", "/dev/text", MREPL);
threadexits(nil);
} }
int int
@ -231,7 +222,7 @@ _sendinput(Window *w, ulong q0, ulong *q1)
if(!n || !eraseinput) if(!n || !eraseinput)
return n; return n;
/* erase q0 to q0+n */ /* erase q0 to q0+n */
sprint(buf, "#%lud,#%lud", q0, q0+n); snprint(buf, sizeof(buf), "#%lud,#%lud", q0, q0+n);
winsetaddr(w, buf, 0); winsetaddr(w, buf, 0);
write(w->data, buf, 0); write(w->data, buf, 0);
*q1 -= n; *q1 -= n;
@ -254,10 +245,14 @@ sendinput(Window *w, ulong q0, ulong *q1)
Event esendinput; Event esendinput;
void void
fsloop(void*) fsloop(void *arg)
{ {
Fsevent e; Fsevent e;
Req **l, *r; Req **l, *r;
Window *w = arg; /* the main window */
threadcreate(mainctl, w, STACK);
startpipe();
eq = &q; eq = &q;
memset(&esendinput, 0, sizeof esendinput); memset(&esendinput, 0, sizeof esendinput);
@ -568,77 +563,3 @@ mainctl(void *v)
} }
} }
} }
enum
{
NARGS = 100,
NARGCHAR = 8*1024,
EXECSTACK = STACK+(NARGS+1)*sizeof(char*)+NARGCHAR
};
struct Exec
{
char **argv;
Channel *cpid;
};
int
lookinbin(char *s)
{
if(s[0] == '/')
return 0;
if(s[0]=='.' && s[1]=='/')
return 0;
if(s[0]=='.' && s[1]=='.' && s[2]=='/')
return 0;
return 1;
}
/* adapted from mail. not entirely free of details from that environment */
void
execproc(void *v)
{
struct Exec *e;
char *cmd, **av;
Channel *cpid;
e = v;
rfork(RFCFDG|RFNOTEG);
av = e->argv;
close(0);
open("/dev/cons", OREAD);
close(1);
open("/dev/cons", OWRITE);
dup(1, 2);
cpid = e->cpid;
free(e);
procexec(cpid, av[0], av);
if(lookinbin(av[0])){
cmd = estrstrdup("/bin/", av[0]);
procexec(cpid, cmd, av);
}
error("can't exec %s: %r", av[0]);
}
void
startcmd(char *argv[], int *notepg)
{
struct Exec *e;
Channel *cpid;
char buf[64];
int pid;
e = emalloc(sizeof(struct Exec));
e->argv = argv;
cpid = chancreate(sizeof(ulong), 0);
e->cpid = cpid;
sprint(buf, "/mnt/wsys/%d", win->id);
bind(buf, "/dev/acme", MREPL);
bind("/dev/acme/body", "/dev/text", MREPL);
proccreate(execproc, e, EXECSTACK);
do
pid = recvul(cpid);
while(pid == -1);
sprint(buf, "/proc/%d/notepg", pid);
*notepg = open(buf, OWRITE);
}

View file

@ -1,6 +1,6 @@
</$objtype/mkfile </$objtype/mkfile
TARG=win TARG=winfs
OFILES=\ OFILES=\
fs.$O\ fs.$O\
main.$O\ main.$O\

View file

@ -17,7 +17,7 @@ void pipectl(void*);
int pipefd; int pipefd;
Wpid *wpid; Wpid *wpid;
int snarffd; int snarffd = -1;
Channel *newpipechan; Channel *newpipechan;
int int
@ -70,7 +70,7 @@ pipecommand(Window *w, char *s)
if(q0 == q1){ if(q0 == q1){
t = nil; t = nil;
k = 0; k = 0;
if(snarffd > 0){ if(snarffd >= 0){
seek(0, snarffd, 0); seek(0, snarffd, 0);
for(;;){ for(;;){
t = realloc(t, k+8192+2); t = realloc(t, k+8192+2);

View file

@ -24,15 +24,6 @@ newwindow(void)
return w; return w;
} }
void
winsetdump(Window *w, char *dir, char *cmd)
{
if(dir != nil)
ctlprint(w->ctl, "dumpdir %s\n", dir);
if(cmd != nil)
ctlprint(w->ctl, "dump %s\n", cmd);
}
void void
winsetdir(Window *w, char *dir, char *name) winsetdir(Window *w, char *dir, char *name)
{ {

12
acme/bin/win Executable file
View file

@ -0,0 +1,12 @@
#!/bin/rc
if(~ $#* 0){
*=(rc -i)
}
/acme/bin/$cputype/winfs $1 >/dev/null >[2=1] || {
# compat
exec /acme/bin/$cputype/win $*
exit
}
echo dump $* > /dev/acme/ctl
</dev/cons >/dev/cons >[2=1] $*
exit ''