mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
Little tweaks and documentation.
This commit is contained in:
parent
efc2b0c99e
commit
af78a4cd2b
11 changed files with 178 additions and 64 deletions
123
NOTES
123
NOTES
|
@ -1,9 +1,5 @@
|
||||||
This is a port of some Plan 9 libraries and programs to Unix.
|
This is a port of some Plan 9 libraries and programs to Unix.
|
||||||
|
|
||||||
Some parts expect that the tree is installed in /usr/local/plan9.
|
|
||||||
Most are position independent. The few hard-coded references
|
|
||||||
(there's one in sam) should really be fixed.
|
|
||||||
|
|
||||||
* Obtaining the source
|
* Obtaining the source
|
||||||
|
|
||||||
Tarballs will be posted nightly (but only when there are updates!) at
|
Tarballs will be posted nightly (but only when there are updates!) at
|
||||||
|
@ -19,18 +15,125 @@ See below.
|
||||||
|
|
||||||
* Building
|
* Building
|
||||||
|
|
||||||
To build, cd into src and run make; mk install. This will place binaries
|
First, you need to extract the tarball or check out the CVS tree
|
||||||
in "bin". At time of writing, the commands are sam, samterm, rc, and mk.
|
(see below for CVS). You should be able to install the tree anywhere
|
||||||
There are a few shell scripts already included in bin -- B, Bwait,
|
-- tools check the environment variable $PLAN9 for the root of the
|
||||||
and samsave.
|
tree. Most of them assume /usr/local/plan9 if $PLAN9 is not set.
|
||||||
|
|
||||||
The "make" builds mk. Mk builds the rest.
|
To build and install, cd into the plan9/ directory and run "./INSTALL".
|
||||||
|
This will first build "mk" and then use mk to build the rest of the
|
||||||
|
system, installing libraries in plan9/lib/ and binaries in plan9/bin/.
|
||||||
|
There are a few shell scripts already included in bin -- B, Bwait,
|
||||||
|
and samsave. Arguably these directories should be broken up by
|
||||||
|
architecture so that
|
||||||
|
|
||||||
|
* Writing programs
|
||||||
|
|
||||||
|
The bin/ directory contains shell scripts 9a, 9c, 9l, and 9ar that mimic
|
||||||
|
the Plan 9 tools pretty well, except in the object names: "9c x.c" produces
|
||||||
|
x.o not x.9, and "9l x.o" produces "a.out" not "9.out" or "o.out".
|
||||||
|
|
||||||
|
Mkfiles look substantially the same as in Plan 9, with slightly different
|
||||||
|
names for the included rules. The most significant
|
||||||
|
difference is that, since there is no autolinker, the Plan 9 libraries
|
||||||
|
needed must be named explicitly. The variable SHORTLIBS can
|
||||||
|
be used to list them without giving paths, e.g.:
|
||||||
|
|
||||||
|
SHORTLIBS=thread bio 9
|
||||||
|
|
||||||
|
The default is "SHORTLIBS=9". (Libc is known as lib9; libregexp is
|
||||||
|
known as libregexp9; the rest of the libraries retain their usual names.)
|
||||||
|
|
||||||
|
Various function names (like open, accept, dup, malloc) are #defined in
|
||||||
|
order to provide routines that mimic the Plan 9 interface better
|
||||||
|
(for example, open handles the OCEXEC flag). Lib9.h contains these
|
||||||
|
definitions. Function "foo" is #defined to "p9foo". These definitions
|
||||||
|
can cause problems in the rare case that other Unix headers are needed
|
||||||
|
as well. To avoid this, #define NOPLAN9DEFINES before including lib9.h,
|
||||||
|
and then add the p9 prefix yourself for the renamed functions you wish to use.
|
||||||
|
|
||||||
|
* 9P servers and "name spaces"
|
||||||
|
|
||||||
|
A few Plan 9 programs, notably the plumber and acme, are heavily
|
||||||
|
dependent on the use of 9P to interact with other programs. Rather
|
||||||
|
than rewrite them, they have been left alone. Via the helper program 9pserve,
|
||||||
|
they post a Unix domain socket with a well-known name (for example,
|
||||||
|
"acme" or "plumb") in the directory /tmp/ns.$USER.$DISPLAY.
|
||||||
|
Clients connect to that socket and interact via 9P. 9pserve takes
|
||||||
|
care of muxing the various clients of that socket onto a single 9P
|
||||||
|
conversation with the actual server, just like the kernel does on Plan 9.
|
||||||
|
|
||||||
|
The choice of "namespace" directory is meant to provide a different
|
||||||
|
name space for each X11 session a user has. The environment variable
|
||||||
|
$NAMESPACE overrides this. The command "namespace" prints the
|
||||||
|
current name space directory.
|
||||||
|
|
||||||
|
In order to run normal Unix commands with their input or output
|
||||||
|
connected to a 9P server, there is a new 9P request "openfd" whose
|
||||||
|
response contains a real Unix file descriptor. 9pserve handles
|
||||||
|
this request by sending a normal open to the real 9P server and
|
||||||
|
sending back one side of a pipe. Then 9pserver forks a thread to
|
||||||
|
ferry bytes back and forth between its end of the pipe and the 9P
|
||||||
|
conversation. This works reasonably well, but has the drawback
|
||||||
|
that reads are no longer "demand-driven" (the ferry thread issues
|
||||||
|
the reads and fills the pipe regardless of whether the other end
|
||||||
|
of the pipe is being read) and writes cannot return errors (writes
|
||||||
|
to the pipe by the application will always succeed even though the
|
||||||
|
write in the ferry thread might actually draw an interesting error).
|
||||||
|
This doesn't cause too many problems in practice, but is worth
|
||||||
|
keeping in mind.
|
||||||
|
|
||||||
|
The command "9p" interacts with a given server to read or write
|
||||||
|
a particular file. Run "9p" for a usage message.
|
||||||
|
|
||||||
|
* Plumbing
|
||||||
|
|
||||||
|
There is a plumber. It expects to find a plumbing rule file in
|
||||||
|
$HOME/lib/plumbing. $PLAN9/plumb/initial.plumbing is a
|
||||||
|
good start.
|
||||||
|
|
||||||
|
Sam and acme interact with the plumber as they do on Plan 9.
|
||||||
|
(If there is no plumber, sam falls back to a named pipe
|
||||||
|
as it always has on Unix.) Unlike on Plan 9, there is a "web"
|
||||||
|
command whose purpose is to load files or URLs in a running
|
||||||
|
web browser. Right now, only Mozilla Firebird and Opera are
|
||||||
|
supported, but it should be easy to add others to the script.
|
||||||
|
The plumbing rules in $PLAN9/plumb/basic know to run "web"
|
||||||
|
to handle URLs.
|
||||||
|
|
||||||
|
Because sam and acme read from the plumber using file descriptors
|
||||||
|
(and therefore the openfd hack described above), if the editor exits,
|
||||||
|
this fact is not noted until the ferry thread tries to write the next
|
||||||
|
plumbing message to the pipe. At this point the ferry thread closes
|
||||||
|
the corresponding plumber fid, but the plumber thinks the message
|
||||||
|
has been sent -- the message is lost. The message did serve a purpose --
|
||||||
|
now the plumber knows there are no readers of the "edit" channel,
|
||||||
|
so when it gets the next message it will start a new editor.
|
||||||
|
This situation doesn't happen often, but it is worth keeping in mind.
|
||||||
|
|
||||||
|
Both acme and sam try to raise themselves when they get plumbing
|
||||||
|
messages.
|
||||||
|
|
||||||
|
* Acme
|
||||||
|
|
||||||
|
Acme works.
|
||||||
|
|
||||||
|
Programs executed with the middle button interact with acme by the
|
||||||
|
"openfd" trick described above. In a plain execution (as opposed
|
||||||
|
to >prog or |prog), because of the delay introduced by the pipes,
|
||||||
|
there is no guarantee that the command output will finish being
|
||||||
|
displayed before the exit status notice is displayed. This can be
|
||||||
|
annoying.
|
||||||
|
|
||||||
|
There is a "win" shell. Of course, since we're on Unix, win can't
|
||||||
|
tell when programs are reading from the tty, so proper input point
|
||||||
|
management is right out the window.
|
||||||
|
|
||||||
* Helping out
|
* Helping out
|
||||||
|
|
||||||
If you'd like to help out, great!
|
If you'd like to help out, great!
|
||||||
|
|
||||||
The TODO file contains our (somewhat long) to do list.
|
The TODO file contains a small list.
|
||||||
|
|
||||||
If you port this code to other architectures, please share your changes
|
If you port this code to other architectures, please share your changes
|
||||||
so others can benefit. See PORTING for some notes.
|
so others can benefit. See PORTING for some notes.
|
||||||
|
|
18
TODO
18
TODO
|
@ -2,24 +2,6 @@
|
||||||
- bug with discovery of initial window size in certain cases
|
- bug with discovery of initial window size in certain cases
|
||||||
(reported by Sean Dorward)
|
(reported by Sean Dorward)
|
||||||
|
|
||||||
* Plumber
|
|
||||||
- have named-pipe-based plumber from Caerwyn Jones
|
|
||||||
- 9term right-click plumbs
|
|
||||||
- plumb rules file runs B
|
|
||||||
- easy to hook up web browser:
|
|
||||||
|
|
||||||
# urls to web browser
|
|
||||||
type is text
|
|
||||||
data matches '(https?|ftp|file|gopher|mailto|news|nntp|telnet|wais|prospero)://[a-zA-Z0-9_@\-]+([.:][a-zA-Z0-9_@\-]+)*/?[a-zA-Z0-9_?,%#~&/\-+=]+([:.][a-zA-Z0-9_?,%#~&/\-+=]+)*'
|
|
||||||
plumb to web
|
|
||||||
plumb start /usr/rsc/bin/web $0
|
|
||||||
|
|
||||||
- want to change back to 9P-based plumber, need to build
|
|
||||||
infrastructure first
|
|
||||||
|
|
||||||
* Acme
|
|
||||||
- with 9P infrastructure, should "just work".
|
|
||||||
|
|
||||||
* upas/fs+Mail
|
* upas/fs+Mail
|
||||||
- with 9P infrastructure, should "just work".
|
- with 9P infrastructure, should "just work".
|
||||||
|
|
||||||
|
|
35
bin/web
Executable file
35
bin/web
Executable file
|
@ -0,0 +1,35 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
plumb1()
|
||||||
|
{
|
||||||
|
case $BROWSER in
|
||||||
|
# Other browsers here
|
||||||
|
# ...
|
||||||
|
*opera*)
|
||||||
|
$BROWSER -remote 'openURL('$i', new-page)'
|
||||||
|
;;
|
||||||
|
*firebird*)
|
||||||
|
$BROWSER -remote 'openURL('$i', new-window)'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# = 0 ]
|
||||||
|
then
|
||||||
|
plumb1 about:blank
|
||||||
|
else
|
||||||
|
for i
|
||||||
|
do
|
||||||
|
if [ -f "$i" ]
|
||||||
|
then
|
||||||
|
i=file://`pwd`/$i
|
||||||
|
fi
|
||||||
|
plumb1 $i
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $BROWSER in
|
||||||
|
*opera*)
|
||||||
|
$BROWSER -remote 'raise()'
|
||||||
|
esac
|
||||||
|
|
11
plumb/basic
11
plumb/basic
|
@ -119,7 +119,10 @@ dst is postscript
|
||||||
arg isfile $data
|
arg isfile $data
|
||||||
plumb start gv $data
|
plumb start gv $data
|
||||||
|
|
||||||
type is text
|
# urls to internet explorer on another machine
|
||||||
data matches 'Local (.*)'
|
type is text
|
||||||
plumb to none
|
data matches '(https?|ftp|file|gopher|mailto|news|nntp|telnet|wais|prospero)://[a-zA-Z0-9_@\-]+([.:][a-zA-Z0-9_@\-]+)*/?[a-zA-Z0-9_?,%#~&/\-+=@]+([:.][@a-zA-Z0-9_?,%#~&/\-+=]+)*'
|
||||||
plumb start rc -c $1
|
plumb to web
|
||||||
|
plumb start /usr/rsc/bin/web $0
|
||||||
|
# plumb start winstart iexplore -new $0
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ hostproc(void *arg)
|
||||||
i = 0;
|
i = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
i = 1-i; /* toggle */
|
i = 1-i; /* toggle */
|
||||||
n = read(rcfd[0], rcbuf[i].data, sizeof rcbuf[i].data);
|
n = threadread(rcfd[0], rcbuf[i].data, sizeof rcbuf[i].data);
|
||||||
if(n <= 0){
|
if(n <= 0){
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
fprint(2, "9term: host read error: %r\n");
|
fprint(2, "9term: host read error: %r\n");
|
||||||
|
@ -163,7 +163,7 @@ void
|
||||||
hoststart(void)
|
hoststart(void)
|
||||||
{
|
{
|
||||||
hostc = chancreate(sizeof(int), 0);
|
hostc = chancreate(sizeof(int), 0);
|
||||||
proccreate(hostproc, hostc, 32*1024);
|
threadcreate(hostproc, hostc, 32*1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -196,6 +196,7 @@ plumblook(Plumbmsg *m)
|
||||||
openfile(nil, &e);
|
openfile(nil, &e);
|
||||||
free(e.name);
|
free(e.name);
|
||||||
free(e.u.at);
|
free(e.u.at);
|
||||||
|
drawtopwindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -234,6 +235,7 @@ plumbshow(Plumbmsg *m)
|
||||||
winsettag(w);
|
winsettag(w);
|
||||||
textscrdraw(&w->body);
|
textscrdraw(&w->body);
|
||||||
textsetselect(&w->tag, w->tag.file->b.nc, w->tag.file->b.nc);
|
textsetselect(&w->tag, w->tag.file->b.nc, w->tag.file->b.nc);
|
||||||
|
drawtopwindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -25,7 +25,7 @@ long invlong(int);
|
||||||
void hsetdot(int, long, long);
|
void hsetdot(int, long, long);
|
||||||
void hmoveto(int, long);
|
void hmoveto(int, long);
|
||||||
void hsetsnarf(int);
|
void hsetsnarf(int);
|
||||||
/* void hplumb(int); */
|
void hplumb(int);
|
||||||
void clrlock(void);
|
void clrlock(void);
|
||||||
int snarfswap(char*, int, char**);
|
int snarfswap(char*, int, char**);
|
||||||
|
|
||||||
|
@ -296,11 +296,9 @@ inmesg(Hmesg type, int count)
|
||||||
threadexitsall(nil);
|
threadexitsall(nil);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
case Hplumb:
|
case Hplumb:
|
||||||
hplumb(m);
|
hplumb(m);
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,7 +666,6 @@ hsetsnarf(int nc)
|
||||||
setcursor(mousectl, cursor);
|
setcursor(mousectl, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void
|
void
|
||||||
hplumb(int nc)
|
hplumb(int nc)
|
||||||
{
|
{
|
||||||
|
@ -687,7 +684,6 @@ hplumb(int nc)
|
||||||
}
|
}
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hgrow(int m, long a, long new, int req)
|
hgrow(int m, long a, long new, int req)
|
||||||
|
|
|
@ -23,6 +23,6 @@ HFILES=\
|
||||||
|
|
||||||
CFLAGS=$CFLAGS -I../sam
|
CFLAGS=$CFLAGS -I../sam
|
||||||
LDFLAGS=$LDFLAGS -L$X11/lib -lX11 -lm
|
LDFLAGS=$LDFLAGS -L$X11/lib -lX11 -lm
|
||||||
SHORTLIB=frame draw thread regexp9 bio 9
|
SHORTLIB=frame draw plumb fs mux thread regexp9 bio 9
|
||||||
|
|
||||||
<$PLAN9/src/mkone
|
<$PLAN9/src/mkone
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <cursor.h>
|
#include <cursor.h>
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include <frame.h>
|
#include <frame.h>
|
||||||
|
#include <plumb.h>
|
||||||
#include "flayer.h"
|
#include "flayer.h"
|
||||||
#include "samterm.h"
|
#include "samterm.h"
|
||||||
|
|
||||||
|
@ -170,20 +171,15 @@ extstart(void)
|
||||||
atexit(removeextern);
|
atexit(removeextern);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
int
|
int
|
||||||
plumbformat(int i)
|
plumbformat(Plumbmsg *m, int i)
|
||||||
{
|
{
|
||||||
Plumbmsg *m;
|
|
||||||
char *addr, *data, *act;
|
char *addr, *data, *act;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
data = (char*)plumbbuf[i].data;
|
data = (char*)plumbbuf[i].data;
|
||||||
m = plumbunpack(data, plumbbuf[i].n);
|
|
||||||
if(m == nil)
|
|
||||||
return 0;
|
|
||||||
n = m->ndata;
|
n = m->ndata;
|
||||||
if(n == 0){
|
if(n == 0 || 2+n+2 >= READBUFSIZE){
|
||||||
plumbfree(m);
|
plumbfree(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -219,8 +215,9 @@ void
|
||||||
plumbproc(void *argv)
|
plumbproc(void *argv)
|
||||||
{
|
{
|
||||||
Channel *c;
|
Channel *c;
|
||||||
int i, n, which, *fdp;
|
int i, *fdp;
|
||||||
void **arg;
|
void **arg;
|
||||||
|
Plumbmsg *m;
|
||||||
|
|
||||||
arg = argv;
|
arg = argv;
|
||||||
c = arg[0];
|
c = arg[0];
|
||||||
|
@ -229,16 +226,14 @@ plumbproc(void *argv)
|
||||||
i = 0;
|
i = 0;
|
||||||
threadfdnoblock(*fdp);
|
threadfdnoblock(*fdp);
|
||||||
for(;;){
|
for(;;){
|
||||||
i = 1-i; /* toggle */
|
m = threadplumbrecv(*fdp);
|
||||||
n = threadread(*fdp, plumbbuf[i].data, READBUFSIZE);
|
if(m == nil){
|
||||||
if(n <= 0){
|
|
||||||
fprint(2, "samterm: plumb read error: %r\n");
|
fprint(2, "samterm: plumb read error: %r\n");
|
||||||
threadexits("plumb"); /* not a fatal error */
|
threadexits("plumb"); /* not a fatal error */
|
||||||
}
|
}
|
||||||
plumbbuf[i].n = n;
|
if(plumbformat(m, i)){
|
||||||
if(plumbformat(i)){
|
send(c, &i);
|
||||||
which = i;
|
i = 1-i; /* toggle */
|
||||||
send(c, &which);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,18 +253,11 @@ plumbstart(void)
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
arg[0] =plumbc;
|
arg[0] = plumbc;
|
||||||
arg[1] = &fd;
|
arg[1] = &fd;
|
||||||
threadcreate(plumbproc, arg, STACK);
|
threadcreate(plumbproc, arg, STACK);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
|
||||||
plumbstart(void)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
hostproc(void *arg)
|
hostproc(void *arg)
|
||||||
|
|
|
@ -124,6 +124,8 @@ xerror(XDisplay *d, XErrorEvent *e)
|
||||||
{
|
{
|
||||||
char buf[200];
|
char buf[200];
|
||||||
|
|
||||||
|
if(e->request_code == 42) /* XSetInputFocus */
|
||||||
|
return 0;
|
||||||
print("X error: error_code=%d, request_code=%d, minor=%d disp=%p\n",
|
print("X error: error_code=%d, request_code=%d, minor=%d disp=%p\n",
|
||||||
e->error_code, e->request_code, e->minor_code, d);
|
e->error_code, e->request_code, e->minor_code, d);
|
||||||
XGetErrorText(d, e->error_code, buf, sizeof buf);
|
XGetErrorText(d, e->error_code, buf, sizeof buf);
|
||||||
|
|
|
@ -8,7 +8,10 @@
|
||||||
void
|
void
|
||||||
drawtopwindow(void)
|
drawtopwindow(void)
|
||||||
{
|
{
|
||||||
XRaiseWindow(_x.display, _x.drawable);
|
XMapRaised(_x.display, _x.drawable);
|
||||||
|
XFlush(_x.display);
|
||||||
|
XSetInputFocus(_x.display, _x.drawable, RevertToPointerRoot,
|
||||||
|
CurrentTime);
|
||||||
XFlush(_x.display);
|
XFlush(_x.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue