freebsd-apple-userland-cmds — per-repo, per-binary port auditA data-grounded audit of six Apple userland repos — bootstrap_cmds, file_cmds, shell_cmds, system_cmds, network_cmds, text_cmds — for the question "should we replace FreeBSD's version with Apple's?". Decision rule: port if Apple's version gives Mach IPC integration, libxpc/libdispatch/launchd integration, or a real feature advantage over the FreeBSD equivalent. Skip if there's no advantage. Tables grounded in direct source inspection by five parallel research agents over /Users/jmaloney/Documents/launchd/{bootstrap,file,shell,system,network,text}_cmds/. Tools install at their Apple-canonical paths; FreeBSD-runtime stays installed and we overwrite the conflict paths.
/System/Library/Tools/, no /usr/local/sbin/, no PATH-shadowing. Apple's ifconfig goes at /sbin/ifconfig.FreeBSD-runtime owns the conflict paths. The live ISO never pkg upgrades; dev machines must be aware.FreeBSD-runtime provides that we have no Apple replacement forEven after the 28-binary port list lands and overwrites every conflict path, FreeBSD-runtime still carries roughly five categories of tools we depend on. None of these has a viable Apple-source replacement on FreeBSD — Apple's equivalents either don't exist, target HFS+/APFS only, or use macOS-kernel-specific interfaces that don't translate.
| Category | Tools still needed from FreeBSD-runtime | Why no Apple replacement |
|---|---|---|
| Filesystem mount & check | mount, umount, mount_nullfs, mount_unionfs, mount_tmpfs, mount_devfs, mount_nfs, mount_msdosfs, mount_cd9660, fsck, fsck_ffs, fsck_msdosfs, newfs, newfs_msdos, tunefs | Apple's system_cmds equivalents target HFS+/APFS via Apple's VFS layer. FreeBSD uses UFS / ZFS / unionfs / nullfs — entirely different kernel interfaces. No code reuse possible. |
| Kernel module management | kldload, kldunload, kldstat, kldconfig, kldxref | Apple uses kexts via kextload / kextunload against a fundamentally different module-loading kernel API. FreeBSD's klds are FreeBSD-only. Critical for boot — mach.ko itself is loaded via kldload. |
| Storage glue | swapon, swapoff, mdconfig, mdmfs, gpart, geom, devfs, dumpon, savecore | FreeBSD-specific subsystems: GEOM stack, devfs rulesets, memory-disk framework, swap layout, dump format. Apple has no equivalents that target these subsystems. |
| Boot & init (until Phase I3) | init, halt * | init stays until launchd-842 is PID 1 (Phase I3). halt we don't port from system_cmds — Apple's wraps Apple-specific power-mgmt; FreeBSD's is enough. reboot + shutdown ARE in our PORT list (system_cmds, with launchd-coordination + IOPMLib stubs). |
| Networking we explicitly didn't port | dhclient, mountd, nfsd, nfsiod, traceroute, traceroute6, rtsold | dhclient is FreeBSD's DHCP client; Apple's equivalent is IPConfiguration (separate daemon, separate phase). NFS stack is FreeBSD-only. traceroute(6) Apple versions audit SKIP (no Apple-specific feature). |
| POSIX file ops we audit-skipped | chflags, chown, dd, ipcrm, ipcs, ln, mkdir, mkfifo, mknod, rm, rmdir, shar, stat, touch, truncate | Apple's file_cmds versions have zero integration advantage; FreeBSD's are equivalent. We deliberately don't port these (see §4). |
| POSIX shell tools we audit-skipped | basename, chroot, date, dirname, echo, env, expr, false, find, getopt, hexdump, hostname, jot, kill, mktemp, nice, nohup, printenv, printf, pwd, realpath, renice, script, seq, sleep, tee, test, time, true, tty, uname, users, w, who, xargs, yes | Same — Apple's shell_cmds for these have no Apple-stack integration. FreeBSD's are equivalent. We deliberately don't port these (see §5). |
| Tracing / introspection FreeBSD does its own way | ktrace, kdump, top, vmstat, iostat, ps, pstat, systat, dtrace, dtraceopt, dmesg | Apple's analogues (fs_usage, sc_usage, latency) audit SKIP — they depend on Apple's kdebug infrastructure. FreeBSD has dtrace; replicating kdebug is not worth it. |
* FreeBSD-rc is a separate pkg, not part of FreeBSD-runtime. We keep it for Phases I1/I2 (since FreeBSD's init still calls /etc/rc). Phase I3+ drops FreeBSD-rc when launchd-842 plists own multi-user bring-up.
Bottom line: FreeBSD-runtime isn't going anywhere. Filesystem glue, GEOM, kld, swap, dump, NFS, and the ~40 plain-POSIX tools we audit-skipped all live there. The pkg is doing real work post-port; the conflict overwrites only displace ~17 of its ~200+ files.
| Repo | Binaries total | PORT | PARTIAL | SKIP | Net "advantage" driver |
|---|---|---|---|---|---|
bootstrap_cmds | ~4 files | 4 | 0 | 0 | MIG. Pre-req for launchd-842 + every future MIG-using daemon. |
file_cmds | 27 | 7 | 3 | 17 | ACL + xattr + clonefile + fcopyfile preservation across cp/mv/ls/etc. |
shell_cmds | ~45 | 2 | 2 | ~41 | Open Directory (id), BSM audit (su). |
system_cmds | ~40 | 4 | 5 | ~31 | Mach IPC introspection (lsmp/hostinfo/stackshot) + IOKit NVRAM. |
network_cmds | 15 | 10 | 1 | 4 | SystemConfiguration parity, IFSCOPE routing, LQM, IPv6 secure ND. |
text_cmds | 34 | 1 | 0 | 33 | Only sort uses Mach semaphores for parallel sorting. |
| Total | ~165 | 28 | 11 | ~126 | — |
Roughly 17% of Apple's userland is worth replacing on FreeBSD. The remaining 83% is BSD-derived plain-POSIX code with no integration advantage; FreeBSD's existing versions are as good or better.
bootstrap_cmds — install table| Apple binary | Source path | FreeBSD path today | Install path | Conflict |
|---|---|---|---|---|
mig | xcodescripts/install-mig.sh | (not present) | /usr/bin/mig | none |
migcom | migcom.tproj/ | (not present) | /usr/libexec/migcom | none |
mig.1, migcom.1 | migcom.tproj/*.1 | (not present) | /usr/share/man/man1/ | none |
Zero conflicts; pure addition. Smoke marker: MIG-BUILD-OK — mig --help exits 0, migcom emits help on stderr. Once installed, generate the seven launchd-842 .defs stubs into a vendored mig-output/ tree.
file_cmds audit| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | Verdict |
|---|---|---|---|---|
cp | fcopyfile, clonefile, ACL + xattr (cp/utils.c:138-491) | APFS clonefile COW; resource-fork + ACL preservation | /bin/cp | PORT |
chmod | Apple libacl (chmod_acl.c:121-854) | Extended ACL manipulation (ACL_EXTENDED_ALLOW/DENY) | /bin/chmod | PORT |
ls | getxattr, acl_get_link_np, SF_DATALESS (ls/ls.c:1113-1147) | ACL display (-e), xattr count, dataless-file awareness | /bin/ls | PORT |
mv | fcopyfile for ACL+xattr (mv/mv.c:443) | Cross-FS move preserves permissions+xattr | /bin/mv | PORT |
install | fcopyfile ACL+xattr (install/xinstall.c:1201-1203) | ACL preservation in install(1) | /usr/bin/install | PORT |
gzip | fgetattrlist, fsetattrlist, fcopyfile (gzip/gzip.c:1385-1507) | Preserves ACLs+xattrs across compression | /usr/bin/gzip | PORT |
pax | fcopyfile, setattrlist (pax/file_subs.c:845-852) | Precise timestamp + ACL+xattr in archives | /bin/pax | PORT |
df | getattrlist for ATTR_VOL_SPACEUSED (df/df.c:542-553) | Volume metadata without traversal | /bin/df | PARTIAL |
du | getattrlist for SF_DATALESS (du/du.c:595) | Accurate dataless-file accounting | /usr/bin/du | PARTIAL |
mtree | libdispatch (mtree/commoncrypto.c:35-84) | GCD-parallel hashing | /usr/sbin/mtree | PARTIAL |
| 17 others chflags, chown, cksum, compress, dd, ipcrm, ipcs, ln, mkdir, mkfifo, mknod, pathchk, rm, rmdir, shar, stat, touch, truncate, xattr | None | Standard POSIX | various | SKIP |
Driver: Apple's cp/mv/ls/install/gzip/pax preserve ACLs + extended attributes + APFS clonefile semantics through file operations. FreeBSD's POSIX.1e ACLs and extattr(2) overlap but the userland tools don't preserve them uniformly. Porting the seven essentials makes the toolchain Apple-metadata-aware.
Risks: libacl + libdispatch dependencies for chmod/ls/install/mtree. clonefile(2) is APFS-only; Apple's cp falls back to byte-copy on non-clone-capable filesystems — benign on FreeBSD's UFS/ZFS. xattr the tool is SKIP because Apple's xattr(2) API diverges from FreeBSD's extattr(2) too sharply; the wrapper underneath libxpc/launchd uses Apple's API directly so we ship a shim there, not here.
shell_cmds audit| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | Verdict |
|---|---|---|---|---|
id | CoreFoundation + Open Directory (id/open_directory.c:11-93) | OD-backed identity lookups for enterprise LDAP/NIS | /usr/bin/id | PORT |
su | BSM audit session (su.c:219-222; bsm/audit_session.h) | Audit-session-aware privilege escalation | /usr/bin/su | PORT |
path_helper | None (file I/O only) | Reads /etc/paths + /etc/paths.d/ to build PATH | (not present) | PARTIAL |
killall | KERN_PROCARGS2 sysctl (killall.c:414) | Full-argv match vs FreeBSD's truncated ki_comm | /usr/bin/killall | PARTIAL |
| ~40 others basename, chroot, date, dirname, echo, env, expr, false, find, getopt, hexdump, hostname, jot, kill, lastcomm, lockf, logname, mktemp, nice, nohup, printenv, printf, pwd, realpath, renice, script, seq, sh, shlock, sleep, stdbuf, tee, test, time, true, tty, uname, w, who, xargs, yes, … | None | Standard POSIX | various | SKIP |
Driver: two narrow wins. id grows enterprise-directory awareness (Open Directory); su grows BSM audit-session tracking. Everything else is plain BSD/POSIX with no integration value.
Risk callout: Apple id requires libopendirectory, which has no FreeBSD equivalent. Two paths: (a) ship a no-op libopendirectory shim and let id fall back to /etc/passwd; (b) defer the id port until Open Directory or an equivalent enterprise-directory shim lands. Recommendation: ship the no-op shim and defer real OD work to a separate phase.
system_cmds auditThis is the most Mach-IPC-heavy of the six repos. The PORT candidates require kernel-side mach.ko work; the SKIP list calls out which tools depend on Apple's kdebug infrastructure (FreeBSD has dtrace instead) and aren't worth replicating.
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | Verdict |
|---|---|---|---|---|
lsmp | Mach IPC introspection (task_read_for_pid, mach_port_space_info, host_processor_sets) | Mach port enumeration — no FreeBSD equivalent | (not present) | PORT |
hostinfo | Mach: host_info HOST_BASIC_INFO, processor sets (hostinfo.c:65-104) | Reports Mach kernel version, processor-set state | (not present) | PORT |
nvram | IOKit (IORegistry, IORegistryEntryCreateCFProperty) | Firmware-parameter R/W via IOKit | (not present) | PORT |
stackshot | Mach + stackshot syscall | Kernel stack snapshots | (not present) | PORT |
lskq | EVFILT_MACHPORT in kqueue (lskq.c:100) | Mach-aware kqueue analysis | /usr/bin/lskq | PARTIAL |
reboot | Bootstrap + IOKit kextmanager (reboot.c:67-75) | launchd-coordinated reboot, kext locking | /sbin/reboot | PARTIAL |
shutdown | IOKit IOPMLib + BSM audit (shutdown.c:64-66, 838) | Power-management-aware shutdown, audit-logged | /sbin/shutdown | PARTIAL |
gcore | Mach-image introspection | Core dumps with Mach thread-state notes | /usr/bin/gcore | PARTIAL |
login | BSM audit (bsm/audit_session.h) | Audit-aware session creation | /bin/login | PARTIAL |
taskpolicy | Mach task_policy_set/get | QoS + CPU-limit management | /usr/bin/taskpolicy | PARTIAL |
fs_usage, sc_usage, latency | kdebug + Mach timing | kdebug-based tracing | various | SKIP |
kpgo, memory_pressure, vm_stat, vm_purgeable_stat | Apple-only kernel features (PGO, jetsam, purgeable VM) | n/a on FreeBSD | various | SKIP |
| ~25 others arch, at, atrun, accton, chpass, cpuctl, dmesg, dynamic_pager, getconf, getty, hostinfo*, iostat, mean, mkfile, newgrp, nologin, passwd, pagesize, proc_uuid_policy, purge, sa, sync, sysctl, vipw, wait4path, zdump, zic, zlog, zprint, … | None or trivial | Standard POSIX | various | SKIP |
Kernel-side mach.ko work this implies. Porting the four strong PORTs requires new mach.ko traps:
lsmp → task_read_for_pid, mach_port_space_info, host_processor_sets, processor_set_tasks_with_flavor (4 new traps)hostinfo → host_info HOST_BASIC_INFO flavor + processor info (1 new trap, multiple flavors)stackshot → kernel stackshot syscall (1 new syscall, large)nvram → IOKit NVRAM driver (different track entirely; EFI device-tree walker)The first three fit our existing multiplexer slot 219 pattern. IOKit NVRAM is its own subsystem and probably waits.
network_cmds auditHighest port ratio of any repo — 10 of 15. Not because these tools have heavy Mach integration (they don't), but because they're the system-of-record for network state that configd will read. Apple's struct layouts and tool output formats differ from FreeBSD's; for configd to work later, these tools must produce Apple-shaped output.
| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | Verdict |
|---|---|---|---|---|
ifconfig | IFEF_* flags, LQM (ifconfig.c:2090-3036) | AWDL/cellular/companion interface types, LQM quality state | /sbin/ifconfig | PORT |
route | RTF_IFSCOPE parsing (route.c:130, 814-818, 1776-1778) | Interface-scoped routes, RTF_PINNED/RTF_IFREF | /sbin/route | PORT |
arp | IFSCOPE, IFNET_LQM_THRESH_* (arp.c:1127-1136) | Interface-scoped ARP for multi-homed mDNS | /usr/sbin/arp | PORT |
ndp | ND6_IFF_* flags, prefix list sysctl | SEND (secure ND), proxy prefixes, NUD state machine | /usr/sbin/ndp | PORT |
ping | IP_NO_IFT_CELLULAR, DSCP marking (ping.c:754-756) | Cellular exclusion, QoS class | /sbin/ping | PORT |
ping6 | IPV6_NO_IFT_CELLULAR, DSCP marking (ping6.c:850-852) | IPv6 variant of ping with cellular/QoS | /sbin/ping6 (symlink) | PORT |
rtadvd | RDNSS/DNSSL + PVD config | IPv6 prefix advertisement with Apple extras | /usr/sbin/rtadvd | PORT |
rtsol | IPv6 router-solicitation daemon | Auto IPv6 prefix solicitation | /usr/sbin/rtsold | PORT |
kdumpd | launchd plist + socket activation | Establishes launchd-managed-daemon pattern | (not present) | PORT |
netstat | LQM thresholds, NSTAT cellular link status (if.c:1328-2261) | LQM + cellular display | /usr/bin/netstat | PARTIAL |
traceroute | None | None Apple-specific | /usr/sbin/traceroute | SKIP |
traceroute6 | None | None Apple-specific | /usr/sbin/traceroute6 | SKIP |
dnctl | Apple dummynet control | Apple-specific QoS scheduling | (not present; FreeBSD-ipfw omitted) | SKIP |
rarpd | None | Legacy RARP server | (not present) | SKIP |
spray | None | Sun-RPC bandwidth measurement | (not present) | SKIP |
Driver: SystemConfiguration parity. configd's job — coming in a later phase — is to read ifconfig -a, route -n get, ndp -pr, arp -a, netstat -i output and turn it into the SC store. Those tools have to emit Apple-shaped state, or configd's parser breaks. kdumpd's launchd plist is independently useful: it's the worked example for launchd-managed-socket-activation we'll copy when we add ntpd, mDNSResponder, etc.
text_cmds audit| Binary | Apple-stack integration | Apple-specific feature | FreeBSD path | Verdict |
|---|---|---|---|---|
sort | Mach semaphores (sort/file.c:140-159) | Multi-threaded sort via Mach IPC | /usr/bin/sort | PORT |
| 33 others banner, bintrans, cat, col, colrm, column, comm, csplit, cut, ed, expand, fmt, fold, grep, head, jq, join, lam, look, md5, nl, paste, pr, rev, rs, sed, split, tail, tr, ul, unexpand, uniq, unvis, vis, wc, … | None — pure POSIX stream processors | Locale and encoding edge cases only | various | SKIP |
Driver: sort alone uses Mach semaphores for parallelism. Everything else is BSD stream processing with no integration story.
28 binaries to port across all six repos, ordered by where they land in the build pipeline:
| # | Binary | Source repo | Install path | Conflict pkg |
|---|---|---|---|---|
| 1 | mig | bootstrap_cmds | /usr/bin/mig | — |
| 2 | migcom | bootstrap_cmds | /usr/libexec/migcom | — |
| 3 | arp | network_cmds | /usr/sbin/arp | FreeBSD-runtime |
| 4 | ifconfig | network_cmds | /sbin/ifconfig | FreeBSD-runtime |
| 5 | ndp | network_cmds | /usr/sbin/ndp | FreeBSD-runtime |
| 6 | netstat (PARTIAL) | network_cmds | /usr/bin/netstat | FreeBSD-runtime |
| 7 | ping | network_cmds | /sbin/ping | FreeBSD-runtime |
| 8 | ping6 | network_cmds | /sbin/ping6 | FreeBSD-runtime |
| 9 | route | network_cmds | /sbin/route | FreeBSD-runtime |
| 10 | rtadvd | network_cmds | /usr/sbin/rtadvd | FreeBSD-runtime |
| 11 | rtsol | network_cmds | /usr/sbin/rtsol | none (name differs from FreeBSD's rtsold) |
| 12 | kdumpd | network_cmds | /usr/libexec/kdumpd | — |
| 13 | cp | file_cmds | /bin/cp | FreeBSD-runtime |
| 14 | chmod | file_cmds | /bin/chmod | FreeBSD-runtime |
| 15 | ls | file_cmds | /bin/ls | FreeBSD-runtime |
| 16 | mv | file_cmds | /bin/mv | FreeBSD-runtime |
| 17 | install | file_cmds | /usr/bin/install | FreeBSD-utilities |
| 18 | gzip | file_cmds | /usr/bin/gzip | FreeBSD-utilities |
| 19 | pax | file_cmds | /bin/pax | FreeBSD-runtime |
| 20 | id | shell_cmds | /usr/bin/id | FreeBSD-utilities |
| 21 | su | shell_cmds | /usr/bin/su | FreeBSD-utilities |
| 22 | lsmp | system_cmds | /usr/bin/lsmp | — |
| 23 | hostinfo | system_cmds | /usr/bin/hostinfo | — |
| 24 | nvram | system_cmds | /usr/sbin/nvram | — |
| 25 | stackshot | system_cmds | /usr/bin/stackshot | — |
| 26 | reboot (PARTIAL) | system_cmds | /sbin/reboot | FreeBSD-runtime |
| 27 | shutdown (PARTIAL) | system_cmds | /sbin/shutdown | FreeBSD-runtime |
| 28 | sort | text_cmds | /usr/bin/sort | FreeBSD-utilities |
Conditional PARTIALs deferred until after the first 28 are stable: df, du, mtree (file_cmds); path_helper, killall (shell_cmds); lskq, gcore, taskpolicy, login (system_cmds).
build.shpkg install the pkgbase set (current behavior; FreeBSD-runtime + FreeBSD-utilities land here).bootstrap_cmds; install mig + migcom. Marker: MIG-BUILD-OK.mig against the seven launchd-842 .defs files; cache output in src/launchd/mig-output/.network_cmds tools (10 binaries). One smoke marker per tool: NETCMD-IFCONFIG-OK, NETCMD-PING-OK, NETCMD-ROUTE-OK, …file_cmds tools (7 binaries). Markers: FILECMD-CP-OK, …shell_cmds tools (id, su). Ship a no-op libopendirectory shim so id falls back to /etc/passwd.system_cmds tools that don't need new kernel traps yet. Defer lsmp / hostinfo / stackshot until the mach.ko-side traps land.sort from text_cmds. Last because it adds Mach-semaphore use to a generic stream tool — isolation matters.Worst in ifconfig, netstat, route, arp, ndp. Apple extends struct ifreq, struct ifmediareq, struct rt_msghdr; some Apple ioctls don't exist on FreeBSD. Apple-only feature paths will fail gracefully (ioctl returns -1, flag never set) — acceptable.
idApple's id calls libopendirectory. FreeBSD has no equivalent. Ship a no-op shim; id falls back to /etc/passwd like FreeBSD's. Real OD work is a separate, far-future phase.
4 new traps for lsmp + hostinfo + stackshot (port-space introspection, host info flavors, stackshot syscall). All fit the multiplexer slot 219 pattern; ~600 LOC of mach.ko work. nvram needs an IOKit NVRAM driver — separate track, much bigger.
Same caveat as before. The ISO never pkg upgrades; dev machines run the overwrite step manually after upgrades.
cp --reflink semanticsApple cp uses clonefile(2) automatically on supported filesystems. On FreeBSD UFS this no-ops to byte-copy. On ZFS we might want it to call zfs_clone_range eventually; not required.
mtree + sortBoth use libdispatch. We already ship /usr/lib/system/libdispatch.so, so this is free.
FreeBSD-rc removal. Once launchd-842 is PID 1, its plists own multi-user bring-up. Drop the pkg then. Gershwin Phase 2 reference./sbin/init replacement. Overwrite with launchd-842 binary or symlink. Same overwrite-after-install model.nvram; separate kernel-side track.id, login, auth. Months of work.id; the real one waits for OD.fs_usage, latency, sc_usage all SKIP. FreeBSD has dtrace; replicating kdebug is not worth it.Drafted 2026-05-13 from five parallel agent passes across /Users/jmaloney/Documents/launchd/{bootstrap,file,shell,system,network,text}_cmds/. Companion to the launchd-842 port plan. All file:line citations link back to the verbatim Apple sources.