Host: boot time, load, memory, CPU time, counters, disks, interfaces, interrupts, processes and users, the same records on Linux and Darwin.
Linux reads sysinfo(2) and /proc; Darwin reads sysctl, the Mach host statistics, IOKit and proc_pidinfo over the dlopen FFI; both read utmpx through libc.
HostThe machine as the kernel reports it: boot time, load, memory, CPU time, system-wide counters, disk, network and interrupt totals, processes and logged-in users, the same records on Linux and Darwin.
A field the kernel does not report is nil. Darwin reports another user’s process memory and CPU time only to root.
source‘linux or ‘darwin: which reader answers; nil means this kernel’s
Static field: data held by Host itself, not by its instances.
proc-rootThe /proc tree the Linux reader opens
Static field: data held by Host itself, not by its instances.
typesThe STRING, POINTER and INTEGER type handles, once %types has looked them up
Static field: data held by Host itself, not by its instances.
ctxWhat %darwin-ctx resolves, once it has; cleared when an image is loaded
Static field: data held by Host itself, not by its instances.
(Host %backend)The reader that answers: the source field, or this kernel’s.
Returns: SYMBOL — ‘linux or ‘darwin
Examples:
(List includes? (Host %backend) (list 'linux 'darwin)) => #t(Host %sym name)The named libc function, resolved through the process’s own handle.
Parameters:
STRING — libc function nameReturns: POINTER — The function pointer
(Host %call name . argv)Call a libc function and fold its int result to a signed value.
Parameters:
STRING — libc function nameLIST — Its argumentsReturns: INTEGER — The result, negative on failure
Examples:
(= (Host %call "getpid") (Sys getpid)) => #t(Host %buf n)A GC-owned region of n bytes. Its contents are not zeroed: read only what a call wrote.
Parameters:
INTEGER — Size in bytesReturns: STRING — The region
(Host %ptr buf)The region’s address, for a C argument.
Parameters:
STRING — A region from %bufReturns: POINTER — The address
Examples:
(Host %cstr-ptr (Host %ptr "hi")) => "hi"(Host %int-at buf off n)The unsigned little-endian integer of n bytes at off.
Parameters:
STRING — A regionINTEGER — Byte offsetINTEGER — Width: 1, 2, 4 or 8Returns: INTEGER — The value
Examples:
(Host %int-at "AB" 0 2) => 16961
(Host %int-at "AB" 1 1) => 66(Host %signed-at buf off n)The two’s-complement integer of n bytes at off.
Parameters:
STRING — A regionINTEGER — Byte offsetINTEGER — Width: 1, 2 or 4Returns: INTEGER — The value
Examples:
(Host %signed-at (bytes->str (list 255 255)) 0 2) => -1
(Host %signed-at "AB" 0 2) => 16961(Host %types)The STRING, POINTER and INTEGER type handles, looked up once: a (Type named) lookup costs tens of thousands of objects, and a C string is read for every argument of every process.
Returns: LIST — (STRING POINTER INTEGER)
Examples:
(List length (Host %types)) => 3(Host %cstr-at buf off n)The NUL-terminated string at off, at most n bytes. Read through its address: a region’s own length stops at its first NUL, so a substring of it cannot reach past one.
Parameters:
STRING — A regionINTEGER — Byte offsetINTEGER — Most bytes to readReturns: STRING — The string
Examples:
(Host %cstr-at "hello" 1 3) => "ell"
(Host %cstr-at (bytes->str (list 97 98 0 99)) 0 4) => "ab"(Host %cstr-ptr p)The C string at an address.
Parameters:
POINTER — Address of a NUL-terminated stringReturns: STRING — The string
Examples:
(Host %cstr-ptr (Host %ptr "hi")) => "hi"(Host %int s)The integer a decimal field spells; nil when it spells none.
Parameters:
STRING — Decimal digits, optionally signedReturns: ANY — INTEGER, or nil
Examples:
(Host %int "-42") => -42
(null? (Host %int "x")) => #t(Host %hex s)The integer a run of hex digits spells, read up to the first byte that is not one; 0 for none. Sixteen digits are its 64 bits, through the int doors whether or not the tower is loaded, so a value past the signed range, such as an address in the top half of the address space, is negative.
Parameters:
STRING — Hexadecimal digitsReturns: INTEGER — The value
Examples:
(Host %hex "ff") => 255
(Host %hex "1fz") => 31(Host %fold-lines path f init)Fold f over a file’s lines, read a piece at a time, so a long /proc file is never held whole.
Parameters:
STRING — A fileCALLABLE — (f line acc) answers the next acc; line has no newlineANY — The first accReturns: ANY — The last acc, or nil when the file cannot be opened
Examples:
(Host %fold-lines "/dev/null" (fn (_ line n) (+ n 1)) 0) => 0
(null? (Host %fold-lines "/nonexistent/file" (fn (_ line n) (+ n 1)) 0)) => #t(Host %read path)The whole of a /proc file, or nil when it cannot be opened. /proc files stat as empty, so this reads to end of file rather than sizing by stat. Text only: a NUL ends the string.
Parameters:
STRING — A file under /procReturns: ANY — STRING, or nil
Examples:
(null? (Host %read "/nonexistent/file")) => #t(Host %fields s)The line’s fields, split on runs of spaces.
Parameters:
STRING — A lineReturns: LIST — Field strings
Examples:
(Host %fields " cpu0 12 34 ") => ("cpu0" "12" "34")(Host %line-value lines key)The integer after a line’s leading key, or nil when no line has it.
Parameters:
LIST — Lines of a /proc fileSTRING — Leading word, e.g. “btime” or “Cached:”Returns: ANY — INTEGER, or nil
Examples:
(Host %line-value (list "cpu 1 2" "btime 1700000000") "btime") => 1700000000
(null? (Host %line-value (list "cpu 1 2") "btime")) => #t(Host %lines name)A /proc file’s lines, or nil when it cannot be read.
Parameters:
STRING — File under the /proc rootReturns: LIST — Line strings
Examples:
(null? (Host %lines "no-such-file")) => #t(Host %sysconf linux darwin)A sysconf value; the name numbers differ between the two libcs.
Parameters:
INTEGER — The name’s number on LinuxINTEGER — Its number on DarwinReturns: INTEGER — The value
Examples:
(= (Host %sysconf 30 29) (Host %page-size)) => #t(Host %hz)Clock ticks a second (_SC_CLK_TCK), the unit of /proc’s CPU times.
Returns: INTEGER — Ticks a second
Examples:
(< 0 (Host %hz)) => #t(Host %ticks->ns t)Clock ticks in nanoseconds.
Parameters:
INTEGER — Clock ticksReturns: INTEGER — Nanoseconds
Examples:
(Host %ticks->ns (Host %hz)) => 1000000000(Host %sysinfo)struct sysinfo as an alist of the fields read here.
Returns: ALIST — uptime, three loads (scaled by 65536), memory fields in units, unit
(Host %sysctl name n)The value of a sysctl name as a region, or nil when the kernel refuses.
Parameters:
STRING — A sysctl name, e.g. “vm.loadavg”INTEGER — Buffer sizeReturns: ANY — STRING region, or nil
(Host %sysctl-size name)How many bytes the sysctl name’s value currently needs.
Parameters:
STRING — A sysctl nameReturns: INTEGER — Bytes, 0 when the kernel refuses
(Host %page-size)The page size (sysconf _SC_PAGESIZE), the unit of /proc’s rss and of the Mach page counts.
Returns: INTEGER — Bytes
Examples:
(< 0 (Host %page-size)) => #t(Host %mach-ns t)Mach time units in nanoseconds, by mach_timebase_info.
Parameters:
INTEGER — Mach absolute time unitsReturns: INTEGER — Nanoseconds
(Host boot-time)When the machine booted, in unix seconds. Linux answers now less sysinfo’s uptime, as BusyBox’s uptime -s does; Darwin answers kern.boottime.
Returns: INTEGER — Unix seconds
(Host load)The 1, 5 and 15 minute load averages. Each is the kernel’s fixed-point value divided by its scale, so it is exact: sysinfo’s 65536 on Linux, vm.loadavg’s fscale on Darwin.
Returns: LIST — Three floats
(Host %darwin-loads)vm.loadavg’s three averages, each divided by its fscale.
Returns: LIST — Three floats
(Host tasks)The scheduler’s counts: running (entities runnable now), total (entities that exist) and last-pid (the pid most recently handed out). Linux reads /proc/loadavg’s fourth and fifth fields, which top prints after the load averages; Darwin reports none of them.
Returns: ALIST — ((running . N) (total . N) (last-pid . N)); a field not reported is nil
(Host memory)Memory and swap in bytes: total free shared buffers cached reclaimable available swap-total swap-free anon mapped slab dirty writeback. Linux takes the totals from sysinfo and cached (Cached), reclaimable (SReclaimable), available (MemAvailable), anon (AnonPages), mapped (Mapped), slab (Slab), dirty (Dirty) and writeback (Writeback) from /proc/meminfo, as BusyBox’s free and top -m do. Darwin takes total from hw.memsize, free, cached (file-backed pages) and anon (anonymous pages) from the Mach VM statistics and swap from vm.swapusage; it reports no shared, buffers, reclaimable, available, mapped, slab, dirty or writeback.
Returns: ALIST — ((total . N) (free . N) … (swap-free . N)); a field not reported is nil
(Host %linux-memory)memory, from sysinfo and /proc/meminfo.
Returns: ALIST — The memory record
(Host %darwin-memory)memory, from sysctl and host_statistics64 (HOST_VM_INFO64).
Returns: ALIST — The memory record
(Host %darwin-vm)host_statistics64’s HOST_VM_INFO64, a struct vm_statistics64, or nil when the kernel refuses.
Returns: ANY — STRING region, or nil
(Host counters)The kernel’s running totals since boot: context-switches interrupts softirqs forks running blocked paged-in paged-out swap-ins swap-outs faults major-faults open-files max-files. running and blocked are the processes runnable now and waiting on I/O now (the running count includes the reader); paged-in and paged-out are bytes; swap-ins and swap-outs are pages; open-files is the file handles in use and max-files the kernel’s limit. Linux reads /proc/stat (ctxt intr softirq processes procs_running procs_blocked), /proc/vmstat (pgpgin pgpgout pswpin pswpout pgfault pgmajfault) and /proc/sys/fs/file-nr, as BusyBox’s vmstat and nmeter do. Darwin reads the Mach VM statistics (pageins pageouts swapins swapouts faults) and kern.num_files and kern.maxfiles; it reports no context switches, interrupts, softirqs, forks, run queue or major faults. Differences between two readings give the rates vmstat shows.
Returns: ALIST — ((context-switches . N) (interrupts . N) … (max-files . N)); a field not reported is nil
(Host %linux-counters)counters, from /proc/stat, /proc/vmstat and /proc/sys/fs/file-nr.
Returns: ALIST — The counters record
(Host %darwin-counters)counters, from host_statistics64’s HOST_VM_INFO64 and sysctl.
Returns: ALIST — The counters record
(Host interrupts)The interrupt counts since boot, one record a source: name counts total description soft?. name is the kernel’s label (an IRQ number, or NMI, LOC, TIMER and the like); counts pairs each processor’s number with its count, nil for a source the kernel counts only once; total is their sum; description is the rest of the line (controller, trigger, devices), nil when there is none; soft? is #t for a softirq. Linux reads /proc/interrupts and then /proc/softirqs, as BusyBox’s mpstat -I does. Darwin reports none, and answers nil.
Returns: ANY — LIST of interrupt records, or nil
(Host %irq-table name soft)The records of one /proc interrupt table: a header naming the processors (CPU0 CPU1 …), then a line a source, NAME: then a count a processor.
Parameters:
STRING — interrupts or softirqs, under the /proc rootBOOL — Whether its sources are softirqsReturns: LIST — Interrupt records
(Host %digits? s)Whether a field is all decimal digits, and at least one.
Parameters:
STRING — A fieldReturns: BOOL — #t or #f
Examples:
(Host %digits? "123") => #t
(Host %digits? "12a") => #f
(Host %digits? "") => #f(Host disks)The block devices’ I/O totals since boot, one record a device: name major minor reads reads-merged read-bytes read-time writes writes-merged write-bytes write-time in-flight io-time queue-time. Times are nanoseconds: read-time and write-time the time spent on each, io-time the time the device was busy, queue-time the busy time weighted by the requests in flight. Linux reads /proc/diskstats, as BusyBox’s iostat and nmeter do, every device and partition it lists (a sector there is 512 bytes); an old kernel’s four-figure partition line gives only reads, read-bytes, writes and write-bytes. Darwin reads each IOBlockStorageDriver’s Statistics through IOKit, named by its media’s BSD name, and reports no merges, in-flight, io-time or queue-time.
Returns: LIST — Disk records
(Host %disk-record name v)The disk record for a name and its figures.
Parameters:
STRING — Device nameLIST — major minor and the twelve totals, in disks’ orderReturns: ALIST — The disk record
Examples:
(Assoc get 'reads (Host %disk-record "sda" (list 8 0 120))) => 120
(null? (Assoc get 'writes (Host %disk-record "sda" (list 8 0 120)))) => #t(Host %linux-disks)disks, from /proc/diskstats: major minor name, then reads merged sectors ms, writes merged sectors ms, in-flight, io ms and weighted ms.
Returns: LIST — Disk records
(Host %darwin-disks)disks, from IOKit: each IOBlockStorageDriver’s Statistics dictionary (Operations, Bytes and Total Time, read and write, the times in nanoseconds), and the BSD Name, Major and Minor of the media under it. A driver with no media, an empty reader, is left out. nil when IOKit will not load.
Returns: LIST — Disk records
(Host interfaces)The network interfaces’ traffic totals since boot, one record an interface: name rx-bytes rx-packets rx-errors rx-dropped rx-fifo rx-frame rx-compressed rx-multicast tx-bytes tx-packets tx-errors tx-dropped tx-fifo tx-collisions tx-carrier tx-compressed. rx counts what arrived, tx what was sent. Linux reads /proc/net/dev, as BusyBox’s nmeter and ifconfig do. Darwin reads each interface’s ifmibdata sysctl, as netstat -i does, with tx-dropped its send queue’s drops; it reports no fifo, frame, compressed or carrier counts.
Returns: LIST — Interface records
(Host %interface-record name v)The interface record for a name and its totals.
Parameters:
STRING — Interface nameLIST — The sixteen totals, in interfaces’ orderReturns: ALIST — The interface record
Examples:
(Assoc get 'tx-bytes (Host %interface-record "lo" (list 1 2 3 4 5 6 7 8 900))) => 900(Host %linux-interfaces)interfaces, from /proc/net/dev: two header lines, then NAME: and sixteen totals, received then sent. The first total may follow the colon with no space.
Returns: LIST — Interface records
(Host %darwin-interfaces)interfaces, as netstat -i reads them: the indexes from the RTM_IFINFO2 messages of sysctl CTL_NET PF_ROUTE 0 0 NET_RT_IFLIST2 0, then each interface’s struct ifmibdata from CTL_NET PF_LINK NETLINK_GENERIC IFMIB_IFDATA INDEX IFDATA_GENERAL. The routing messages’ own if_data64 counts bytes in 32 bits for a user without privileges; the ifmibdata’s counts are whole.
Returns: LIST — Interface records
(Host cpu)CPU time since boot across all processors, in nanoseconds: user nice system idle iowait irq softirq steal guest guest-nice. Linux reads /proc/stat’s cpu line; Darwin reads HOST_CPU_LOAD_INFO, which reports the first four. Differences between two readings give the percentages top shows.
Returns: ALIST — ((user . NS) (nice . NS) … (guest-nice . NS)); a field not reported is nil
(Host cpus)CPU time since boot for each processor, one record each in the kernel’s order, with cpu’s fields. Linux reads /proc/stat’s cpuN lines; Darwin reads host_processor_info’s PROCESSOR_CPU_LOAD_INFO, which reports user, nice, system and idle.
Returns: LIST — One cpu record a processor
(Host %cpu-record ticks)A cpu record from clock ticks: user nice system idle iowait irq softirq steal guest guest-nice, in nanoseconds. guest and guest-nice are also counted in user and nice, as the kernel counts them.
Parameters:
LIST — Tick counts in /proc/stat’s order; fewer than ten leave the rest nilReturns: ALIST — The cpu record
Examples:
(Assoc get 'user (Host %cpu-record (list (Host %hz)))) => 1000000000
(null? (Assoc get 'idle (Host %cpu-record (list 1 2)))) => #t(Host %darwin-cpu-ticks)host_processor_info’s PROCESSOR_CPU_LOAD_INFO ticks for each processor, in cpu’s order: user, nice, system, idle. The kernel hands back an array it allocated, which is returned to it with vm_deallocate.
Returns: LIST — Four tick counts a processor
(Host %darwin-ticks)HOST_CPU_LOAD_INFO’s ticks, in cpu’s order: user, nice, system, idle.
Returns: LIST — Four tick counts
(Host processes)Every process, one record each: pid ppid pgid sid uid gid ruid rgid state comm tty tty-major tty-minor nice start threads vsz rss utime stime processor. uid and gid are the effective ids, ruid and rgid the real ones. state is a Linux state letter (R S D T Z); start is unix seconds; vsz and rss are bytes; utime and stime are nanoseconds; tty is the terminal’s device number, nil for none, and tty-major and tty-minor its two halves as this kernel packs them; processor is the CPU it last ran on. Darwin answers state (unless zombie or stopped), threads, vsz, rss, utime and stime only for this user’s processes unless running as root, and reports no processor.
Returns: LIST — Process records
(Host process pid)One process’s record, as processes gives it, or nil when there is no such process.
Parameters:
INTEGER — Process IDReturns: ANY — A process record, or nil
(Host args pid)The process’s argument vector, or nil when the kernel will not give it: a kernel thread on Linux, another user’s process on Darwin.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of strings, or nil
(Host exe pid)The process’s executable, as an absolute path, or nil when the kernel will not give it. Linux reads the /proc/PID/exe link, which only the process’s owner or root may read; Darwin asks proc_pidpath, which answers for any process.
Parameters:
INTEGER — Process IDReturns: ANY — STRING, or nil
(Host threads pid)The process’s threads, one record each with the process record’s fields, pid the thread’s id and comm its name. Linux reads /proc/PID/task/TID/stat, so each thread’s state, CPU time and processor are its own; Darwin lists the threads with proc_pidinfo and reads each one’s state, name and CPU time, the other fields being the process’s, and answers only for this user’s processes unless running as root. nil when the process is gone or the kernel will not say.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of thread records, or nil
(Host %darwin-threads pid)threads, from proc_pidinfo: PROC_PIDLISTTHREADIDS for the ids, then PROC_PIDTHREADID64INFO for each thread’s struct proc_threadinfo.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of thread records, or nil
(Host maps pid)The process’s memory mappings, summed as BusyBox’s top -m sums /proc/PID/smaps, in bytes: mapped-rw and mapped-ro, the size of the writable mappings and of the readable or executable rest (a device mapping other than /dev/zero, and a —p guard gap, counted in neither); stack, the [stack] mapping’s size; and the resident shared-clean, shared-dirty, private-clean and private-dirty. Darwin walks the regions with proc_pidinfo’s PROC_PIDREGIONINFO, takes protection, the stack tag and the private and shared resident pages from the kernel, and counts a region’s dirtied pages as private for a private or copy-on-write region and shared otherwise; it answers only for this user’s processes unless running as root. nil when the process is gone or the kernel will not say.
Parameters:
INTEGER — Process IDReturns: ANY — ((mapped-ro . B) (mapped-rw . B) (stack . B) (shared-clean . B) (shared-dirty . B) (private-clean . B) (private-dirty . B)), or nil
(Host %maps-record v)The maps record for seven sums in its order.
Parameters:
LIST — mapped-ro mapped-rw stack shared-clean shared-dirty private-clean private-dirty, bytesReturns: ALIST — The maps record
Examples:
(Assoc get 'stack (Host %maps-record (list 1 2 3 4 5 6 7))) => 3(Host %linux-maps pid)maps, from /proc/PID/smaps, read a line at a time, BusyBox’s procps_read_smaps over the same lines.
Parameters:
INTEGER — Process IDReturns: ANY — The maps record, or nil
(Host %darwin-maps pid)maps, from proc_pidinfo’s PROC_PIDREGIONINFO, one struct proc_regioninfo a region from address 0 up.
Parameters:
INTEGER — Process IDReturns: ANY — The maps record, or nil
(Host files pid . uses)What the process has open, one record each: its current directory, its root, its executable, each file descriptor in descriptor order, and each file it maps. use is ‘cwd, ‘root, ‘exe, ‘fd or ‘map; fd is the descriptor’s number, nil for the others; dev and ino are the device and inode of what it holds; type is ‘file for a path and otherwise the kernel’s own word (‘socket ‘pipe ‘anon_inode on Linux; ‘socket ‘pipe ‘kqueue ‘pshm ‘psem ‘fsevents ‘netpolicy ‘channel ‘nexus on Darwin); name is the kernel’s name for it; id is the kernel’s number for a socket or pipe. An internet socket adds proto (‘tcp ‘udp ‘raw or ‘icmp), family (4 or 6) and port, its local port. Linux reads the /proc/PID cwd, root, exe and fd links and the maps lines, so a descriptor’s name is its link’s text whatever the type (socket:[INODE], anon_inode:[eventfd]), and joins a socket to /proc/net by its inode; Darwin asks proc_pidinfo and proc_pidfdinfo, names only a file, by its path, gives a socket its kernel handle as both id and ino, and reports a root only for a chrooted process. Only the process’s owner or root may read them. nil when the process is gone or the kernel will not say.
Parameters:
INTEGER — Process IDLIST — The uses to read, of ‘cwd ‘root ‘exe ‘fd ‘map; every one when none is namedReturns: ANY — LIST of file records, or nil
(Host %file-record use fd dev ino type name id inet)The files record for one thing a process has open.
Parameters:
SYMBOL — cwd root exe fd or mapANY — Descriptor, or nilANY — INTEGER, or nilANY — INTEGER, or nilANY — SYMBOL, or nilANY — STRING, or nilANY — INTEGER, or nilLIST — proto family port fields, or nilReturns: ALIST — The record
Examples:
(Assoc get 'fd (Host %file-record 'fd 3 () () 'pipe () 7 ())) => 3
(Assoc get 'id (Host %file-record 'fd 3 () () 'pipe () 7 ())) => 7(Host %file-set)A set of files by device and inode, for a walk that meets the same file many times: answers (seen? dev ino), #t when the pair was already given and #f the first time, when it is added. The pairs sit in one zeroed region of 16-byte slots, opened by address: a list scanned per region made a walk over Firefox’s 7,000 regions and 2,000 files quadratic. A table holding 16,384 files answers #f for any more.
Returns: CALLABLE — (seen? dev ino)
Examples:
((fn (_ seen?) (seen? 1 2)) (Host %file-set)) => #f
((fn (_ seen?) (seen? 1 2) (seen? 1 2)) (Host %file-set)) => #t(Host %dev-ino path)The device and inode stat(2) reports for path, or nil when it cannot be stat’d, read where the platform’s stat layout puts them.
Parameters:
STRING — A path, followed through linksReturns: ANY — PAIR (dev . ino), or nil
Examples:
(null? (Host %dev-ino "/nonexistent/file")) => #t(Host %linux-dev s)| The device number this platform’s makedev packs from a major and minor, so a maps line compares equal to stat(2)’s dev for the same file: glibc’s on Linux, major « 24 | minor on Darwin, where a spec runs the Linux reader over a fixture. |
Parameters:
STRING — MAJ:MIN in hexadecimal, as /proc/PID/maps writes itReturns: INTEGER — The device
Examples:
(Host %maps-dev (Host %linux-dev "08:01")) => "08:01"(Host %linux-sockets)The internet sockets /proc/net lists, by inode: an alist from each inode to its proto, family and local port, from tcp, udp, raw and icmp and their 6 twins. A table the kernel does not have is skipped.
Returns: ALIST — inode -> (proto family port) fields
(Host %linux-files pid uses)files, from the /proc/PID cwd, root, exe and fd links and the maps lines: a link to a path is a file; any other spells its type before a colon and, for a socket or pipe, its inode between brackets. dev and ino are stat(2)’s through the link.
Parameters:
INTEGER — Process IDLIST — The uses to readReturns: ANY — LIST of file records, or nil
(Host %darwin-files pid uses)files: proc_pidinfo’s PROC_PIDVNODEPATHINFO for the current and root directories, proc_pidpath for the executable, PROC_PIDLISTFDS for the descriptors, a struct proc_fdinfo (fd, type) each, then proc_pidfdinfo for a file’s struct vnode_fdinfowithpath or a socket’s struct socket_fdinfo or a pipe’s struct pipe_fdinfo, and PROC_PIDREGIONPATHINFO’s regions from address 0 up for the mapped files.
Parameters:
INTEGER — Process IDLIST — The uses to readReturns: ANY — LIST of file records, or nil
(Host holders path . mount?)The processes that hold a path: as their working directory, root or executable, through a descriptor or a mapping, in pid order; with mount? #t, those that hold anything on the path’s file system. Darwin asks the kernel, with proc_listpidspath (PROC_LISTPIDSPATH_PATH_IS_VOLUME for the file system); Linux reads each process’s files records and compares the device and inode. A process whose files this user may not read is not among them. nil when the path will not stat.
Parameters:
STRING — A path, followed through linksLIST — #t to ask for its whole file system insteadReturns: ANY — LIST of pids, or nil
(Host %darwin-holders path whole)holders, from proc_listpidspath over PROC_ALL_PIDS: the kernel walks each process’s descriptors, directories, text and mappings. The buffer has room for the process table proc_listpids reports, and a few hundred more.
Parameters:
STRING — A path that statsBOOL — Its file system rather than the pathReturns: LIST — Pids
(Host %linux-holders path whole)holders, from each /proc/PID: the cwd, root and exe links and the fd links stat’d, then the maps text searched for the path’s ` MAJ:MIN INODE ` (or with whole, ` MAJ:MIN `) as the kernel prints it, one strstr over the file. A process is read only as far as its first match.
Parameters:
STRING — A path that statsBOOL — Its file system rather than the pathReturns: LIST — Pids
(Host %maps-dev dev)The device as /proc/PID/maps prints it, MAJ:MIN in lower-case hexadecimal, two digits at least: %linux-dev read backwards, in this platform’s encoding.
Parameters:
INTEGER — A device number, as stat(2) reports itReturns: STRING — MAJ:MIN
Examples:
(Host %maps-dev (Host %linux-dev "fd:1a")) => "fd:1a"(Host regions pid)The process’s memory mappings one record a region, in address order, as BusyBox’s pmap reads /proc/PID/smaps: start, the region’s address, its 64 bits as a signed integer (negative in the top half of the address space, as Linux’s [vsyscall] is); size, its length in bytes; mode, four characters of permissions (r, w, x or a dash, then p for private or s for shared); name, the mapped file’s path or the kernel’s name for the region, nil for an anonymous one; and pss, private-dirty and swap in bytes. Darwin walks the regions with proc_pidinfo’s PROC_PIDREGIONPATHINFO, takes the path of the file a region maps, counts a region’s dirtied pages as private for a private or copy-on-write region, and reports no pss; it answers only for this user’s processes unless running as root. nil when the process is gone or the kernel will not say.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of ((start . ADDR) (size . B) (mode . STRING) (name . STRING) (pss . B) (private-dirty . B) (swap . B)), or nil
(Host %region-record v)The region record for seven fields in its order.
Parameters:
LIST — start size mode name pss private-dirty swapReturns: ALIST — The region record
Examples:
(Assoc get 'mode (Host %region-record (list 4096 8192 "r-xp" "/bin/sh" 0 0 0))) => "r-xp"(Host %linux-regions pid)regions, from /proc/PID/smaps, read a line at a time, BusyBox’s pmap over the same lines.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of region records, or nil
(Host %darwin-regions pid)regions, from proc_pidinfo’s PROC_PIDREGIONPATHINFO, one struct proc_regionwithpathinfo a region from address 0 up.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of region records, or nil
(Host %linux-btime)The boot time /proc/stat records, the base of a process’s start time.
Returns: INTEGER — Unix seconds
(Host %linux-processes)processes, from /proc/PID/stat; a process that exits mid-walk is left out.
Returns: LIST — Process records
(Host %linux-record btime name)One process’s record from /proc/PID/stat, or nil when it is gone.
Parameters:
INTEGER — Boot time, unix secondsSTRING — The pid, as its /proc directory is namedReturns: ANY — A process record, or nil
(Host %linux-record-at btime dir id)A record from a directory’s stat file, or nil when it is gone. comm is read between the first ( and the last ), since a name may hold either. A field past the end of a short line is nil.
Parameters:
INTEGER — Boot time, unix secondsSTRING — A /proc/PID or /proc/PID/task/TID directoryINTEGER — The pid or thread id the directory is named forReturns: ANY — A process record, or nil
(Host %owner path)The uid and gid owning a path, as BusyBox’s ps reads a process’s user and group.
Parameters:
STRING — A /proc/PID directoryReturns: ANY — PAIR (uid . gid), or nil
Examples:
(null? (Host %owner "/nonexistent/file")) => #t(Host %real-ids dir)The real uid and gid, the first number of /proc/PID/status’s Uid: and Gid: lines, as BusyBox’s ps reads ruser and rgroup.
Parameters:
STRING — A /proc/PID directoryReturns: ANY — PAIR (ruid . rgid), or nil
(Host %linux-args pid)args, from /proc/PID/cmdline: the strings between its NUL bytes, split as each read lands, since a string holding a NUL cannot be carried whole.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of strings, or nil
(Host %nul-split s from end most)The first most NUL-terminated strings between from and end.
Parameters:
STRING — Bytes holding NUL-terminated stringsINTEGER — Where to startINTEGER — Where to stopINTEGER — Most strings to takeReturns: LIST — Strings
Examples:
(Host %nul-split (bytes->str (list 97 0 98 99 0 100 0)) 0 7 2) => ("a" "bc")(Host %sysctl-mib mib n)A sysctl value by numeric name, as (region . length), or nil when the kernel refuses or answers nothing (no such process). With no size, the kernel is asked first, so the region is as large as the value and no larger.
Parameters:
LIST — The name as integersANY — Buffer size, or nil to ask the kernel how much the value needsReturns: ANY — PAIR (region . length), or nil
(Host %darwin-processes)processes, from kern.proc.all and proc_pidinfo. The table is asked for its size first and given room for a few more processes, since it can grow between the two calls.
Returns: LIST — Process records
(Host %darwin-ctx)What reading Darwin’s process records needs, fetched once a process rather than once a field: the pointer and conversion primitives, the type handles, proc_pidinfo, getsid and sysctl resolved, and the Mach timebase. Cached in ctx; the image recache hook clears it, since a resolved symbol is a fact of the process that resolved it.
Returns: LIST — (ref call make ->ptr proc_pidinfo getsid numer denom sysctl set! cvt string-type pointer-type integer-type byte-len byte-ref)
(Host %darwin-record b o ctx)One process’s record from its kinfo_proc row, with proc_pidinfo’s task info where the kernel gives it. state is Z or T from p_stat (SZOMB, SSTOP); otherwise p_stat reads SRUN for nearly every process, so R or S comes from the task info’s running-thread count, as Darwin’s ps decides it, and is nil where the task info is refused.
Parameters:
STRING — kinfo_proc rowsINTEGER — This row’s offsetLIST — What %darwin-ctx answersReturns: ALIST — A process record
(Host %darwin-args pid)args, from kern.procargs2: argc, the executable’s path, padding NULs, then the argc strings.
Parameters:
INTEGER — Process IDReturns: ANY — LIST of strings, or nil
(Host users)The logged-in sessions: utmp’s user-process entries, as BusyBox’s who and uptime count them: user tty host time pid. time is the login, in unix seconds.
Returns: LIST — Session records
(Host utmp)Every entry in libc’s utmpx database with a user name (setutxent/getutxent, as BusyBox’s who -a reads it): user tty host time pid type. type is the entry’s kind: run-level, boot-time, new-time, old-time, init-process, login-process, user-process, dead-process, accounting, signature or shutdown-time (the last two Darwin’s), or nil for one this table does not know. time is unix seconds.
Returns: LIST — Entry records