Pseudo-terminals, and what tmux and htop needed around them

- /dev/ptmx and /dev/pts/N: Unix98 pairs with a full line discipline,
  window sizes, job control and hangup (kernel/dev/pty.c).
- The console speaks scroll regions, insert/delete line, SU/SD, RI/IND/NEL,
  DECSC/DECRC; swallows charset designations and private CSI sequences;
  and LF only returns the carriage under ONLCR.
- setsid() drops the controlling terminal, so a pane's pty becomes its ctty.
- pipe2() honours O_NONBLOCK and O_CLOEXEC (libevent's signal pipe).
- File modes are stored and enforced: chmod, fchmod(at), umask, creation
  modes; /tmp is 1777.
- /proc/stat has real user/system/idle; /proc/<pid>/task; kthread flag.
- SO_PEERCRED, IOV_MAX 1024.
- /proc/strace: name a program and its syscalls go to the kernel log.
- World gains htop, btop, tmux, mc, ncdu, fastfetch, games, X toys, NetSurf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-25 02:11:10 +01:00
commit fd9d392416
28 changed files with 1577 additions and 47 deletions

View file

@ -752,6 +752,23 @@ SYSCALL_DEFINE(getsockopt)
argaddr(3, &uval);
argaddr(4, &ulenp);
// SO_PEERCRED: who is on the other end of a Unix socket. tmux asks its
// client this and, told nothing, refuses it as a stranger.
if (level == 1 && name == 17) {
struct { int pid; uint uid, gid; } cr;
int want;
if (sock_peercred(s, &cr.pid, &cr.uid, &cr.gid) < 0)
return -ENOTCONN;
if (!uval || !ulenp || get_user(want, ulenp) < 0)
return -EFAULT;
if (want < (int)sizeof(cr))
return -EINVAL;
if (copy_to_user(uval, &cr, sizeof(cr)) < 0)
return -EFAULT;
want = sizeof(cr);
return put_user(want, ulenp) < 0 ? -EFAULT : 0;
}
if ((r = sockopt_get(s, level, name, &val)) < 0)
return r;
return opt_out(uval, ulenp, val);
@ -769,11 +786,11 @@ SYSCALL_DEFINE(getsockopt)
// docs/plan/foundations.md item 1, and docs/plan/hybrid.md mechanism 1.
// ---------------------------------------------------------------------------
// Linux caps an iovec at UIO_MAXIOV = 1024. Thirty-two is the cap here for one
// reason: each entry is validated and copied individually, and a caller that
// needs more than thirty-two separate buffers in one message is describing a
// problem this kernel has not met. EMSGSIZE is Linux's answer for too many.
#define SCH_IOV_MAX 32
// Linux caps an iovec at UIO_MAXIOV = 1024, and so does this. It was 32, and
// tmux met it on its first message: imsg hands sendmsg every queued buffer at
// once, one iovec each, and a client announcing its environment has dozens.
// Nothing is sized by the count -- each entry is fetched and copied on its own.
#define SCH_IOV_MAX 1024
// The control buffer is copied onto the kernel stack, and that stack is 4 KB
// (param.h, KSTACKSIZE). 256 bytes holds CMSG_SPACE(SCM_MAXFD * 4) six times