There are a few issues with Plan 9's `access`:
- it has side effects: to test the actual access (that the file
servers can allow or deny according to complex custom rules)
it opens and then closes the file, allocating (and disposing) the fd
- it does not work on directories, since
- they cannot be opened for writing, despite the fact that to
create a file in a directory you must be granted write access on
that directory
- they cannot be opened for execution, despite the fact that to
access a file in a directory you must be granted execution access
on that directory
Despite the fact that `access` (even on UNIX) is a violation of the
"tell, don't ask" principle (the access could be forbidden just after
its successful return, making subsequent `open` fail anyway), this
fact smells of a little design error in the file interface.
So, right now we choose to let the libposix's `access` lie on directories:
it will always return 0 on AWRITE and AEXEC for them, accepting that
a successive create/mkdir may fail.
However, a cleaner file API and protocol should allow a simpler `access`
to be implemented for directories too.
For each test, if a script exists with the same name of the test
plus the .runner suffix, the runner is run instead of the test.
As a first example qa/lib/newlib/testsuite/atexit is run by
qa/lib/newlib/testsuite/atexit.runner.
These .runner scripts allow more complex checks of the side effects
generated by the test.
With this commit all functions declared in libc.h have been renamed
with the "jehanne_" prefix. This is done for several reason:
- it removes conflicts during symbol resolution when linking
standard C libraries like newlib or musl
- it allows programs depending on a standard C library to directly
link to a library depending on our non standard libc (eg libsec).
To ease transiction two files are provided:
- sys/include/lib9.h that can be included instead of <libc.h> to use
the old names (via a simple set of macros)
- sys/src/lib/c/lib9.c that can be compiled with a program where the
macro provided by lib9.h are too dumb (see for example rc or grep).
In the kernel port/lib.h has been modified accordingly and some of
the functions it directly provides has been renamed too (eg malloc
in qmalloc.c and print in devcons.c).
These new implementations
- do several validity check on input parameters
- allow a bit larger variable names (127 bytes, aka sizeof(Proc.genbuf)-1)
- preserve nulls in the content (the original version used to replace
'\0' with ' '). I can't see why they did, actually.
See also http://marc.info/?l=9fans&m=148475801229908&w=2
Should also fix CID 155718
In Plan9 the create syscall fallback on a open(OTRUNC) if the
path provided already exists. This is actually a common requirement
as most programs (editors, cat...) simply requires that a file is
there and is empty, and doesn't care overwriting existing contents
(note that this is particularily sensible with something like fossil).
In Jehanne the application is responsible of actually handle this
"file exists" error but libc provides ocreate() to mimic the Plan9
behaviour. Note that ocreate introduce a subtle race too: the path
is walked several times if the file exists, thus it could misbehave
on concurrent namespace changes. However I guess this is not going to
happen often enough to care now.
NOTE we will probably address this rare race too, with a more drammatic change
to syscalls: a new walk() syscall that will provide an unopen fd.
Added wdir to devself and devproc:
- read '#0/wdir' to get the working directory of the calling process
NOTE that a read(fd, nil, -1) will return the negated length
of the working directory, just in case you want to
allocate the memory required
- read '/proc/n/wdir' to know the working directory of process n
(read(fd, nil, -1) still returns the negated length)
- write '#0/wdir' to change the working directory of the calling process
NOTE: no offset is allowed and the provided string must
be null terminated
- write '/proc/n/wdir' to change the working directory of process n
NOTE: no offset is allowed and the provided string must
be null terminated; moreover if another process change the working
directory change during the write, the current process will
receive an error.
In libc updated getwd() and chdir().
Also modified pwd to get advantage of the new file.
To test, run /arch/amd64/qa/kern/wdir.rc or simply try
% pwd
/usr/glenda
% echo -n /tmp > /proc/$pid/wdir
% pwd
/tmp
% cat '#0/wdir' && echo
/tmp
The expected use cases for wdir in devproc are rio and acme.
Also, note that we could theoretically remove the cd builtin
from rc and simply implement it as a rc function.
We don't do that to preserve rc portability to other OS.