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:
parent
022087cdcd
commit
e1cdcfdb17
7 changed files with 57 additions and 127 deletions
|
@ -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*);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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, ¬epg);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
</$objtype/mkfile
|
</$objtype/mkfile
|
||||||
|
|
||||||
TARG=win
|
TARG=winfs
|
||||||
OFILES=\
|
OFILES=\
|
||||||
fs.$O\
|
fs.$O\
|
||||||
main.$O\
|
main.$O\
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
12
acme/bin/win
Executable 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 ''
|
Loading…
Reference in a new issue