Add stderr stream; more Unix I/O work
parent
588253dfe3
commit
309a1c179c
|
@ -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 ;
|
||||
|
|
|
@ -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) ;
|
||||
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
|
@ -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 ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,4 +10,3 @@ C-STRUCT: timeval
|
|||
"timeval" <c-object>
|
||||
[ set-timeval-usec ] keep
|
||||
[ set-timeval-sec ] keep ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
5
vm/io.c
5
vm/io.c
|
@ -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)
|
||||
|
|
7
vm/run.h
7
vm/run.h
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue