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:
parent
c65bfa3fa3
commit
fd9d392416
28 changed files with 1577 additions and 47 deletions
|
|
@ -25,6 +25,10 @@ struct {
|
|||
struct proc proc[NPROC];
|
||||
} ptable;
|
||||
|
||||
// CPU time of every process already reaped, so that /proc/stat's busy time
|
||||
// does not drop each time one is. Under ptable.lock, like the processes.
|
||||
static uint64 reaped_utime, reaped_stime;
|
||||
|
||||
// Kernel stacks, one per ptable slot, statically.
|
||||
//
|
||||
// **They used to be a single kalloc() page**, and a measurement said that was
|
||||
|
|
@ -313,6 +317,8 @@ found:
|
|||
p->pending_signals = 0;
|
||||
p->alarm_at = p->alarm_every = 0; // a child's timers start disarmed
|
||||
p->utime = p->stime = p->cutime = p->cstime = 0;
|
||||
p->strace = 0;
|
||||
p->umask = 022;
|
||||
|
||||
// A recycled slot must not inherit a dead process's place in the queue --
|
||||
// in either direction. sched_init_proc starts it at min_vruntime, which is
|
||||
|
|
@ -509,6 +515,8 @@ fork(void)
|
|||
np->fs_base = myproc()->fs_base;
|
||||
|
||||
safestrcpy(np->name, myproc()->name, sizeof(myproc()->name));
|
||||
np->strace = myproc()->strace;
|
||||
np->umask = myproc()->umask;
|
||||
|
||||
// The child inherits the parent's place in the queue, priority and all.
|
||||
//
|
||||
|
|
@ -746,6 +754,8 @@ waitpid(int pid, int *status, int options, uint64 *ut, uint64 *st)
|
|||
// of processes rather than one generation deep.
|
||||
myproc()->cutime += p->utime + p->cutime;
|
||||
myproc()->cstime += p->stime + p->cstime;
|
||||
reaped_utime += p->utime;
|
||||
reaped_stime += p->stime;
|
||||
// wait4()'s fourth argument wants the *child's* usage, not the
|
||||
// parent's running total, so it has to be read here -- three lines
|
||||
// further down the slot is UNUSED and these are zero.
|
||||
|
|
@ -1786,6 +1796,11 @@ proc_setsid(void)
|
|||
}
|
||||
myproc()->sid = myproc()->pid;
|
||||
myproc()->pgid = myproc()->pid;
|
||||
// A new session starts with no controlling terminal; that is what lets the
|
||||
// first terminal it opens become one. Keeping the old one meant a tmux pane
|
||||
// still had tty1 as its /dev/tty, and zsh and htop drew straight onto the
|
||||
// console underneath tmux instead of into their pane.
|
||||
myproc()->ctty = 0;
|
||||
r = myproc()->sid;
|
||||
release(&ptable.lock);
|
||||
return r;
|
||||
|
|
@ -1913,6 +1928,7 @@ proc_snapshot(int idx, struct procinfo *out)
|
|||
out->nivcsw = p->nivcsw;
|
||||
safestrcpy(out->name, p->name, sizeof(out->name));
|
||||
safestrcpy(out->exe, p->exe, sizeof(out->exe));
|
||||
out->kthread = p->kfn != 0;
|
||||
release(&ptable.lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2012,3 +2028,24 @@ proc_kill_init(void)
|
|||
if (initproc)
|
||||
initproc->killed = 1;
|
||||
}
|
||||
|
||||
// Ticks spent in user and kernel mode by every process, living or reaped.
|
||||
// What /proc/stat's busy columns are made of; the rest of the time was idle.
|
||||
void
|
||||
proc_cputime(uint64 *user, uint64 *sys)
|
||||
{
|
||||
struct proc *p;
|
||||
uint64 u, s;
|
||||
|
||||
acquire(&ptable.lock);
|
||||
u = reaped_utime;
|
||||
s = reaped_stime;
|
||||
for (p = ptable.proc; p < &ptable.proc[NPROC]; p++)
|
||||
if (p->state != UNUSED) {
|
||||
u += p->utime;
|
||||
s += p->stime;
|
||||
}
|
||||
release(&ptable.lock);
|
||||
*user = u;
|
||||
*sys = s;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue