On Sat 03 Sep 2022 at 10:23, nature <nat...@blazebone.com> wrote: > Then I tried something simpler like the echo server wrom > rosettacode: https://rosettacode.org/wiki/Echo_server#Forth and this > didn't work as well. > > I then tried to insert some ." at different places and I realized that > create-server and accept-socket works, it's read-socket that > fails/blocks indefinitely. When going deeper and trying to figure out > where exactly in read-socket things were blocking, I found that it's the > recv call that blocks/fails. I wasn't able to figure out more than > that...
It seems that read-socket is trying to provide some kind of higher lever blocking API I do not understand. You can see the source code for read-socket with the following commands: • (eepitch-shell) • (eepitch-kill) • (eepitch-shell) gforth require unix/socket.fs view read-socket view (rs) Using read and write instead of read-socket and write-socket worked for me, see the attached forking echo server example.
\ GOOD \ TODO avoid pthread linking \ gforth ./echo-server9.fs \ (not needed anymore) GFORTHHIST=/no-history gforth ./echo-server9.fs ' noop IS bootmessage \ ' noop IS 'cold \ still uses history file warnings off -status include unix/socket.fs \ include unix/libc.fs \ ?errno-throw c-library wait \c #include <sys/wait.h> \c #define _WNOHANG() WNOHANG c-function WNOHANG _WNOHANG -- n ( -- WNOHANG ) c-function waitpid waitpid n a n -- n ( pid_t *wstatus options -- pid_t ) \c #include <unistd.h> c-function alarm alarm n -- void ( sec -- ) c-function (dup2) dup2 n n -- n ( oldfd newfd -- newfd ) \c #include <signal.h> \c #define _sigchld() signal(SIGCHLD, SIG_IGN) c-function -sigchld _sigchld -- void end-c-library : dup2 ( oldfd newfd -- ) (dup2) -1 = ?errno-throw ; 80 constant size 0 value %server : echo ( -- ) BEGIN 2 alarm \ timeout after 2s inactivity 0 pad size read pad swap ( a u -- ) \ dup . errno . dup 0> WHILE \ 2dup type \ 2dup dump >r >r 1 r> r> write \ TODO loop REPEAT drop drop ; : parent ( socket -- ) close-socket ; : child ( socket -- ) %server close-server dup fileno dup 0 dup2 1 dup2 close-socket ['] echo catch drop bye ; : zombies BEGIN -1 0 WNOHANG waitpid 0> WHILE REPEAT ; : serve 12345 create-server to %server %server 8 listen -sigchld BEGIN 2 alarm \ timeout after 2s inactivity zombies \ TODO test alarm to unblock accept-socket every 2s %server accept-socket 0 alarm \ turn of alarm [char] . emit fork() dup 0< throw IF parent ELSE child THEN AGAIN ; :noname ['] serve catch drop bye ; is 'quit \ history close-file drop