Skip to content

Implement accept4 - #2779

Open
emkey1 wants to merge 1 commit into
ish-app:masterfrom
emkey1:implement_accept4
Open

Implement accept4#2779
emkey1 wants to merge 1 commit into
ish-app:masterfrom
emkey1:implement_accept4

Conversation

@emkey1

@emkey1 emkey1 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

accept4 is wired to syscall_stub, so it returns ENOSYS.

Go's net package uses it for every accepted connection, which is what #1889 and #2553 both report:

accept tcp [::]:9999: accept4: function not implemented

Go has no fallback to plain accept, so a Go server fails on its first connection.

What it does

accept plus two flags that apply to the accepted fd: SOCK_CLOEXEC sets FD_CLOEXEC on it and SOCK_NONBLOCK sets O_NONBLOCK on it, neither touching the listener. Any other flag is EINVAL. The socketcall entry is filled in to match.

Verification

Same static i386 binary run on real Linux and on iSH, over a loopback TCP connection:

before after / real Linux
accept4(flags=0) ENOSYS connected fd
SOCK_CLOEXEC sets FD_CLOEXEC ENOSYS set
listener FD_CLOEXEC untouched ok ok
SOCK_NONBLOCK sets O_NONBLOCK ENOSYS set
nonblocking accepted fd reads ENOSYS EAGAIN
peer address filled in ENOSYS AF_INET
bogus flags ENOSYS EINVAL

Reproduced on the Alpine 3.19.0 rootfs the App Store build downloads (ROOTFS_URL in app/iSH.xcconfig), against master 7864dd6.

python3 from the mirrored 3.19 repo also reaches this path: CPython calls accept4(SOCK_CLOEXEC) on Linux, and the log shows stub syscall 364 on each accept. CPython does fall back to plain accept() on ENOSYS, so it keeps working; the difference from Go is the fallback, not the call.

accept4 is wired to syscall_stub, so it returns ENOSYS. Go's net package
uses it for every accepted connection, which is what ish-app#1889 and ish-app#2553 both
report: "accept tcp [::]:9999: accept4: function not implemented".

It is accept plus two flags that apply to the accepted fd: SOCK_CLOEXEC
sets FD_CLOEXEC on it and SOCK_NONBLOCK sets O_NONBLOCK on it, neither
touching the listener. Any other flag is EINVAL. The socketcall entry is
filled in to match.

Verified against real Linux with the same static i386 binary, over a
loopback TCP connection:

                                      before   after / real Linux
  accept4(flags=0)                    ENOSYS   connected fd
  SOCK_CLOEXEC sets FD_CLOEXEC        ENOSYS   set
  listener FD_CLOEXEC untouched       ok       ok
  SOCK_NONBLOCK sets O_NONBLOCK       ENOSYS   set
  nonblocking accepted fd reads       ENOSYS   EAGAIN
  peer address filled in              ENOSYS   AF_INET
  bogus flags                         ENOSYS   EINVAL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants