Skip to content

sysvipc: implement missing semctl commands for semaphores#343

Open
hernandevelop wants to merge 2 commits intotermux:masterfrom
hernandevelop:fix/sysvipc-semctl-ipc-stat
Open

sysvipc: implement missing semctl commands for semaphores#343
hernandevelop wants to merge 2 commits intotermux:masterfrom
hernandevelop:fix/sysvipc-semctl-ipc-stat

Conversation

@hernandevelop
Copy link
Copy Markdown

Summary

The semaphore implementation in sysvipc_sem.c was missing several semctl commands, most notably IPC_STAT which was stubbed out with #if 0 (containing a copy-paste from message queues that referenced queue->stats). Any unimplemented command fell through to default: return -EINVAL.

This caused applications that verify semaphore state via semctl(semid, 0, IPC_STAT, &buf) to receive EINVAL and incorrectly conclude the semaphore was destroyed.

Changes

  • sysvipc_sys.h: Add SysVIpcSemidDs struct (matching kernel semid_ds layout, consistent with existing SysVIpcShmidDs)
  • sysvipc_internal.h: Add stats field to SysVIpcSemaphore
  • sysvipc_sem.c:
    • Implement IPC_STAT / SEM_STAT / SEM_STAT_ANY: return semaphore metadata to userspace
    • Implement IPC_SET: allow updating permissions
    • Implement GETPID, GETNCNT, GETZCNT: return waiter counts
    • Initialize sem_ctime and sem_perm.mode on semget
    • Update sem_otime on successful semop
    • Update sem_ctime on SETVAL

Context

I ran into this while trying to run JetBrains Toolbox inside proot-distro on Android. Toolbox uses SysV semaphores for single-instance locking and calls IPC_STAT to check sem_otime after initialization. The missing implementation caused it to always fail with "Semaphore doesn't exist anymore".

The fix follows the same patterns already used in sysvipc_shm.c (which has a working IPC_STAT implementation) and sysvipc_msg.c.

Testing

  • Verified JetBrains Toolbox starts and acquires its semaphore lock correctly
  • Verified semgetsemctl SETVALsemopsemctl IPC_STAT sequence works end-to-end
  • No regressions observed in existing proot-distro desktop sessions (Cinnamon on Ubuntu)

…T, GETZCNT, GETPID)

semctl for semaphores was missing several commands that are commonly
used by applications to query semaphore state. Notably IPC_STAT was
stubbed out with #if 0 and fell through to the default case returning
-EINVAL, causing applications that verify semaphore existence via
IPC_STAT (checking sem_otime) to incorrectly conclude the semaphore
was destroyed.

Changes:
- Add SysVIpcSemidDs struct to sysvipc_sys.h (matching kernel layout)
- Add stats field to SysVIpcSemaphore for tracking metadata
- Implement IPC_STAT, SEM_STAT, SEM_STAT_ANY: return semaphore metadata
- Implement IPC_SET: allow updating permissions
- Implement GETPID, GETNCNT, GETZCNT: return waiter counts
- Initialize sem_ctime and sem_perm.mode on semget
- Update sem_otime on successful semop
- Update sem_ctime on SETVAL

Tested with JetBrains Toolbox which relies on IPC_STAT to verify
semaphore initialization state.
The SHM helper process now creates an abstract Unix socket listener
using Termux:X11's protocol (\0/dev/shm/<socket_id>), and generates
shmids in Termux:X11-compatible format (socket_id << 16 | counter).

When a process inside proot creates a SHM segment and sends the shmid
to the X11 server via XShmAttach, the server can now find and attach
the segment through the bridge socket, receiving the ashmem fd via
SCM_RIGHTS.

This eliminates the need for workarounds like:
- GSK_RENDERER=cairo (disabling GL rendering in GTK4)
- termux-x11 -extension MIT-SHM (disabling SHM entirely)
- LD_PRELOAD with external shm_compat.so

Changes:
- sysvipc_shm.c: Add X11 bridge thread in helper process that serves
  the Termux:X11 fd-passing protocol. Register segments on allocation,
  unregister on free. Send bridge socket_id to proot main process via
  existing pipe. Refactor helper launch into sysvipc_shm_ensure_helper()
  so socket_id is available before generating shmids.
- sysvipc_internal.h: Add x11_shmid field to SysVIpcSharedMem struct.
  Add LOOKUP_SHM_OBJECT macro for x11_shmid-based lookup.
- GNUmakefile: Link with -lpthread for bridge thread.

Tested with GTK4 file-roller (MIT-SHM) and Cinnamon desktop session
on Termux:X11 with proot-distro.
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.

1 participant