Add stderr stream; more Unix I/O work

db4
Slava Pestov 2008-01-18 19:43:14 -05:00
parent 588253dfe3
commit 309a1c179c
10 changed files with 120 additions and 19 deletions

View File

@ -35,6 +35,9 @@ GENERIC: stream-write-table ( table-cells style stream -- )
! Default stream
SYMBOL: stdio
! Default error stream
SYMBOL: stderr
: close ( -- ) stdio get stream-close ;
: readln ( -- str/f ) stdio get stream-readln ;

View File

@ -57,11 +57,12 @@ M: c-reader stream-close
M: object init-io ;
: stdin 11 getenv ;
: stdout 12 getenv ;
: stderr 38 getenv ;
M: object init-stdio
stdin stdout <duplex-c-stream> stdio set-global ;
stdin stdout <duplex-c-stream> stdio set-global
stderr <c-writer> stderr set-global ;
M: object io-multiplex (sleep) ;

View File

@ -154,7 +154,7 @@ M: port port-flush ( port -- )
dup buffer-empty? [ drop ] [ (wait-to-write) ] if ;
M: unix-io io-multiplex ( ms -- )
make-timeval unix-io-multiplex ;
unix-io-multiplex ;
M: unix-io init-io ( -- )
H{ } clone read-tasks set-global
@ -162,4 +162,8 @@ M: unix-io init-io ( -- )
init-unix-io ;
M: unix-io init-stdio ( -- )
0 1 handle>duplex-stream io:stdio set-global ;
0 1 handle>duplex-stream io:stdio set-global
2 <writer> io:stderr set-global ;
: multiplexer-error ( n -- )
0 < [ err_no ignorable-error? [ (io-error) ] unless ] when ;

View File

@ -0,0 +1,83 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: alien.syntax kernel io.nonblocking io.unix.backend
sequences assocs unix unix.kqueue math namespaces ;
IN: io.unix.backend.kqueue
TUPLE: unix-kqueue-io ;
! Global variables
SYMBOL: kqueue-fd
SYMBOL: kqueue-changes
SYMBOL: kqueue-events
: max-events ( -- n )
#! We read up to 256 events at a time. This is an arbitrary
#! constant...
256 ; inline
M: unix-kqueue-io init-unix-io ( -- )
V{ } clone kqueue-changes set-global
max-events "kevent" <c-array> kqueue-events set-global
kqueue kqueue-fd dup io-error set-global ;
: add-change ( event -- ) kqueue-changes get-global push ;
: io-task-filter ( task -- n )
class {
{ read-task EVFILT_READ }
{ accept-task EVFILT_READ }
{ receive-task EVFILT_READ }
{ write-task EVFILT_WRITE }
{ connect-task EVFILT_WRITE }
{ send-task EVFILT_WRITE }
} case ;
: make-kevent ( task -- event )
"kevent" <c-object>
over io-task-fd over set-kevent-ident
over io-task-filter over set-kevent-filter ;
: make-add-kevent ( task -- event )
make-kevent
EV_ADD over set-kevent-flags ;
: make-delete-kevent ( task -- event )
make-kevent
EV_DELETE over set-kevent-flags ;
M: unix-select-io register-io-task ( task -- )
make-add-kevent add-change ;
M: unix-select-io unregister-io-task ( task -- )
make-delete-kevent add-change ;
: kqueue-changelist ( -- byte-array n )
kqueue-changes get-global
dup concat f like over length rot delete-all ;
: kqueue-eventlist ( -- byte-array n )
kqueue-events get-global max-events ;
: do-kevent ( timespec -- n )
>r
kqueue-fd get-global
kqueue-changelist
kqueue-eventlist
r> kevent dup multiplexer-error ;
: kevent-task ( kevent -- task )
dup kevent-filter {
{ [ dup EVFILT_READ = ] [ read-tasks ] }
{ [ dup EVFILT_WRITE = ] [ write-tasks ] }
} cond get at ;
: handle-kevents ( n eventlist -- )
[ kevent-nth kevent-task handle-fd ] curry each ;
M: unix-select-io unix-io-multiplex ( ms -- )
make-timespec
do-kevent
kqueue-events get-global handle-kevents ;
T{ unix-kqueue-io } unix-io-backend set-global

View File

@ -44,9 +44,8 @@ M: unix-select-io register-io-task ( task -- ) drop ;
M: unix-select-io unregister-io-task ( task -- ) drop ;
M: unix-select-io unix-io-multiplex ( timeval -- )
>r FD_SETSIZE init-fdsets r> select 0 < [
err_no ignorable-error? [ (io-error) ] unless
] when
make-timeval >r FD_SETSIZE init-fdsets r>
select multiplexer-error
read-fdset/tasks handle-fdset
write-fdset/tasks handle-fdset ;

View File

@ -1,9 +1,11 @@
USE: io.unix.backend
USE: io.unix.files
USE: io.unix.sockets
USE: io.unix.launcher
USE: io.unix.mmap
USE: io.backend
USE: namespaces
USING: io.unix.backend io.unix.files io.unix.sockets
io.unix.launcher io.unix.mmap io.backend combinators namespaces
system vocabs.loader ;
{
{ [ macosx? ] [ "io.unix.backend.kqueue" ] }
{ [ bsd? ] [ "io.unix.backend.kqueue" ] }
{ [ unix? ] [ "io.unix.backend.select" ] }
} cond require
T{ unix-io } io-backend set-global

View File

@ -10,4 +10,3 @@ C-STRUCT: timeval
"timeval" <c-object>
[ set-timeval-usec ] keep
[ set-timeval-sec ] keep ;

View File

@ -41,6 +41,12 @@ C-STRUCT: timespec
{ "time_t" "sec" }
{ "long" "nsec" } ;
: make-timespec ( ms -- timespec )
1000 /mod 1000000 *
"timespec" <c-object>
[ set-timespec-nsec ] keep
[ set-timespec-usec ] keep ;
! ! ! Unix constants
! File type

View File

@ -13,8 +13,9 @@ normal operation. */
void init_c_io(void)
{
userenv[IN_ENV] = allot_alien(F,(CELL)stdin);
userenv[OUT_ENV] = allot_alien(F,(CELL)stdout);
userenv[STDIN_ENV] = allot_alien(F,(CELL)stdin);
userenv[STDOUT_ENV] = allot_alien(F,(CELL)stdout);
userenv[STDERR_ENV] = allot_alien(F,(CELL)stderr);
}
void io_error(void)

View File

@ -16,8 +16,8 @@ typedef enum {
OS_ENV, /* operating system name */
ARGS_ENV = 10, /* command line arguments */
IN_ENV, /* stdin FILE* handle */
OUT_ENV, /* stdout FILE* handle */
STDIN_ENV, /* stdin FILE* handle */
STDOUT_ENV, /* stdout FILE* handle */
IMAGE_ENV = 13, /* image path name */
EXECUTABLE_ENV, /* runtime executable path name */
@ -51,6 +51,9 @@ typedef enum {
STACK_TRACES_ENV = 36,
UNDEFINED_ENV = 37, /* default quotation for undefined words */
STDERR_ENV = 38, /* stderr FILE* handle */
STAGE2_ENV = 39 /* have we bootstrapped? */
} F_ENVTYPE;