FWIW, I've now extended/written (well, it previously only had getpid) a POSIX interface. It only contains a handful of functions currently, but it's a start, and I think I've got the basics, especially the error handling, done quite well.
I've put it up at http://scheme.mine.nu/gambit/scratch/cj-posix/ . As always, it's written for my chjmodule system, but it shouldn't be difficult to get to work independantly.
Some usage examples:
(bruse cj-posix) (_close 132)
#<posix-exception #2 errno: 9>
(posix-exception? #2)
#t
(posix-exception-message #2)
"Bad file descriptor"
(posix-exception-errno #2)
9
(close 132)
*** ERROR IN (stdin)@4.1 -- close (fd): (132) "Bad file descriptor" 1>
For all POSIX functions which can return errors, I'm exporting two functions, following this principle: the function with an underscore prepended does not throw exceptions; in case of an error, it returns a posix-exception structure. This is efficient, and Schemier (and safer against usage errors) than handling untyped integer values, and it solves the problem that the separate errno variable cannot be safely read from scheme (as the runtime may wipe it out before the user gets a chance to see the value). The function without the underscore throws a (currently untyped) exception on errors.
Some more examples:
(pipe)
#s32(3 4)
(define in (fd->port 3 'RDONLY)) (define out (fd->port 4 'WRONLY)) out
#<output-port #3 (fd-4)>
(display "Hallo\n" out) (force-output out) (read in)
Hallo
(define ex (let ((pid (fork))) (println "pid: " pid) (if (> pid 0) (let ((s (s32vector 1))) (waitpid pid s 0) s) "in child")))
pid: 0
pid: 27649
ex "in child"
(_exit 12) ex
#s32(3072)
(WIFEXITED ex)
#t
(WEXITSTATUS ex)
12
(WTERMSIG ex)
*** ERROR IN (console)@7.1 -- status value is not suited for this operation: #s32(3072) WTERMSIG 1>
At 9:28 Uhr +0800 31.07.2006, TJay wrote:
I see. I've not thought of how threads would be affected, and I'd hate to think of the kinds of strange, hidden bugs I'd get from unflushed buffered ports. I'll have to be super careful if I do any forking.
I think (with some awareness of the issues) it may not be that difficult.
Me too, I'll need multiprocessig soon, for web services. I may try both approaches (or maybe first forking). At least I (or we) now have the choice.
Christian.