<commit_before>! Copyright (C) 2004, 2008 <NAME>, <NAME>. 
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.c-types alien.strings generic kernel math
namespaces threads sequences byte-arrays io.ports
io.binary io.unix.backend io.streams.duplex
io.backend io.ports io.files io.files.private
io.encodings.utf8 math.parser continuations libc combinators
system accessors qualified destructors unix locals ;

EXCLUDE: io => read write close ;
EXCLUDE: io.sockets => accept ;

IN: io.unix.sockets

: socket-fd ( domain type -- fd )
    0 socket dup io-error <fd> |dispose ;

: set-socket-option ( fd level opt -- )
    >r >r handle-fd r> r> 1 <int> "int" heap-size setsockopt io-error ;

M: unix addrinfo-error ( n -- )
    dup zero? [ drop ] [ gai_strerror throw ] if ;

! Client sockets - TCP and Unix domain
M: object (get-local-address) ( handle remote -- sockaddr )
    >r handle-fd r> empty-sockaddr/size <int>
    [ getsockname io-error ] 2keep drop ;

M: object (get-remote-address) ( handle local -- sockaddr )
    >r handle-fd r> empty-sockaddr/size <int>
    [ getpeername io-error ] 2keep drop ;

: init-client-socket ( fd -- )
    SOL_SOCKET SO_OOBINLINE set-socket-option ;

: wait-to-connect ( port -- )
    dup handle>> handle-fd f 0 write
    {
        { [ 0 = ] [ drop ] }
        { [ err_no EAGAIN = ] [ dup +output+ wait-for-port wait-to-connect ] }
        { [ err_no EINTR = ] [ wait-to-connect ] }
        [ (io-error) ]
    } cond ;

M: object establish-connection ( client-out remote -- )
    [ drop ] [ [ handle>> handle-fd ] [ make-sockaddr/size ] bi* connect ] 2bi
    {
        { [ 0 = ] [ drop ] }
        { [ err_no EINPROGRESS = ] [
            [ +output+ wait-for-port ] [ wait-to-connect ] bi
        ] }
        [ (io-error) ]
    } cond ;

M: object ((client)) ( addrspec -- fd )
    protocol-family SOCK_STREAM socket-fd dup init-client-socket ;

! Server sockets - TCP and Unix domain
: init-server-socket ( fd -- )
    SOL_SOCKET SO_REUSEADDR set-socket-option ;

: server-socket-fd ( addrspec type -- fd )
    >r dup protocol-family r> socket-fd
    dup init-server-socket
    dup handle-fd rot make-sockaddr/size bind io-error ;

M: object (server) ( addrspec -- handle )
    [
        SOCK_STREAM server-socket-fd
        dup handle-fd 10 listen io-error
    ] with-destructors ;

: do-accept ( server addrspec -- fd )
    [ handle>> handle-fd ] [ empty-sockaddr/size <int> ] bi* accept ; inline

M:: object (accept) ( server addrspec -- fd sockaddr )
    server addrspec do-accept
    {
        { [ dup 0 >= ] [ <fd> dup addrspec (get-remote-sockaddr) ] }
        { [ err_no EINTR = ] [ drop (accept) ] }
        { [ err_no EAGAIN = ] [
            drop
            server +input+ wait-for-port
            server addrspec (accept)
        ] }
        [ (io-error) ]
    } cond ;

! Datagram sockets - UDP and Unix domain
M: unix (datagram)
    [ SOCK_DGRAM server-socket-fd ] with-destructors ;

SYMBOL: receive-buffer

: packet-size 65536 ; inline

packet-size <byte-array> receive-buffer set-global

:: do-receive ( port -- packet sockaddr )
    port addr>> empty-sockaddr/size [| sockaddr len |
        port handle>> handle-fd ! s
        receive-buffer get-global ! buf
        packet-size ! nbytes
        0 ! flags
        sockaddr ! from
        len <int> ! fromlen
        recvfrom dup 0 >= [
            receive-buffer get-global swap head sockaddr
        ] [
            drop f f
        ] if
    ] call ;<commit_msg>Fix conflict<commit_after>! Copyright (C) 2004, 2008 <NAME>, <NAME>. 
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.c-types alien.strings generic kernel math
namespaces threads sequences byte-arrays io.ports
io.binary io.unix.backend io.streams.duplex
io.backend io.ports io.files io.files.private
io.encodings.utf8 math.parser continuations libc combinators
system accessors qualified destructors unix locals ;

EXCLUDE: io => read write close ;
EXCLUDE: io.sockets => accept ;

IN: io.unix.sockets

: socket-fd ( domain type -- fd )
    0 socket dup io-error <fd> |dispose ;

: set-socket-option ( fd level opt -- )
    >r >r handle-fd r> r> 1 <int> "int" heap-size setsockopt io-error ;

M: unix addrinfo-error ( n -- )
    dup zero? [ drop ] [ gai_strerror throw ] if ;

! Client sockets - TCP and Unix domain
M: object (get-local-address) ( handle remote -- sockaddr )
    >r handle-fd r> empty-sockaddr/size <int>
    [ getsockname io-error ] 2keep drop ;

M: object (get-remote-address) ( handle local -- sockaddr )
    >r handle-fd r> empty-sockaddr/size <int>
    [ getpeername io-error ] 2keep drop ;

: init-client-socket ( fd -- )
    SOL_SOCKET SO_OOBINLINE set-socket-option ;

: wait-to-connect ( port -- )
    dup handle>> handle-fd f 0 write
    {
        { [ 0 = ] [ drop ] }
        { [ err_no EAGAIN = ] [ dup +output+ wait-for-port wait-to-connect ] }
        { [ err_no EINTR = ] [ wait-to-connect ] }
        [ (io-error) ]
    } cond ;

M: object establish-connection ( client-out remote -- )
    [ drop ] [ [ handle>> handle-fd ] [ make-sockaddr/size ] bi* connect ] 2bi
    {
        { [ 0 = ] [ drop ] }
        { [ err_no EINPROGRESS = ] [
            [ +output+ wait-for-port ] [ wait-to-connect ] bi
        ] }
        [ (io-error) ]
    } cond ;

M: object ((client)) ( addrspec -- fd )
    protocol-family SOCK_STREAM socket-fd dup init-client-socket ;

! Server sockets - TCP and Unix domain
: init-server-socket ( fd -- )
    SOL_SOCKET SO_REUSEADDR set-socket-option ;

: server-socket-fd ( addrspec type -- fd )
    >r dup protocol-family r> socket-fd
    dup init-server-socket
    dup handle-fd rot make-sockaddr/size bind io-error ;

M: object (server) ( addrspec -- handle )
    [
        SOCK_STREAM server-socket-fd
        dup handle-fd 10 listen io-error
    ] with-destructors ;

: do-accept ( server addrspec -- fd sockaddr )
    [ handle>> handle-fd ] [ empty-sockaddr/size <int> ] bi*
    [ accept ] 2keep drop ; inline

M: object (accept) ( server addrspec -- fd sockaddr )
    2dup do-accept
    {
        { [ over 0 >= ] [ >r 2nip <fd> r> ] }
        { [ err_no EINTR = ] [ 2drop (accept) ] }
        { [ err_no EAGAIN = ] [
            2drop
            [ drop +input+ wait-for-port ]
            [ (accept) ]
            2bi
        ] }
        [ (io-error) ]
    } cond ;

! Datagram sockets - UDP and Unix domain
M: unix (datagram)
    [ SOCK_DGRAM server-socket-fd ] with-destructors ;

SYMBOL: receive-buffer

: packet-size 65536 ; inline

packet-size <byte-array> receive-buffer set-global

:: do-receive ( port -- packet sockaddr )
    port addr>> empty-sockaddr/size [| sockaddr len |
        port handle>> handle-fd ! s
        receive-buffer get-global ! buf
        packet-size ! nbytes
        0 ! flags
        sockaddr ! from
        len <int> ! fromlen
        recvfrom dup 0 >= [
            receive-buffer get-global swap head sockaddr
        ] [
            drop f f
        ] if
    ] call ;
{'fraction_non_alphanumeric': 0.12578706353749283, 'fraction_numerical': 0.008586147681740127, 'mean_word_length': 2.234150856085146, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4994486', 'n_tokens_mistral': 2372, 'n_tokens_neox': 2290, 'n_words': 648}