From 1b0b27f8d1026de7c98116296b4432261088b24c Mon Sep 17 00:00:00 2001 From: Eirikr Hinngart <151315375+Oichkatzelesfrettschen@users.noreply.github.com> Date: Sat, 31 May 2025 20:20:57 -0700 Subject: [PATCH] Remove remaining NetBSD references --- bsd_tree.txt | 2945 +++++++++++++++++ minix/commands/cdprobe/Makefile | 5 - minix/commands/crontab/Makefile | 12 - minix/commands/fetch/fetch.c | 1131 ------- minix/commands/fsck.mfs/Makefile | 8 - minix/commands/partition/Makefile | 8 - minix/commands/writeisofs/Makefile | 6 - minix/drivers/bus/pci/Makefile | 26 - minix/drivers/eeprom/cat24c256/Makefile | 10 - minix/drivers/net/ip1000/Makefile | 14 - minix/drivers/net/rtl8139/Makefile | 16 - minix/drivers/net/rtl8169/Makefile | 16 - minix/drivers/net/vt6105/Makefile | 14 - minix/drivers/power/tps65217/Makefile | 10 - minix/drivers/power/tps65950/Makefile | 10 - minix/drivers/sensors/bmp085/Makefile | 15 - minix/drivers/sensors/sht21/Makefile | 15 - minix/drivers/sensors/tsl2550/Makefile | 15 - minix/drivers/storage/memory/Makefile | 37 - minix/drivers/storage/ramdisk/Makefile | 218 -- minix/drivers/system/random/Makefile | 16 - minix/drivers/tty/tty/Makefile | 17 - minix/drivers/tty/tty/keymaps/Makefile | 27 - minix/drivers/video/tda19988/Makefile | 10 - minix/fs/procfs/Makefile | 14 - minix/include/minix/driver.h | 43 - minix/include/minix/drivers.h | 45 - minix/kernel/Makefile | 113 - minix/kernel/arch/earm/Makefile.inc | 98 - minix/kernel/arch/i386/Makefile.inc | 126 - minix/lib/libmagicrt/Makefile | 79 - minix/lib/libminc/Makefile | 346 -- minix/lib/libminc/arch/earm/Makefile.libc.inc | 111 - minix/lib/libsockdriver/sockdriver.c | 1150 ------- minix/lib/libsockevent/Makefile | 9 - minix/servers/ipc/inc.h | 66 - minix/servers/ipc/main.c | 284 -- minix/servers/ipc/sem.c | 888 ----- minix/servers/ipc/shm.c | 469 --- minix/servers/is/Makefile | 21 - minix/servers/mib/Makefile | 21 - minix/servers/mib/kern.c | 508 --- minix/servers/mib/main.c | 492 --- minix/servers/mib/mib.h | 390 --- minix/servers/mib/proc.c | 1288 ------- minix/servers/mib/tree.c | 1842 ----------- minix/servers/mib/vm.c | 154 - minix/servers/pm/Makefile | 17 - minix/servers/pm/getset.c | 223 -- minix/servers/rs/Makefile | 20 - minix/servers/vfs/path.c | 933 ------ minix/servers/vfs/stadir.c | 446 --- minix/servers/vm/Makefile | 33 - minix/usr.bin/trace/Makefile | 25 - 54 files changed, 2945 insertions(+), 11910 deletions(-) create mode 100644 bsd_tree.txt delete mode 100644 minix/commands/cdprobe/Makefile delete mode 100644 minix/commands/crontab/Makefile delete mode 100644 minix/commands/fetch/fetch.c delete mode 100644 minix/commands/fsck.mfs/Makefile delete mode 100644 minix/commands/partition/Makefile delete mode 100644 minix/commands/writeisofs/Makefile delete mode 100644 minix/drivers/bus/pci/Makefile delete mode 100644 minix/drivers/eeprom/cat24c256/Makefile delete mode 100644 minix/drivers/net/ip1000/Makefile delete mode 100644 minix/drivers/net/rtl8139/Makefile delete mode 100644 minix/drivers/net/rtl8169/Makefile delete mode 100644 minix/drivers/net/vt6105/Makefile delete mode 100644 minix/drivers/power/tps65217/Makefile delete mode 100644 minix/drivers/power/tps65950/Makefile delete mode 100644 minix/drivers/sensors/bmp085/Makefile delete mode 100644 minix/drivers/sensors/sht21/Makefile delete mode 100644 minix/drivers/sensors/tsl2550/Makefile delete mode 100644 minix/drivers/storage/memory/Makefile delete mode 100644 minix/drivers/storage/ramdisk/Makefile delete mode 100644 minix/drivers/system/random/Makefile delete mode 100644 minix/drivers/tty/tty/Makefile delete mode 100644 minix/drivers/tty/tty/keymaps/Makefile delete mode 100644 minix/drivers/video/tda19988/Makefile delete mode 100644 minix/fs/procfs/Makefile delete mode 100644 minix/include/minix/driver.h delete mode 100644 minix/include/minix/drivers.h delete mode 100644 minix/kernel/Makefile delete mode 100644 minix/kernel/arch/earm/Makefile.inc delete mode 100644 minix/kernel/arch/i386/Makefile.inc delete mode 100644 minix/lib/libmagicrt/Makefile delete mode 100644 minix/lib/libminc/Makefile delete mode 100644 minix/lib/libminc/arch/earm/Makefile.libc.inc delete mode 100644 minix/lib/libsockdriver/sockdriver.c delete mode 100644 minix/lib/libsockevent/Makefile delete mode 100644 minix/servers/ipc/inc.h delete mode 100644 minix/servers/ipc/main.c delete mode 100644 minix/servers/ipc/sem.c delete mode 100644 minix/servers/ipc/shm.c delete mode 100644 minix/servers/is/Makefile delete mode 100644 minix/servers/mib/Makefile delete mode 100644 minix/servers/mib/kern.c delete mode 100644 minix/servers/mib/main.c delete mode 100644 minix/servers/mib/mib.h delete mode 100644 minix/servers/mib/proc.c delete mode 100644 minix/servers/mib/tree.c delete mode 100644 minix/servers/mib/vm.c delete mode 100644 minix/servers/pm/Makefile delete mode 100644 minix/servers/pm/getset.c delete mode 100644 minix/servers/rs/Makefile delete mode 100644 minix/servers/vfs/path.c delete mode 100644 minix/servers/vfs/stadir.c delete mode 100644 minix/servers/vm/Makefile delete mode 100644 minix/usr.bin/trace/Makefile diff --git a/bsd_tree.txt b/bsd_tree.txt new file mode 100644 index 000000000..04c38daaa --- /dev/null +++ b/bsd_tree.txt @@ -0,0 +1,2945 @@ +./.DS_Store +./.github/workflows/c-cpp.yml +./.github/workflows/cmake-multi-platform.yml +./.gitignore +./.gitreview +./LICENSE +./bsd_tree.txt +./minix/.DS_Store +./minix/Makefile +./minix/Makefile.inc +./minix/commands/DESCRIBE/DESCRIBE.sh +./minix/commands/DESCRIBE/Makefile +./minix/commands/MAKEDEV/MAKEDEV.8 +./minix/commands/MAKEDEV/MAKEDEV.sh +./minix/commands/MAKEDEV/Makefile +./minix/commands/Makefile +./minix/commands/Makefile.inc +./minix/commands/at/Makefile +./minix/commands/at/at.1 +./minix/commands/at/at.c +./minix/commands/atnormalize/Makefile +./minix/commands/atnormalize/atnormalize.8 +./minix/commands/atnormalize/atnormalize.c +./minix/commands/autopart/Makefile +./minix/commands/autopart/autopart.8 +./minix/commands/autopart/autopart.c +./minix/commands/backup/Makefile +./minix/commands/backup/backup.8 +./minix/commands/backup/backup.c +./minix/commands/cawf/Makefile +./minix/commands/cawf/README +./minix/commands/cawf/bsfilt.1 +./minix/commands/cawf/bsfilt.c +./minix/commands/cawf/cawf.1 +./minix/commands/cawf/cawf.c +./minix/commands/cawf/cawf.h +./minix/commands/cawf/cawflib.h +./minix/commands/cawf/common +./minix/commands/cawf/device.c +./minix/commands/cawf/device.cf +./minix/commands/cawf/diffs +./minix/commands/cawf/dumb.dev +./minix/commands/cawf/error.c +./minix/commands/cawf/expand.c +./minix/commands/cawf/expr.c +./minix/commands/cawf/getopt.c +./minix/commands/cawf/macsup.c +./minix/commands/cawf/man.mac +./minix/commands/cawf/me.mac +./minix/commands/cawf/mnx.mac +./minix/commands/cawf/ms.mac +./minix/commands/cawf/nreq.c +./minix/commands/cawf/output.c +./minix/commands/cawf/pass2.c +./minix/commands/cawf/pass3.c +./minix/commands/cawf/proto.h +./minix/commands/cawf/regerror.c +./minix/commands/cawf/regexp.c +./minix/commands/cawf/regexp.h +./minix/commands/cawf/regmagic.h +./minix/commands/cawf/store.c +./minix/commands/cawf/string.c +./minix/commands/cdprobe/cdprobe.8 +./minix/commands/cdprobe/cdprobe.c +./minix/commands/cleantmp/Makefile +./minix/commands/cleantmp/cleantmp.8 +./minix/commands/cleantmp/cleantmp.c +./minix/commands/compress/Makefile +./minix/commands/compress/compress.1 +./minix/commands/compress/compress.c +./minix/commands/crc/Makefile +./minix/commands/crc/crc.1 +./minix/commands/crc/crc.c +./minix/commands/cron/Makefile +./minix/commands/cron/cron.8 +./minix/commands/cron/cron.c +./minix/commands/cron/misc.c +./minix/commands/cron/misc.h +./minix/commands/cron/tab.c +./minix/commands/cron/tab.h +./minix/commands/crontab/crontab.1 +./minix/commands/crontab/crontab.c +./minix/commands/devmand/devmand.cfg +./minix/commands/devmand/main.c +./minix/commands/devmand/proto.h +./minix/commands/devmand/usb.y +./minix/commands/devmand/usb_driver.h +./minix/commands/devmand/usb_scan.l +./minix/commands/devsize/Makefile +./minix/commands/devsize/devsize.8 +./minix/commands/devsize/devsize.c +./minix/commands/dhrystone/Makefile +./minix/commands/dhrystone/dhrystone.1 +./minix/commands/dhrystone/dhrystone.c +./minix/commands/dosread/Makefile +./minix/commands/dosread/dosdir.1 +./minix/commands/dosread/dosread.1 +./minix/commands/dosread/dosread.c +./minix/commands/dosread/doswrite.1 +./minix/commands/eject/Makefile +./minix/commands/eject/eject.1 +./minix/commands/eject/eject.c +./minix/commands/fdisk/Makefile +./minix/commands/fdisk/fdisk.8 +./minix/commands/fdisk/fdisk.c +./minix/commands/fetch/Makefile +./minix/commands/fix/Makefile +./minix/commands/fix/fix.8 +./minix/commands/fix/fix.c +./minix/commands/format/Makefile +./minix/commands/format/format.1 +./minix/commands/format/format.c +./minix/commands/fsck.mfs/fsck.c +./minix/commands/fsck.mfs/fsck.mfs.1 +./minix/commands/gcov-pull/Makefile +./minix/commands/gcov-pull/gcov-pull.c +./minix/commands/ifdef/Makefile +./minix/commands/ifdef/ifdef.1 +./minix/commands/ifdef/ifdef.c +./minix/commands/intr/Makefile +./minix/commands/intr/intr.8 +./minix/commands/intr/intr.c +./minix/commands/isoread/Makefile +./minix/commands/isoread/isodir.1 +./minix/commands/isoread/isoinfo.1 +./minix/commands/isoread/isoread.1 +./minix/commands/isoread/isoread.c +./minix/commands/loadfont/Makefile +./minix/commands/loadfont/loadfont.1 +./minix/commands/loadfont/loadfont.c +./minix/commands/loadkeys/Makefile +./minix/commands/loadkeys/loadkeys.1 +./minix/commands/loadkeys/loadkeys.c +./minix/commands/loadramdisk/Makefile +./minix/commands/loadramdisk/loadramdisk.8 +./minix/commands/loadramdisk/loadramdisk.c +./minix/commands/look/Makefile +./minix/commands/look/look.1 +./minix/commands/look/look.c +./minix/commands/lp/Makefile +./minix/commands/lp/lp.1 +./minix/commands/lp/lp.c +./minix/commands/lpd/Makefile +./minix/commands/lpd/lpd.c +./minix/commands/lspci/Makefile +./minix/commands/lspci/lspci.1 +./minix/commands/lspci/lspci.sh +./minix/commands/mail/Makefile +./minix/commands/mail/mail.1 +./minix/commands/mail/mail.c +./minix/commands/minix-service/Makefile +./minix/commands/minix-service/config.h +./minix/commands/minix-service/minix-service.8 +./minix/commands/minix-service/minix-service.c +./minix/commands/minix-service/parse.c +./minix/commands/minix-service/parse.h +./minix/commands/minix-service/print.c +./minix/commands/minix-service/proto.h +./minix/commands/minix-service/system.conf.5 +./minix/commands/minix-service/util.c +./minix/commands/mount/Makefile +./minix/commands/mount/mount.1 +./minix/commands/mount/mount.c +./minix/commands/mt/Makefile +./minix/commands/mt/mt.1 +./minix/commands/mt/mt.c +./minix/commands/netconf/Makefile +./minix/commands/part/Makefile +./minix/commands/part/part.8 +./minix/commands/part/part.c +./minix/commands/partition/partition.8 +./minix/commands/partition/partition.c +./minix/commands/pkgin_all/Makefile +./minix/commands/pkgin_all/pkgin_all.sh +./minix/commands/pkgin_cd/Makefile +./minix/commands/pkgin_cd/pkgin_cd.sh +./minix/commands/pkgin_sets/Makefile +./minix/commands/pkgin_sets/pkgin_sets.sh +./minix/commands/playwave/Makefile +./minix/commands/playwave/playwave.1 +./minix/commands/playwave/playwave.c +./minix/commands/prep/Makefile +./minix/commands/prep/prep.1 +./minix/commands/prep/prep.c +./minix/commands/printroot/Makefile +./minix/commands/printroot/printroot.8 +./minix/commands/printroot/printroot.c +./minix/commands/profile/Makefile +./minix/commands/profile/profile.1 +./minix/commands/profile/profile.c +./minix/commands/profile/tools/profextr.pl +./minix/commands/profile/tools/proftsc.pl +./minix/commands/progressbar/Makefile +./minix/commands/progressbar/progressbar.c +./minix/commands/ramdisk/Makefile +./minix/commands/ramdisk/ramdisk.c +./minix/commands/rawspeed/Makefile +./minix/commands/rawspeed/rawspeed.8 +./minix/commands/rawspeed/rawspeed.c +./minix/commands/readclock/Makefile +./minix/commands/readclock/readclock.8 +./minix/commands/readclock/readclock.c +./minix/commands/recwave/Makefile +./minix/commands/recwave/recwave.1 +./minix/commands/recwave/recwave.c +./minix/commands/remsync/Makefile +./minix/commands/remsync/remsync.1 +./minix/commands/remsync/remsync.c +./minix/commands/repartition/Makefile +./minix/commands/repartition/repartition.8 +./minix/commands/repartition/repartition.c +./minix/commands/rotate/Makefile +./minix/commands/rotate/rotate.8 +./minix/commands/rotate/rotate.sh +./minix/commands/screendump/Makefile +./minix/commands/screendump/screendump.8 +./minix/commands/screendump/screendump.c +./minix/commands/setup/Makefile +./minix/commands/setup/setup.8 +./minix/commands/slip/Makefile +./minix/commands/slip/slip.8 +./minix/commands/slip/slip.c +./minix/commands/spell/Makefile +./minix/commands/spell/spell.1 +./minix/commands/spell/spell.sh +./minix/commands/sprofalyze/Makefile +./minix/commands/sprofalyze/sprofalyze.8 +./minix/commands/sprofalyze/sprofalyze.c +./minix/commands/sprofdiff/Makefile +./minix/commands/sprofdiff/sprofdiff.8 +./minix/commands/sprofdiff/sprofdiff.c +./minix/commands/sprofdiff/tdist.c +./minix/commands/sprofdiff/tdist.h +./minix/commands/srccrc/Makefile +./minix/commands/srccrc/srccrc.8 +./minix/commands/srccrc/srccrc.sh +./minix/commands/svrctl/Makefile +./minix/commands/svrctl/svrctl.1 +./minix/commands/svrctl/svrctl.c +./minix/commands/swifi/Makefile +./minix/commands/swifi/db_access.c +./minix/commands/swifi/db_access.h +./minix/commands/swifi/db_disasm.c +./minix/commands/swifi/db_machdep.h +./minix/commands/swifi/db_sym.c +./minix/commands/swifi/db_sym.h +./minix/commands/swifi/ddb.h +./minix/commands/swifi/extra.c +./minix/commands/swifi/extra.h +./minix/commands/swifi/fault_model.c +./minix/commands/swifi/read_nlist.c +./minix/commands/swifi/swifi.h +./minix/commands/swifi/systest.c +./minix/commands/swifi/tests/do_swifi +./minix/commands/swifi/tests/do_swifi_bug1 +./minix/commands/swifi/tests/rnd.c +./minix/commands/swifi/tests/rs.restart_imm +./minix/commands/swifi/tests/run_swifi +./minix/commands/swifi/tests/run_swifi-x +./minix/commands/swifi/tests/run_t1 +./minix/commands/swifi/tests/run_t1a +./minix/commands/swifi/tests/run_t1b +./minix/commands/swifi/tests/run_t2 +./minix/commands/swifi/tests/run_t2a +./minix/commands/swifi/tests/run_t2b +./minix/commands/swifi/tests/socket.c +./minix/commands/synctree/Makefile +./minix/commands/synctree/synctree.1 +./minix/commands/synctree/synctree.c +./minix/commands/sysenv/Makefile +./minix/commands/sysenv/sysenv.1 +./minix/commands/sysenv/sysenv.c +./minix/commands/term/Makefile +./minix/commands/term/term.1 +./minix/commands/term/term.c +./minix/commands/termcap/Makefile +./minix/commands/termcap/termcap.1 +./minix/commands/termcap/termcap.c +./minix/commands/tget/Makefile +./minix/commands/tget/tget.1 +./minix/commands/tget/tget.c +./minix/commands/truncate/Makefile +./minix/commands/truncate/truncate.1 +./minix/commands/truncate/truncate.c +./minix/commands/umount/Makefile +./minix/commands/umount/umount.1 +./minix/commands/umount/umount.c +./minix/commands/update/Makefile +./minix/commands/update/update.8 +./minix/commands/update/update.c +./minix/commands/update_asr/Makefile +./minix/commands/update_asr/update_asr.8 +./minix/commands/update_asr/update_asr.sh +./minix/commands/update_bootcfg/Makefile +./minix/commands/update_bootcfg/update_bootcfg.8 +./minix/commands/update_bootcfg/update_bootcfg.sh +./minix/commands/updateboot/Makefile +./minix/commands/updateboot/updateboot.8 +./minix/commands/updateboot/updateboot.sh +./minix/commands/version/Makefile +./minix/commands/version/version.sh +./minix/commands/vol/Makefile +./minix/commands/vol/vol.1 +./minix/commands/vol/vol.c +./minix/commands/worldstone/Makefile +./minix/commands/worldstone/worldstone.1 +./minix/commands/worldstone/worldstone.sh +./minix/commands/writeisofs/writeisofs.c +./minix/commands/zmodem/Makefile +./minix/commands/zmodem/crctab.c +./minix/commands/zmodem/rbsb.c +./minix/commands/zmodem/rz.1 +./minix/commands/zmodem/rz.c +./minix/commands/zmodem/sz.1 +./minix/commands/zmodem/sz.c +./minix/commands/zmodem/zm.c +./minix/commands/zmodem/zmodem.h +./minix/drivers/Makefile +./minix/drivers/Makefile.inc +./minix/drivers/audio/Makefile +./minix/drivers/audio/Makefile.inc +./minix/drivers/audio/README +./minix/drivers/audio/als4000/Makefile +./minix/drivers/audio/als4000/README +./minix/drivers/audio/als4000/als4000.c +./minix/drivers/audio/als4000/als4000.conf +./minix/drivers/audio/als4000/als4000.h +./minix/drivers/audio/als4000/io.h +./minix/drivers/audio/als4000/mixer.c +./minix/drivers/audio/als4000/mixer.h +./minix/drivers/audio/cmi8738/Makefile +./minix/drivers/audio/cmi8738/README +./minix/drivers/audio/cmi8738/cmi8738.c +./minix/drivers/audio/cmi8738/cmi8738.conf +./minix/drivers/audio/cmi8738/cmi8738.h +./minix/drivers/audio/cmi8738/io.h +./minix/drivers/audio/cmi8738/mixer.c +./minix/drivers/audio/cmi8738/mixer.h +./minix/drivers/audio/cs4281/Makefile +./minix/drivers/audio/cs4281/README +./minix/drivers/audio/cs4281/cs4281.c +./minix/drivers/audio/cs4281/cs4281.conf +./minix/drivers/audio/cs4281/cs4281.h +./minix/drivers/audio/cs4281/io.h +./minix/drivers/audio/cs4281/mixer.c +./minix/drivers/audio/cs4281/mixer.h +./minix/drivers/audio/es1370/AC97.h +./minix/drivers/audio/es1370/Makefile +./minix/drivers/audio/es1370/ak4531.c +./minix/drivers/audio/es1370/ak4531.h +./minix/drivers/audio/es1370/es1370.c +./minix/drivers/audio/es1370/es1370.conf +./minix/drivers/audio/es1370/es1370.h +./minix/drivers/audio/es1370/pci_helper.c +./minix/drivers/audio/es1370/pci_helper.h +./minix/drivers/audio/es1371/AC97.c +./minix/drivers/audio/es1371/AC97.h +./minix/drivers/audio/es1371/Makefile +./minix/drivers/audio/es1371/SRC.c +./minix/drivers/audio/es1371/SRC.h +./minix/drivers/audio/es1371/codec.c +./minix/drivers/audio/es1371/codec.h +./minix/drivers/audio/es1371/es1371.c +./minix/drivers/audio/es1371/es1371.conf +./minix/drivers/audio/es1371/es1371.h +./minix/drivers/audio/es1371/pci_helper.c +./minix/drivers/audio/es1371/pci_helper.h +./minix/drivers/audio/es1371/sample_rate_converter.c +./minix/drivers/audio/es1371/sample_rate_converter.h +./minix/drivers/audio/es1371/wait.c +./minix/drivers/audio/es1371/wait.h +./minix/drivers/audio/sb16/Makefile +./minix/drivers/audio/sb16/README +./minix/drivers/audio/sb16/mixer.c +./minix/drivers/audio/sb16/mixer.h +./minix/drivers/audio/sb16/sb16.c +./minix/drivers/audio/sb16/sb16.h +./minix/drivers/audio/trident/Makefile +./minix/drivers/audio/trident/README +./minix/drivers/audio/trident/io.h +./minix/drivers/audio/trident/mixer.c +./minix/drivers/audio/trident/mixer.h +./minix/drivers/audio/trident/trident.c +./minix/drivers/audio/trident/trident.conf +./minix/drivers/audio/trident/trident.h +./minix/drivers/bus/Makefile +./minix/drivers/bus/Makefile.inc +./minix/drivers/bus/i2c/Makefile +./minix/drivers/bus/i2c/arch/earm/Makefile.inc +./minix/drivers/bus/i2c/arch/earm/i2c.conf +./minix/drivers/bus/i2c/arch/earm/omap_i2c.h +./minix/drivers/bus/i2c/arch/earm/omap_i2c_registers.h +./minix/drivers/bus/i2c/arch/i386/Makefile.inc +./minix/drivers/bus/i2c/i2c.c +./minix/drivers/bus/pci/main.c +./minix/drivers/bus/pci/pci.c +./minix/drivers/bus/pci/pci_table.c +./minix/drivers/bus/ti1225/Makefile +./minix/drivers/bus/ti1225/i82365.h +./minix/drivers/bus/ti1225/ti1225.c +./minix/drivers/bus/ti1225/ti1225.conf +./minix/drivers/bus/ti1225/ti1225.h +./minix/drivers/clock/Makefile +./minix/drivers/clock/Makefile.inc +./minix/drivers/clock/readclock/Makefile +./minix/drivers/clock/readclock/arch/earm/Makefile.inc +./minix/drivers/clock/readclock/arch/earm/arch_readclock.c +./minix/drivers/clock/readclock/arch/earm/omap_rtc.c +./minix/drivers/clock/readclock/arch/earm/omap_rtc.h +./minix/drivers/clock/readclock/arch/i386/Makefile.inc +./minix/drivers/clock/readclock/arch/i386/arch_readclock.c +./minix/drivers/clock/readclock/forward.c +./minix/drivers/clock/readclock/forward.h +./minix/drivers/clock/readclock/readclock.c +./minix/drivers/clock/readclock/readclock.h +./minix/drivers/eeprom/Makefile +./minix/drivers/eeprom/Makefile.inc +./minix/drivers/eeprom/cat24c256/README.txt +./minix/drivers/eeprom/cat24c256/cat24c256.c +./minix/drivers/examples/Makefile +./minix/drivers/examples/Makefile.inc +./minix/drivers/examples/hello/Makefile +./minix/drivers/examples/hello/hello.c +./minix/drivers/examples/hello/hello.conf +./minix/drivers/examples/hello/hello.h +./minix/drivers/hid/Makefile +./minix/drivers/hid/Makefile.inc +./minix/drivers/hid/pckbd/Makefile +./minix/drivers/hid/pckbd/pckbd.c +./minix/drivers/hid/pckbd/pckbd.h +./minix/drivers/hid/pckbd/table.c +./minix/drivers/iommu/Makefile +./minix/drivers/iommu/Makefile.inc +./minix/drivers/iommu/amddev/Makefile +./minix/drivers/iommu/amddev/amddev.c +./minix/drivers/iommu/amddev/amddev.conf +./minix/drivers/net/3c90x/3c90x.c +./minix/drivers/net/3c90x/3c90x.conf +./minix/drivers/net/3c90x/3c90x.h +./minix/drivers/net/3c90x/Makefile +./minix/drivers/net/Makefile +./minix/drivers/net/Makefile.inc +./minix/drivers/net/atl2/Makefile +./minix/drivers/net/atl2/atl2.c +./minix/drivers/net/atl2/atl2.conf +./minix/drivers/net/atl2/atl2.h +./minix/drivers/net/dec21140A/Makefile +./minix/drivers/net/dec21140A/README.txt +./minix/drivers/net/dec21140A/dec21140A.c +./minix/drivers/net/dec21140A/dec21140A.conf +./minix/drivers/net/dec21140A/dec21140A.h +./minix/drivers/net/dp8390/3c503.c +./minix/drivers/net/dp8390/3c503.h +./minix/drivers/net/dp8390/Makefile +./minix/drivers/net/dp8390/dp8390.c +./minix/drivers/net/dp8390/dp8390.conf +./minix/drivers/net/dp8390/dp8390.h +./minix/drivers/net/dp8390/local.h +./minix/drivers/net/dp8390/ne2000.c +./minix/drivers/net/dp8390/ne2000.h +./minix/drivers/net/dp8390/rtl8029.c +./minix/drivers/net/dp8390/rtl8029.h +./minix/drivers/net/dp8390/wdeth.c +./minix/drivers/net/dp8390/wdeth.h +./minix/drivers/net/dpeth/3c501.c +./minix/drivers/net/dpeth/3c501.h +./minix/drivers/net/dpeth/3c503.c +./minix/drivers/net/dpeth/3c503.h +./minix/drivers/net/dpeth/3c509.c +./minix/drivers/net/dpeth/3c509.h +./minix/drivers/net/dpeth/8390.c +./minix/drivers/net/dpeth/8390.h +./minix/drivers/net/dpeth/Makefile +./minix/drivers/net/dpeth/README +./minix/drivers/net/dpeth/devio.c +./minix/drivers/net/dpeth/dp.c +./minix/drivers/net/dpeth/dp.h +./minix/drivers/net/dpeth/dpeth.conf +./minix/drivers/net/dpeth/ne.c +./minix/drivers/net/dpeth/ne.h +./minix/drivers/net/dpeth/netbuff.c +./minix/drivers/net/dpeth/wd.c +./minix/drivers/net/dpeth/wd.h +./minix/drivers/net/e1000/Makefile +./minix/drivers/net/e1000/e1000.c +./minix/drivers/net/e1000/e1000.conf +./minix/drivers/net/e1000/e1000.h +./minix/drivers/net/e1000/e1000_hw.h +./minix/drivers/net/e1000/e1000_pci.h +./minix/drivers/net/e1000/e1000_reg.h +./minix/drivers/net/fxp/Makefile +./minix/drivers/net/fxp/fxp.c +./minix/drivers/net/fxp/fxp.conf +./minix/drivers/net/fxp/fxp.h +./minix/drivers/net/fxp/mii.c +./minix/drivers/net/fxp/mii.h +./minix/drivers/net/ip1000/README +./minix/drivers/net/ip1000/io.h +./minix/drivers/net/ip1000/ip1000.c +./minix/drivers/net/ip1000/ip1000.conf +./minix/drivers/net/ip1000/ip1000.h +./minix/drivers/net/lan8710a/Makefile +./minix/drivers/net/lan8710a/README.txt +./minix/drivers/net/lan8710a/lan8710a.c +./minix/drivers/net/lan8710a/lan8710a.conf +./minix/drivers/net/lan8710a/lan8710a.h +./minix/drivers/net/lan8710a/lan8710a_reg.h +./minix/drivers/net/lance/Makefile +./minix/drivers/net/lance/lance.c +./minix/drivers/net/lance/lance.conf +./minix/drivers/net/lance/lance.h +./minix/drivers/net/rtl8139/liveupdate.c +./minix/drivers/net/rtl8139/rtl8139.c +./minix/drivers/net/rtl8139/rtl8139.conf +./minix/drivers/net/rtl8139/rtl8139.h +./minix/drivers/net/rtl8169/rtl8169.c +./minix/drivers/net/rtl8169/rtl8169.conf +./minix/drivers/net/rtl8169/rtl8169.h +./minix/drivers/net/virtio_net/Makefile +./minix/drivers/net/virtio_net/virtio_net.c +./minix/drivers/net/virtio_net/virtio_net.conf +./minix/drivers/net/virtio_net/virtio_net.h +./minix/drivers/net/vt6105/README +./minix/drivers/net/vt6105/io.h +./minix/drivers/net/vt6105/vt6105.c +./minix/drivers/net/vt6105/vt6105.conf +./minix/drivers/net/vt6105/vt6105.h +./minix/drivers/power/Makefile +./minix/drivers/power/Makefile.inc +./minix/drivers/power/acpi/Makefile +./minix/drivers/power/acpi/acpi.c +./minix/drivers/power/acpi/acpi_globals.h +./minix/drivers/power/acpi/dispatcher/dsargs.c +./minix/drivers/power/acpi/dispatcher/dscontrol.c +./minix/drivers/power/acpi/dispatcher/dsfield.c +./minix/drivers/power/acpi/dispatcher/dsinit.c +./minix/drivers/power/acpi/dispatcher/dsmethod.c +./minix/drivers/power/acpi/dispatcher/dsmthdat.c +./minix/drivers/power/acpi/dispatcher/dsobject.c +./minix/drivers/power/acpi/dispatcher/dsopcode.c +./minix/drivers/power/acpi/dispatcher/dsutils.c +./minix/drivers/power/acpi/dispatcher/dswexec.c +./minix/drivers/power/acpi/dispatcher/dswload.c +./minix/drivers/power/acpi/dispatcher/dswload2.c +./minix/drivers/power/acpi/dispatcher/dswscope.c +./minix/drivers/power/acpi/dispatcher/dswstate.c +./minix/drivers/power/acpi/events/evevent.c +./minix/drivers/power/acpi/events/evglock.c +./minix/drivers/power/acpi/events/evgpe.c +./minix/drivers/power/acpi/events/evgpeblk.c +./minix/drivers/power/acpi/events/evgpeinit.c +./minix/drivers/power/acpi/events/evgpeutil.c +./minix/drivers/power/acpi/events/evhandler.c +./minix/drivers/power/acpi/events/evmisc.c +./minix/drivers/power/acpi/events/evregion.c +./minix/drivers/power/acpi/events/evrgnini.c +./minix/drivers/power/acpi/events/evsci.c +./minix/drivers/power/acpi/events/evxface.c +./minix/drivers/power/acpi/events/evxfevnt.c +./minix/drivers/power/acpi/events/evxfgpe.c +./minix/drivers/power/acpi/events/evxfregn.c +./minix/drivers/power/acpi/executer/exconfig.c +./minix/drivers/power/acpi/executer/exconvrt.c +./minix/drivers/power/acpi/executer/excreate.c +./minix/drivers/power/acpi/executer/exdebug.c +./minix/drivers/power/acpi/executer/exdump.c +./minix/drivers/power/acpi/executer/exfield.c +./minix/drivers/power/acpi/executer/exfldio.c +./minix/drivers/power/acpi/executer/exmisc.c +./minix/drivers/power/acpi/executer/exmutex.c +./minix/drivers/power/acpi/executer/exnames.c +./minix/drivers/power/acpi/executer/exoparg1.c +./minix/drivers/power/acpi/executer/exoparg2.c +./minix/drivers/power/acpi/executer/exoparg3.c +./minix/drivers/power/acpi/executer/exoparg6.c +./minix/drivers/power/acpi/executer/exprep.c +./minix/drivers/power/acpi/executer/exregion.c +./minix/drivers/power/acpi/executer/exresnte.c +./minix/drivers/power/acpi/executer/exresolv.c +./minix/drivers/power/acpi/executer/exresop.c +./minix/drivers/power/acpi/executer/exstore.c +./minix/drivers/power/acpi/executer/exstoren.c +./minix/drivers/power/acpi/executer/exstorob.c +./minix/drivers/power/acpi/executer/exsystem.c +./minix/drivers/power/acpi/executer/exutils.c +./minix/drivers/power/acpi/hardware/hwacpi.c +./minix/drivers/power/acpi/hardware/hwesleep.c +./minix/drivers/power/acpi/hardware/hwgpe.c +./minix/drivers/power/acpi/hardware/hwpci.c +./minix/drivers/power/acpi/hardware/hwregs.c +./minix/drivers/power/acpi/hardware/hwsleep.c +./minix/drivers/power/acpi/hardware/hwtimer.c +./minix/drivers/power/acpi/hardware/hwvalid.c +./minix/drivers/power/acpi/hardware/hwxface.c +./minix/drivers/power/acpi/hardware/hwxfsleep.c +./minix/drivers/power/acpi/include/acapps.h +./minix/drivers/power/acpi/include/acbuffer.h +./minix/drivers/power/acpi/include/accommon.h +./minix/drivers/power/acpi/include/acconfig.h +./minix/drivers/power/acpi/include/acdebug.h +./minix/drivers/power/acpi/include/acdisasm.h +./minix/drivers/power/acpi/include/acdispat.h +./minix/drivers/power/acpi/include/acevents.h +./minix/drivers/power/acpi/include/acexcep.h +./minix/drivers/power/acpi/include/acglobal.h +./minix/drivers/power/acpi/include/achware.h +./minix/drivers/power/acpi/include/acinterp.h +./minix/drivers/power/acpi/include/aclocal.h +./minix/drivers/power/acpi/include/acmacros.h +./minix/drivers/power/acpi/include/acnames.h +./minix/drivers/power/acpi/include/acnamesp.h +./minix/drivers/power/acpi/include/acobject.h +./minix/drivers/power/acpi/include/acopcode.h +./minix/drivers/power/acpi/include/acoutput.h +./minix/drivers/power/acpi/include/acparser.h +./minix/drivers/power/acpi/include/acpi.h +./minix/drivers/power/acpi/include/acpiosxf.h +./minix/drivers/power/acpi/include/acpixf.h +./minix/drivers/power/acpi/include/acpredef.h +./minix/drivers/power/acpi/include/acresrc.h +./minix/drivers/power/acpi/include/acrestyp.h +./minix/drivers/power/acpi/include/acstruct.h +./minix/drivers/power/acpi/include/actables.h +./minix/drivers/power/acpi/include/actbl.h +./minix/drivers/power/acpi/include/actbl1.h +./minix/drivers/power/acpi/include/actbl2.h +./minix/drivers/power/acpi/include/actbl3.h +./minix/drivers/power/acpi/include/actypes.h +./minix/drivers/power/acpi/include/acutils.h +./minix/drivers/power/acpi/include/amlcode.h +./minix/drivers/power/acpi/include/amlresrc.h +./minix/drivers/power/acpi/include/platform/accygwin.h +./minix/drivers/power/acpi/include/platform/acefi.h +./minix/drivers/power/acpi/include/platform/acenvex.h +./minix/drivers/power/acpi/include/platform/acfreebsd.h +./minix/drivers/power/acpi/include/platform/acgcc.h +./minix/drivers/power/acpi/include/platform/achaiku.h +./minix/drivers/power/acpi/include/platform/acintel.h +./minix/drivers/power/acpi/include/platform/aclinux.h +./minix/drivers/power/acpi/include/platform/aclinuxex.h +./minix/drivers/power/acpi/include/platform/acmacosx.h +./minix/drivers/power/acpi/include/platform/acminix.h +./minix/drivers/power/acpi/include/platform/acmsvc.h +./minix/drivers/power/acpi/include/platform/acos2.h +./minix/drivers/power/acpi/include/platform/acwin.h +./minix/drivers/power/acpi/include/platform/acwin64.h +./minix/drivers/power/acpi/namespace/nsaccess.c +./minix/drivers/power/acpi/namespace/nsalloc.c +./minix/drivers/power/acpi/namespace/nsarguments.c +./minix/drivers/power/acpi/namespace/nsconvert.c +./minix/drivers/power/acpi/namespace/nsdump.c +./minix/drivers/power/acpi/namespace/nsdumpdv.c +./minix/drivers/power/acpi/namespace/nseval.c +./minix/drivers/power/acpi/namespace/nsinit.c +./minix/drivers/power/acpi/namespace/nsload.c +./minix/drivers/power/acpi/namespace/nsnames.c +./minix/drivers/power/acpi/namespace/nsobject.c +./minix/drivers/power/acpi/namespace/nsparse.c +./minix/drivers/power/acpi/namespace/nspredef.c +./minix/drivers/power/acpi/namespace/nsprepkg.c +./minix/drivers/power/acpi/namespace/nsrepair.c +./minix/drivers/power/acpi/namespace/nsrepair2.c +./minix/drivers/power/acpi/namespace/nssearch.c +./minix/drivers/power/acpi/namespace/nsutils.c +./minix/drivers/power/acpi/namespace/nswalk.c +./minix/drivers/power/acpi/namespace/nsxfeval.c +./minix/drivers/power/acpi/namespace/nsxfname.c +./minix/drivers/power/acpi/namespace/nsxfobj.c +./minix/drivers/power/acpi/osminixxf.c +./minix/drivers/power/acpi/parser/psargs.c +./minix/drivers/power/acpi/parser/psloop.c +./minix/drivers/power/acpi/parser/psobject.c +./minix/drivers/power/acpi/parser/psopcode.c +./minix/drivers/power/acpi/parser/psopinfo.c +./minix/drivers/power/acpi/parser/psparse.c +./minix/drivers/power/acpi/parser/psscope.c +./minix/drivers/power/acpi/parser/pstree.c +./minix/drivers/power/acpi/parser/psutils.c +./minix/drivers/power/acpi/parser/pswalk.c +./minix/drivers/power/acpi/parser/psxface.c +./minix/drivers/power/acpi/pci.c +./minix/drivers/power/acpi/pci.h +./minix/drivers/power/acpi/resources/rsaddr.c +./minix/drivers/power/acpi/resources/rscalc.c +./minix/drivers/power/acpi/resources/rscreate.c +./minix/drivers/power/acpi/resources/rsdump.c +./minix/drivers/power/acpi/resources/rsdumpinfo.c +./minix/drivers/power/acpi/resources/rsinfo.c +./minix/drivers/power/acpi/resources/rsio.c +./minix/drivers/power/acpi/resources/rsirq.c +./minix/drivers/power/acpi/resources/rslist.c +./minix/drivers/power/acpi/resources/rsmemory.c +./minix/drivers/power/acpi/resources/rsmisc.c +./minix/drivers/power/acpi/resources/rsserial.c +./minix/drivers/power/acpi/resources/rsutils.c +./minix/drivers/power/acpi/resources/rsxface.c +./minix/drivers/power/acpi/tables/tbdata.c +./minix/drivers/power/acpi/tables/tbfadt.c +./minix/drivers/power/acpi/tables/tbfind.c +./minix/drivers/power/acpi/tables/tbinstal.c +./minix/drivers/power/acpi/tables/tbprint.c +./minix/drivers/power/acpi/tables/tbutils.c +./minix/drivers/power/acpi/tables/tbxface.c +./minix/drivers/power/acpi/tables/tbxfload.c +./minix/drivers/power/acpi/tables/tbxfroot.c +./minix/drivers/power/acpi/utilities/utaddress.c +./minix/drivers/power/acpi/utilities/utalloc.c +./minix/drivers/power/acpi/utilities/utbuffer.c +./minix/drivers/power/acpi/utilities/utcache.c +./minix/drivers/power/acpi/utilities/utclib.c +./minix/drivers/power/acpi/utilities/utcopy.c +./minix/drivers/power/acpi/utilities/utdebug.c +./minix/drivers/power/acpi/utilities/utdecode.c +./minix/drivers/power/acpi/utilities/utdelete.c +./minix/drivers/power/acpi/utilities/uterror.c +./minix/drivers/power/acpi/utilities/uteval.c +./minix/drivers/power/acpi/utilities/utexcep.c +./minix/drivers/power/acpi/utilities/utfileio.c +./minix/drivers/power/acpi/utilities/utglobal.c +./minix/drivers/power/acpi/utilities/uthex.c +./minix/drivers/power/acpi/utilities/utids.c +./minix/drivers/power/acpi/utilities/utinit.c +./minix/drivers/power/acpi/utilities/utlock.c +./minix/drivers/power/acpi/utilities/utmath.c +./minix/drivers/power/acpi/utilities/utmisc.c +./minix/drivers/power/acpi/utilities/utmutex.c +./minix/drivers/power/acpi/utilities/utobject.c +./minix/drivers/power/acpi/utilities/utosi.c +./minix/drivers/power/acpi/utilities/utownerid.c +./minix/drivers/power/acpi/utilities/utpredef.c +./minix/drivers/power/acpi/utilities/utprint.c +./minix/drivers/power/acpi/utilities/utresrc.c +./minix/drivers/power/acpi/utilities/utstate.c +./minix/drivers/power/acpi/utilities/utstring.c +./minix/drivers/power/acpi/utilities/uttrack.c +./minix/drivers/power/acpi/utilities/utuuid.c +./minix/drivers/power/acpi/utilities/utxface.c +./minix/drivers/power/acpi/utilities/utxferror.c +./minix/drivers/power/acpi/utilities/utxfinit.c +./minix/drivers/power/acpi/utilities/utxfmutex.c +./minix/drivers/power/tps65217/README.txt +./minix/drivers/power/tps65217/tps65217.c +./minix/drivers/power/tps65950/README.txt +./minix/drivers/power/tps65950/rtc.c +./minix/drivers/power/tps65950/rtc.h +./minix/drivers/power/tps65950/tps65950.c +./minix/drivers/power/tps65950/tps65950.h +./minix/drivers/printer/Makefile +./minix/drivers/printer/Makefile.inc +./minix/drivers/printer/printer/Makefile +./minix/drivers/printer/printer/liveupdate.c +./minix/drivers/printer/printer/printer.c +./minix/drivers/printer/printer/printer.conf +./minix/drivers/sensors/Makefile +./minix/drivers/sensors/Makefile.inc +./minix/drivers/sensors/bmp085/README.txt +./minix/drivers/sensors/bmp085/bmp085.c +./minix/drivers/sensors/bmp085/bmp085.conf +./minix/drivers/sensors/sht21/README.txt +./minix/drivers/sensors/sht21/sht21.c +./minix/drivers/sensors/sht21/sht21.conf +./minix/drivers/sensors/tsl2550/README.txt +./minix/drivers/sensors/tsl2550/tsl2550.c +./minix/drivers/sensors/tsl2550/tsl2550.conf +./minix/drivers/storage/Makefile +./minix/drivers/storage/Makefile.inc +./minix/drivers/storage/ahci/Makefile +./minix/drivers/storage/ahci/ahci.c +./minix/drivers/storage/ahci/ahci.h +./minix/drivers/storage/at_wini/Makefile +./minix/drivers/storage/at_wini/at_wini.c +./minix/drivers/storage/at_wini/at_wini.h +./minix/drivers/storage/at_wini/liveupdate.c +./minix/drivers/storage/fbd/action.c +./minix/drivers/storage/fbd/action.h +./minix/drivers/storage/fbd/fbd.c +./minix/drivers/storage/fbd/rule.c +./minix/drivers/storage/fbd/rule.h +./minix/drivers/storage/filter/Makefile +./minix/drivers/storage/filter/crc.c +./minix/drivers/storage/filter/crc.h +./minix/drivers/storage/filter/driver.c +./minix/drivers/storage/filter/inc.h +./minix/drivers/storage/filter/main.c +./minix/drivers/storage/filter/md5.c +./minix/drivers/storage/filter/md5.h +./minix/drivers/storage/filter/sum.c +./minix/drivers/storage/filter/util.c +./minix/drivers/storage/floppy/Makefile +./minix/drivers/storage/floppy/floppy.c +./minix/drivers/storage/floppy/floppy.h +./minix/drivers/storage/floppy/liveupdate.c +./minix/drivers/storage/memory/local.h +./minix/drivers/storage/memory/memory.c +./minix/drivers/storage/mmc/Makefile +./minix/drivers/storage/mmc/emmc.c +./minix/drivers/storage/mmc/emmc.txt +./minix/drivers/storage/mmc/mmcblk.c +./minix/drivers/storage/mmc/mmchost.h +./minix/drivers/storage/mmc/mmchost_dummy.c +./minix/drivers/storage/mmc/omap_mmc.h +./minix/drivers/storage/ramdisk/proto +./minix/drivers/storage/ramdisk/proto.common.dynamic +./minix/drivers/storage/ramdisk/proto.common.etc +./minix/drivers/storage/virtio_blk/Makefile +./minix/drivers/storage/virtio_blk/virtio_blk.c +./minix/drivers/storage/virtio_blk/virtio_blk.h +./minix/drivers/storage/vnd/Makefile +./minix/drivers/storage/vnd/vnd.c +./minix/drivers/system/Makefile +./minix/drivers/system/Makefile.inc +./minix/drivers/system/gpio/Makefile +./minix/drivers/system/gpio/README.txt +./minix/drivers/system/gpio/gpio.c +./minix/drivers/system/gpio/gpio.conf +./minix/drivers/system/log/Makefile +./minix/drivers/system/log/diag.c +./minix/drivers/system/log/liveupdate.c +./minix/drivers/system/log/log.c +./minix/drivers/system/log/log.h +./minix/drivers/system/random/aes/boxes.dat +./minix/drivers/system/random/aes/rijndael-alg.h +./minix/drivers/system/random/aes/rijndael-api.h +./minix/drivers/system/random/aes/rijndael.h +./minix/drivers/system/random/aes/rijndael_alg.c +./minix/drivers/system/random/aes/rijndael_api.c +./minix/drivers/system/random/aes/word_i386.h +./minix/drivers/system/random/main.c +./minix/drivers/system/random/random.c +./minix/drivers/system/random/random.conf +./minix/drivers/system/random/random.h +./minix/drivers/tty/Makefile +./minix/drivers/tty/Makefile.inc +./minix/drivers/tty/pty/Makefile +./minix/drivers/tty/pty/pty.c +./minix/drivers/tty/pty/ptyfs.c +./minix/drivers/tty/pty/ptyfs.h +./minix/drivers/tty/pty/tty.c +./minix/drivers/tty/pty/tty.h +./minix/drivers/tty/tty/arch/earm/Makefile.inc +./minix/drivers/tty/tty/arch/earm/console.c +./minix/drivers/tty/tty/arch/earm/keyboard.c +./minix/drivers/tty/tty/arch/earm/omap_serial.h +./minix/drivers/tty/tty/arch/earm/rs232.c +./minix/drivers/tty/tty/arch/i386/Makefile.inc +./minix/drivers/tty/tty/arch/i386/console.c +./minix/drivers/tty/tty/arch/i386/keyboard.c +./minix/drivers/tty/tty/arch/i386/rs232.c +./minix/drivers/tty/tty/keymaps/abnt2.src +./minix/drivers/tty/tty/keymaps/colemak.src +./minix/drivers/tty/tty/keymaps/dvorak.src +./minix/drivers/tty/tty/keymaps/french.src +./minix/drivers/tty/tty/keymaps/genmap.c +./minix/drivers/tty/tty/keymaps/german.src +./minix/drivers/tty/tty/keymaps/hungarian.src +./minix/drivers/tty/tty/keymaps/italian.src +./minix/drivers/tty/tty/keymaps/japanese.src +./minix/drivers/tty/tty/keymaps/latin-america.src +./minix/drivers/tty/tty/keymaps/norwegian.src +./minix/drivers/tty/tty/keymaps/polish.src +./minix/drivers/tty/tty/keymaps/portuguese.src +./minix/drivers/tty/tty/keymaps/russian-cp1251.src +./minix/drivers/tty/tty/keymaps/russian-cp866.src +./minix/drivers/tty/tty/keymaps/russian.src +./minix/drivers/tty/tty/keymaps/scandinavian.src +./minix/drivers/tty/tty/keymaps/spanish.src +./minix/drivers/tty/tty/keymaps/uk.src +./minix/drivers/tty/tty/keymaps/ukraine-koi8-u.src +./minix/drivers/tty/tty/keymaps/us-std.src +./minix/drivers/tty/tty/keymaps/us-swap.src +./minix/drivers/tty/tty/tty.c +./minix/drivers/tty/tty/tty.h +./minix/drivers/usb/Makefile +./minix/drivers/usb/Makefile.inc +./minix/drivers/usb/usb_hub/Makefile +./minix/drivers/usb/usb_hub/common.h +./minix/drivers/usb/usb_hub/urb_helper.c +./minix/drivers/usb/usb_hub/urb_helper.h +./minix/drivers/usb/usb_hub/usb_hub.c +./minix/drivers/usb/usb_hub/usb_hub.conf +./minix/drivers/usb/usb_storage/Makefile +./minix/drivers/usb/usb_storage/README.txt +./minix/drivers/usb/usb_storage/bulk.c +./minix/drivers/usb/usb_storage/bulk.h +./minix/drivers/usb/usb_storage/common.h +./minix/drivers/usb/usb_storage/scsi.c +./minix/drivers/usb/usb_storage/scsi.h +./minix/drivers/usb/usb_storage/urb_helper.c +./minix/drivers/usb/usb_storage/urb_helper.h +./minix/drivers/usb/usb_storage/usb_storage.c +./minix/drivers/usb/usb_storage/usb_storage.conf +./minix/drivers/usb/usb_storage/usb_storage.h +./minix/drivers/usb/usbd/Makefile +./minix/drivers/usb/usbd/README.txt +./minix/drivers/usb/usbd/base/earm/Makefile +./minix/drivers/usb/usbd/base/earm/usbd_earm.c +./minix/drivers/usb/usbd/base/usbd.c +./minix/drivers/usb/usbd/hcd/hcd.c +./minix/drivers/usb/usbd/hcd/hcd_common.c +./minix/drivers/usb/usbd/hcd/hcd_ddekit.c +./minix/drivers/usb/usbd/hcd/hcd_schedule.c +./minix/drivers/usb/usbd/hcd/musb/musb_am335x.c +./minix/drivers/usb/usbd/hcd/musb/musb_core.c +./minix/drivers/usb/usbd/hcd/musb/musb_core.h +./minix/drivers/usb/usbd/hcd/musb/musb_regs.h +./minix/drivers/usb/usbd/include/usbd/hcd_common.h +./minix/drivers/usb/usbd/include/usbd/hcd_ddekit.h +./minix/drivers/usb/usbd/include/usbd/hcd_interface.h +./minix/drivers/usb/usbd/include/usbd/hcd_platforms.h +./minix/drivers/usb/usbd/include/usbd/hcd_schedule.h +./minix/drivers/usb/usbd/include/usbd/usbd_common.h +./minix/drivers/usb/usbd/include/usbd/usbd_interface.h +./minix/drivers/usb/usbd/include/usbd/usbd_schedule.h +./minix/drivers/usb/usbd/usbd.conf +./minix/drivers/video/Makefile +./minix/drivers/video/Makefile.inc +./minix/drivers/video/fb/README.txt +./minix/drivers/video/fb/arch/earm/Makefile.inc +./minix/drivers/video/fb/arch/earm/dss.h +./minix/drivers/video/fb/arch/earm/fb_arch.c +./minix/drivers/video/fb/fb.c +./minix/drivers/video/fb/fb.h +./minix/drivers/video/fb/fb_edid.c +./minix/drivers/video/fb/fb_edid.h +./minix/drivers/video/fb/logos.h +./minix/drivers/video/tda19988/README.txt +./minix/drivers/video/tda19988/tda19988.c +./minix/drivers/vmm_guest/Makefile +./minix/drivers/vmm_guest/Makefile.inc +./minix/drivers/vmm_guest/vbox/Makefile +./minix/drivers/vmm_guest/vbox/err.c +./minix/drivers/vmm_guest/vbox/hgcm.c +./minix/drivers/vmm_guest/vbox/proto.h +./minix/drivers/vmm_guest/vbox/vbox.c +./minix/drivers/vmm_guest/vbox/vbox.conf +./minix/drivers/vmm_guest/vbox/vmmdev.h +./minix/fs/Makefile +./minix/fs/Makefile.inc +./minix/fs/ext2/Makefile +./minix/fs/ext2/balloc.c +./minix/fs/ext2/buf.h +./minix/fs/ext2/const.h +./minix/fs/ext2/fs.h +./minix/fs/ext2/glo.h +./minix/fs/ext2/ialloc.c +./minix/fs/ext2/inode.c +./minix/fs/ext2/inode.h +./minix/fs/ext2/link.c +./minix/fs/ext2/main.c +./minix/fs/ext2/misc.c +./minix/fs/ext2/mount.c +./minix/fs/ext2/open.c +./minix/fs/ext2/path.c +./minix/fs/ext2/protect.c +./minix/fs/ext2/proto.h +./minix/fs/ext2/read.c +./minix/fs/ext2/stadir.c +./minix/fs/ext2/super.c +./minix/fs/ext2/super.h +./minix/fs/ext2/table.c +./minix/fs/ext2/time.c +./minix/fs/ext2/type.h +./minix/fs/ext2/utility.c +./minix/fs/ext2/write.c +./minix/fs/hgfs/Makefile +./minix/fs/hgfs/hgfs.8 +./minix/fs/hgfs/hgfs.c +./minix/fs/isofs/Makefile +./minix/fs/isofs/const.h +./minix/fs/isofs/glo.h +./minix/fs/isofs/inc.h +./minix/fs/isofs/inode.c +./minix/fs/isofs/inode.h +./minix/fs/isofs/link.c +./minix/fs/isofs/main.c +./minix/fs/isofs/mount.c +./minix/fs/isofs/path.c +./minix/fs/isofs/proto.h +./minix/fs/isofs/read.c +./minix/fs/isofs/stadir.c +./minix/fs/isofs/super.c +./minix/fs/isofs/super.h +./minix/fs/isofs/susp.c +./minix/fs/isofs/susp_rock_ridge.c +./minix/fs/isofs/table.c +./minix/fs/isofs/uthash.h +./minix/fs/isofs/utility.c +./minix/fs/mfs/Makefile +./minix/fs/mfs/buf.h +./minix/fs/mfs/cache.c +./minix/fs/mfs/clean.h +./minix/fs/mfs/const.h +./minix/fs/mfs/fs.h +./minix/fs/mfs/glo.h +./minix/fs/mfs/inode.c +./minix/fs/mfs/inode.h +./minix/fs/mfs/link.c +./minix/fs/mfs/main.c +./minix/fs/mfs/mfsdir.h +./minix/fs/mfs/misc.c +./minix/fs/mfs/mount.c +./minix/fs/mfs/open.c +./minix/fs/mfs/path.c +./minix/fs/mfs/protect.c +./minix/fs/mfs/proto.h +./minix/fs/mfs/read.c +./minix/fs/mfs/stadir.c +./minix/fs/mfs/stats.c +./minix/fs/mfs/super.c +./minix/fs/mfs/super.h +./minix/fs/mfs/table.c +./minix/fs/mfs/time.c +./minix/fs/mfs/type.h +./minix/fs/mfs/utility.c +./minix/fs/mfs/write.c +./minix/fs/pfs/Makefile +./minix/fs/pfs/pfs.c +./minix/fs/procfs/NOTES +./minix/fs/procfs/buf.c +./minix/fs/procfs/const.h +./minix/fs/procfs/cpuinfo.c +./minix/fs/procfs/glo.h +./minix/fs/procfs/inc.h +./minix/fs/procfs/main.c +./minix/fs/procfs/pid.c +./minix/fs/procfs/proto.h +./minix/fs/procfs/root.c +./minix/fs/procfs/service.c +./minix/fs/procfs/tree.c +./minix/fs/procfs/type.h +./minix/fs/procfs/util.c +./minix/fs/ptyfs/Makefile +./minix/fs/ptyfs/node.c +./minix/fs/ptyfs/node.h +./minix/fs/ptyfs/ptyfs.c +./minix/fs/vbfs/Makefile +./minix/fs/vbfs/vbfs.8 +./minix/fs/vbfs/vbfs.c +./minix/fs/vbfs/vbfs.conf +./minix/include/Makefile +./minix/include/arch/Makefile +./minix/include/arch/earm/Makefile +./minix/include/arch/earm/include/Makefile +./minix/include/arch/earm/include/archconst.h +./minix/include/arch/earm/include/archtypes.h +./minix/include/arch/earm/include/diskparm.h +./minix/include/arch/earm/include/elf.h +./minix/include/arch/earm/include/interrupt.h +./minix/include/arch/earm/include/ipcconst.h +./minix/include/arch/earm/include/memory.h +./minix/include/arch/earm/include/partition.h +./minix/include/arch/earm/include/stackframe.h +./minix/include/arch/earm/include/vm.h +./minix/include/arch/i386/Makefile +./minix/include/arch/i386/include/Makefile +./minix/include/arch/i386/include/archconst.h +./minix/include/arch/i386/include/archtypes.h +./minix/include/arch/i386/include/bios.h +./minix/include/arch/i386/include/cmos.h +./minix/include/arch/i386/include/diskparm.h +./minix/include/arch/i386/include/elf.h +./minix/include/arch/i386/include/fpu.h +./minix/include/arch/i386/include/interrupt.h +./minix/include/arch/i386/include/ipcconst.h +./minix/include/arch/i386/include/memory.h +./minix/include/arch/i386/include/partition.h +./minix/include/arch/i386/include/pci.h +./minix/include/arch/i386/include/pci_amd.h +./minix/include/arch/i386/include/pci_intel.h +./minix/include/arch/i386/include/pci_sis.h +./minix/include/arch/i386/include/pci_via.h +./minix/include/arch/i386/include/ports.h +./minix/include/arch/i386/include/stackframe.h +./minix/include/arch/i386/include/vm.h +./minix/include/configfile.h +./minix/include/ddekit/Makefile +./minix/include/ddekit/assert.h +./minix/include/ddekit/attribs.h +./minix/include/ddekit/condvar.h +./minix/include/ddekit/ddekit.h +./minix/include/ddekit/debug.h +./minix/include/ddekit/initcall.h +./minix/include/ddekit/inline.h +./minix/include/ddekit/interrupt.h +./minix/include/ddekit/lock.h +./minix/include/ddekit/memory.h +./minix/include/ddekit/minix/Makefile +./minix/include/ddekit/minix/msg_queue.h +./minix/include/ddekit/minix/pci.h +./minix/include/ddekit/panic.h +./minix/include/ddekit/pci.h +./minix/include/ddekit/pgtab.h +./minix/include/ddekit/printf.h +./minix/include/ddekit/resources.h +./minix/include/ddekit/semaphore.h +./minix/include/ddekit/thread.h +./minix/include/ddekit/timer.h +./minix/include/ddekit/types.h +./minix/include/ddekit/usb.h +./minix/include/libdde/Makefile +./minix/include/libdde/usb_server.h +./minix/include/libutil.h +./minix/include/minix/Makefile +./minix/include/minix/acpi.h +./minix/include/minix/audio_fw.h +./minix/include/minix/bdev.h +./minix/include/minix/bitmap.h +./minix/include/minix/blockdriver.h +./minix/include/minix/blockdriver_mt.h +./minix/include/minix/board.h +./minix/include/minix/btrace.h +./minix/include/minix/callnr.h +./minix/include/minix/chardriver.h +./minix/include/minix/clkconf.h +./minix/include/minix/com.h +./minix/include/minix/config.h +./minix/include/minix/const.h +./minix/include/minix/cpufeature.h +./minix/include/minix/debug.h +./minix/include/minix/devio.h +./minix/include/minix/devman.h +./minix/include/minix/dmap.h +./minix/include/minix/drvlib.h +./minix/include/minix/ds.h +./minix/include/minix/endpoint.h +./minix/include/minix/fb.h +./minix/include/minix/fsdriver.h +./minix/include/minix/fslib.h +./minix/include/minix/gcov.h +./minix/include/minix/gpio.h +./minix/include/minix/hash.h +./minix/include/minix/hgfs.h +./minix/include/minix/i2cdriver.h +./minix/include/minix/input.h +./minix/include/minix/inputdriver.h +./minix/include/minix/ioctl.h +./minix/include/minix/ipc.h +./minix/include/minix/ipc_filter.h +./minix/include/minix/ipcconst.h +./minix/include/minix/keymap.h +./minix/include/minix/libminixfs.h +./minix/include/minix/log.h +./minix/include/minix/minlib.h +./minix/include/minix/mmio.h +./minix/include/minix/mthread.h +./minix/include/minix/netdriver.h +./minix/include/minix/optset.h +./minix/include/minix/padconf.h +./minix/include/minix/param.h +./minix/include/minix/partition.h +./minix/include/minix/paths.h +./minix/include/minix/portio.h +./minix/include/minix/priv.h +./minix/include/minix/procfs.h +./minix/include/minix/profile.h +./minix/include/minix/safecopies.h +./minix/include/minix/sched.h +./minix/include/minix/sef.h +./minix/include/minix/sffs.h +./minix/include/minix/sockdriver.h +./minix/include/minix/sockevent.h +./minix/include/minix/sound.h +./minix/include/minix/spin.h +./minix/include/minix/sys_config.h +./minix/include/minix/sysinfo.h +./minix/include/minix/syslib.h +./minix/include/minix/sysutil.h +./minix/include/minix/timers.h +./minix/include/minix/type.h +./minix/include/minix/u64.h +./minix/include/minix/usb.h +./minix/include/minix/vbox.h +./minix/include/minix/vboxfs.h +./minix/include/minix/vboxif.h +./minix/include/minix/vboxtype.h +./minix/include/minix/vfsif.h +./minix/include/minix/virtio.h +./minix/include/minix/vm.h +./minix/include/minix/vtreefs.h +./minix/include/net/Makefile +./minix/include/net/gen/Makefile +./minix/include/net/gen/arp_io.h +./minix/include/net/gen/dhcp.h +./minix/include/net/gen/eth_hdr.h +./minix/include/net/gen/eth_io.h +./minix/include/net/gen/ether.h +./minix/include/net/gen/icmp.h +./minix/include/net/gen/icmp_hdr.h +./minix/include/net/gen/if_ether.h +./minix/include/net/gen/in.h +./minix/include/net/gen/inet.h +./minix/include/net/gen/ip_hdr.h +./minix/include/net/gen/ip_io.h +./minix/include/net/gen/oneCsum.h +./minix/include/net/gen/psip_hdr.h +./minix/include/net/gen/psip_io.h +./minix/include/net/gen/rip.h +./minix/include/net/gen/route.h +./minix/include/net/gen/socket.h +./minix/include/net/gen/tcp.h +./minix/include/net/gen/tcp_hdr.h +./minix/include/net/gen/tcp_io.h +./minix/include/net/gen/udp.h +./minix/include/net/gen/udp_hdr.h +./minix/include/net/gen/udp_io.h +./minix/include/net/gen/udp_io_hdr.h +./minix/include/net/gen/vjhc.h +./minix/include/net/hton.h +./minix/include/net/netlib.h +./minix/include/sys/Makefile +./minix/include/sys/elf64.h +./minix/include/sys/elf_core.h +./minix/include/sys/elf_generic.h +./minix/include/sys/ioc_block.h +./minix/include/sys/ioc_disk.h +./minix/include/sys/ioc_fb.h +./minix/include/sys/ioc_fbd.h +./minix/include/sys/ioc_file.h +./minix/include/sys/ioc_memory.h +./minix/include/sys/ioc_sound.h +./minix/include/sys/ioc_tape.h +./minix/include/sys/kbdio.h +./minix/include/sys/procfs.h +./minix/include/sys/statfs.h +./minix/include/sys/svrctl.h +./minix/include/sys/video.h +./minix/kernel/arch/earm/arch_clock.c +./minix/kernel/arch/earm/arch_do_vmctl.c +./minix/kernel/arch/earm/arch_reset.c +./minix/kernel/arch/earm/arch_system.c +./minix/kernel/arch/earm/bsp/include/bsp_init.h +./minix/kernel/arch/earm/bsp/include/bsp_intr.h +./minix/kernel/arch/earm/bsp/include/bsp_padconf.h +./minix/kernel/arch/earm/bsp/include/bsp_reset.h +./minix/kernel/arch/earm/bsp/include/bsp_serial.h +./minix/kernel/arch/earm/bsp/include/bsp_timer.h +./minix/kernel/arch/earm/bsp/ti/Makefile.inc +./minix/kernel/arch/earm/bsp/ti/omap_init.c +./minix/kernel/arch/earm/bsp/ti/omap_intr.c +./minix/kernel/arch/earm/bsp/ti/omap_intr_registers.h +./minix/kernel/arch/earm/bsp/ti/omap_padconf.c +./minix/kernel/arch/earm/bsp/ti/omap_reset.c +./minix/kernel/arch/earm/bsp/ti/omap_rtc.c +./minix/kernel/arch/earm/bsp/ti/omap_rtc.h +./minix/kernel/arch/earm/bsp/ti/omap_serial.c +./minix/kernel/arch/earm/bsp/ti/omap_serial.h +./minix/kernel/arch/earm/bsp/ti/omap_timer.c +./minix/kernel/arch/earm/bsp/ti/omap_timer_registers.h +./minix/kernel/arch/earm/direct_tty_utils.c +./minix/kernel/arch/earm/do_padconf.c +./minix/kernel/arch/earm/exc.S +./minix/kernel/arch/earm/exception.c +./minix/kernel/arch/earm/glo.h +./minix/kernel/arch/earm/head.S +./minix/kernel/arch/earm/hw_intr.c +./minix/kernel/arch/earm/include/arch_clock.h +./minix/kernel/arch/earm/include/arch_proto.h +./minix/kernel/arch/earm/include/arch_watchdog.h +./minix/kernel/arch/earm/include/archconst.h +./minix/kernel/arch/earm/include/ccnt.h +./minix/kernel/arch/earm/include/cpufunc.h +./minix/kernel/arch/earm/include/direct_utils.h +./minix/kernel/arch/earm/include/hw_intr.h +./minix/kernel/arch/earm/include/io.h +./minix/kernel/arch/earm/kernel.lds +./minix/kernel/arch/earm/klib.S +./minix/kernel/arch/earm/memory.c +./minix/kernel/arch/earm/mpx.S +./minix/kernel/arch/earm/pg_utils.c +./minix/kernel/arch/earm/phys_copy.S +./minix/kernel/arch/earm/pre_init.c +./minix/kernel/arch/earm/procoffsets.cf +./minix/kernel/arch/earm/protect.c +./minix/kernel/arch/earm/sconst.h +./minix/kernel/arch/earm/timer.h +./minix/kernel/arch/i386/acpi.c +./minix/kernel/arch/i386/acpi.h +./minix/kernel/arch/i386/apic.c +./minix/kernel/arch/i386/apic.h +./minix/kernel/arch/i386/apic_asm.S +./minix/kernel/arch/i386/apic_asm.h +./minix/kernel/arch/i386/arch_clock.c +./minix/kernel/arch/i386/arch_do_vmctl.c +./minix/kernel/arch/i386/arch_reset.c +./minix/kernel/arch/i386/arch_smp.c +./minix/kernel/arch/i386/arch_system.c +./minix/kernel/arch/i386/arch_watchdog.c +./minix/kernel/arch/i386/breakpoints.c +./minix/kernel/arch/i386/debugreg.S +./minix/kernel/arch/i386/debugreg.h +./minix/kernel/arch/i386/direct_tty_utils.c +./minix/kernel/arch/i386/do_iopenable.c +./minix/kernel/arch/i386/do_readbios.c +./minix/kernel/arch/i386/do_sdevio.c +./minix/kernel/arch/i386/exception.c +./minix/kernel/arch/i386/glo.h +./minix/kernel/arch/i386/head.S +./minix/kernel/arch/i386/i8259.c +./minix/kernel/arch/i386/include/arch_clock.h +./minix/kernel/arch/i386/include/arch_proto.h +./minix/kernel/arch/i386/include/arch_smp.h +./minix/kernel/arch/i386/include/arch_watchdog.h +./minix/kernel/arch/i386/include/archconst.h +./minix/kernel/arch/i386/include/direct_utils.h +./minix/kernel/arch/i386/include/hw_intr.h +./minix/kernel/arch/i386/io_inb.S +./minix/kernel/arch/i386/io_inl.S +./minix/kernel/arch/i386/io_intr.S +./minix/kernel/arch/i386/io_inw.S +./minix/kernel/arch/i386/io_outb.S +./minix/kernel/arch/i386/io_outl.S +./minix/kernel/arch/i386/io_outw.S +./minix/kernel/arch/i386/kernel.lds +./minix/kernel/arch/i386/klib.S +./minix/kernel/arch/i386/memory.c +./minix/kernel/arch/i386/mpx.S +./minix/kernel/arch/i386/oxpcie.c +./minix/kernel/arch/i386/oxpcie.h +./minix/kernel/arch/i386/pg_utils.c +./minix/kernel/arch/i386/pre_init.c +./minix/kernel/arch/i386/procoffsets.cf +./minix/kernel/arch/i386/protect.c +./minix/kernel/arch/i386/sconst.h +./minix/kernel/arch/i386/serial.h +./minix/kernel/arch/i386/trampoline.S +./minix/kernel/arch/i386/usermapped_data_arch.c +./minix/kernel/arch/i386/usermapped_glo_ipc.S +./minix/kernel/clock.c +./minix/kernel/clock.h +./minix/kernel/config.h +./minix/kernel/const.h +./minix/kernel/cpulocals.c +./minix/kernel/cpulocals.h +./minix/kernel/debug.c +./minix/kernel/debug.h +./minix/kernel/extract-errno.sh +./minix/kernel/extract-mfield.sh +./minix/kernel/extract-mtype.sh +./minix/kernel/glo.h +./minix/kernel/interrupt.c +./minix/kernel/interrupt.h +./minix/kernel/ipc.h +./minix/kernel/ipc_filter.h +./minix/kernel/kernel.h +./minix/kernel/main.c +./minix/kernel/priv.h +./minix/kernel/proc.c +./minix/kernel/proc.h +./minix/kernel/profile.c +./minix/kernel/profile.h +./minix/kernel/proto.h +./minix/kernel/smp.c +./minix/kernel/smp.h +./minix/kernel/spinlock.h +./minix/kernel/system.c +./minix/kernel/system.h +./minix/kernel/system/Makefile.inc +./minix/kernel/system/do_abort.c +./minix/kernel/system/do_clear.c +./minix/kernel/system/do_copy.c +./minix/kernel/system/do_devio.c +./minix/kernel/system/do_diagctl.c +./minix/kernel/system/do_endksig.c +./minix/kernel/system/do_exec.c +./minix/kernel/system/do_exit.c +./minix/kernel/system/do_fork.c +./minix/kernel/system/do_getinfo.c +./minix/kernel/system/do_getksig.c +./minix/kernel/system/do_irqctl.c +./minix/kernel/system/do_kill.c +./minix/kernel/system/do_mcontext.c +./minix/kernel/system/do_memset.c +./minix/kernel/system/do_privctl.c +./minix/kernel/system/do_runctl.c +./minix/kernel/system/do_safecopy.c +./minix/kernel/system/do_safememset.c +./minix/kernel/system/do_schedctl.c +./minix/kernel/system/do_schedule.c +./minix/kernel/system/do_setalarm.c +./minix/kernel/system/do_setgrant.c +./minix/kernel/system/do_settime.c +./minix/kernel/system/do_sigreturn.c +./minix/kernel/system/do_sigsend.c +./minix/kernel/system/do_sprofile.c +./minix/kernel/system/do_statectl.c +./minix/kernel/system/do_stime.c +./minix/kernel/system/do_times.c +./minix/kernel/system/do_trace.c +./minix/kernel/system/do_umap.c +./minix/kernel/system/do_umap_remote.c +./minix/kernel/system/do_update.c +./minix/kernel/system/do_vdevio.c +./minix/kernel/system/do_vmctl.c +./minix/kernel/system/do_vtimer.c +./minix/kernel/system/do_vumap.c +./minix/kernel/table.c +./minix/kernel/type.h +./minix/kernel/usermapped_data.c +./minix/kernel/utility.c +./minix/kernel/vm.h +./minix/kernel/watchdog.c +./minix/kernel/watchdog.h +./minix/lib/Makefile +./minix/lib/Makefile.inc +./minix/lib/libacpi/Makefile +./minix/lib/libacpi/acpi.c +./minix/lib/libasyn/Makefile +./minix/lib/libasyn/Makefile.inc +./minix/lib/libasyn/asyn.h +./minix/lib/libasyn/asyn_cancel.c +./minix/lib/libasyn/asyn_close.c +./minix/lib/libasyn/asyn_init.c +./minix/lib/libasyn/asyn_pending.c +./minix/lib/libasyn/asyn_read.c +./minix/lib/libasyn/asyn_special.c +./minix/lib/libasyn/asyn_synch.c +./minix/lib/libasyn/asyn_wait.c +./minix/lib/libasyn/asyn_write.c +./minix/lib/libasyn/asynchio.h +./minix/lib/libaudiodriver/Makefile +./minix/lib/libaudiodriver/audio_fw.c +./minix/lib/libaudiodriver/liveupdate.c +./minix/lib/libbdev/Makefile +./minix/lib/libbdev/NOTES +./minix/lib/libbdev/bdev.c +./minix/lib/libbdev/call.c +./minix/lib/libbdev/const.h +./minix/lib/libbdev/driver.c +./minix/lib/libbdev/ipc.c +./minix/lib/libbdev/minor.c +./minix/lib/libbdev/proto.h +./minix/lib/libbdev/type.h +./minix/lib/libblockdriver/Makefile +./minix/lib/libblockdriver/const.h +./minix/lib/libblockdriver/driver.c +./minix/lib/libblockdriver/driver.h +./minix/lib/libblockdriver/driver_mt.c +./minix/lib/libblockdriver/driver_mt.h +./minix/lib/libblockdriver/driver_st.c +./minix/lib/libblockdriver/drvlib.c +./minix/lib/libblockdriver/liveupdate.c +./minix/lib/libblockdriver/mq.c +./minix/lib/libblockdriver/mq.h +./minix/lib/libblockdriver/trace.c +./minix/lib/libblockdriver/trace.h +./minix/lib/libc/arch/arm/get_bp.S +./minix/lib/libc/arch/arm/read_tsc.c +./minix/lib/libc/arch/arm/sys/__sigreturn.S +./minix/lib/libc/arch/arm/sys/_do_kernel_call_intr.S +./minix/lib/libc/arch/arm/sys/_ipc.S +./minix/lib/libc/arch/arm/sys/brksize.S +./minix/lib/libc/arch/arm/sys/ipc_minix_kerninfo.S +./minix/lib/libc/arch/arm/sys/ucontext.S +./minix/lib/libc/arch/arm/sys/ucontextoffsets.cf +./minix/lib/libc/arch/i386/_cpufeature.c +./minix/lib/libc/arch/i386/_cpuid.S +./minix/lib/libc/arch/i386/get_bp.S +./minix/lib/libc/arch/i386/getprocessor.S +./minix/lib/libc/arch/i386/read_tsc.S +./minix/lib/libc/arch/i386/sys/__sigreturn.S +./minix/lib/libc/arch/i386/sys/_do_kernel_call_intr.S +./minix/lib/libc/arch/i386/sys/_ipc.S +./minix/lib/libc/arch/i386/sys/brksize.S +./minix/lib/libc/arch/i386/sys/ipc_minix_kerninfo.S +./minix/lib/libc/arch/i386/sys/ucontext.S +./minix/lib/libc/arch/i386/sys/ucontextoffsets.cf +./minix/lib/libc/gen/clock.c +./minix/lib/libc/gen/configfile.c +./minix/lib/libc/gen/fslib.c +./minix/lib/libc/gen/fsversion.c +./minix/lib/libc/gen/gcov.c +./minix/lib/libc/gen/gcov_flush.c +./minix/lib/libc/gen/getpass.c +./minix/lib/libc/gen/itoa.c +./minix/lib/libc/gen/mtab.c +./minix/lib/libc/gen/raise.c +./minix/lib/libc/gen/read_tsc_64.c +./minix/lib/libc/gen/stderr.c +./minix/lib/libc/sys/MISSING_SYSCALLS +./minix/lib/libc/sys/__getcwd.c +./minix/lib/libc/sys/__getlogin.c +./minix/lib/libc/sys/_exit.c +./minix/lib/libc/sys/_mcontext.c +./minix/lib/libc/sys/_ucontext.c +./minix/lib/libc/sys/accept.c +./minix/lib/libc/sys/access.c +./minix/lib/libc/sys/adjtime.c +./minix/lib/libc/sys/bind.c +./minix/lib/libc/sys/brk.c +./minix/lib/libc/sys/chdir.c +./minix/lib/libc/sys/chmod.c +./minix/lib/libc/sys/chown.c +./minix/lib/libc/sys/chroot.c +./minix/lib/libc/sys/clock_getres.c +./minix/lib/libc/sys/clock_gettime.c +./minix/lib/libc/sys/clock_settime.c +./minix/lib/libc/sys/close.c +./minix/lib/libc/sys/connect.c +./minix/lib/libc/sys/dup.c +./minix/lib/libc/sys/dup2.c +./minix/lib/libc/sys/environ.c +./minix/lib/libc/sys/execve.c +./minix/lib/libc/sys/fchmod.c +./minix/lib/libc/sys/fchown.c +./minix/lib/libc/sys/fcntl.c +./minix/lib/libc/sys/flock.c +./minix/lib/libc/sys/fork.c +./minix/lib/libc/sys/fpathconf.c +./minix/lib/libc/sys/fstatfs.c +./minix/lib/libc/sys/fstatvfs.c +./minix/lib/libc/sys/fsync.c +./minix/lib/libc/sys/ftruncate.c +./minix/lib/libc/sys/futimens.c +./minix/lib/libc/sys/futimes.c +./minix/lib/libc/sys/gcov_flush_sys.c +./minix/lib/libc/sys/getdents.c +./minix/lib/libc/sys/getegid.c +./minix/lib/libc/sys/geteuid.c +./minix/lib/libc/sys/getgid.c +./minix/lib/libc/sys/getgroups.c +./minix/lib/libc/sys/getitimer.c +./minix/lib/libc/sys/getpeername.c +./minix/lib/libc/sys/getpgrp.c +./minix/lib/libc/sys/getpid.c +./minix/lib/libc/sys/getppid.c +./minix/lib/libc/sys/getrlimit.c +./minix/lib/libc/sys/getrusage.c +./minix/lib/libc/sys/getsid.c +./minix/lib/libc/sys/getsockname.c +./minix/lib/libc/sys/getsockopt.c +./minix/lib/libc/sys/gettimeofday.c +./minix/lib/libc/sys/getuid.c +./minix/lib/libc/sys/getvfsstat.c +./minix/lib/libc/sys/init.c +./minix/lib/libc/sys/issetugid.c +./minix/lib/libc/sys/kernel_utils.c +./minix/lib/libc/sys/kill.c +./minix/lib/libc/sys/link.c +./minix/lib/libc/sys/listen.c +./minix/lib/libc/sys/loadname.c +./minix/lib/libc/sys/lseek.c +./minix/lib/libc/sys/lutimes.c +./minix/lib/libc/sys/m_closefrom.c +./minix/lib/libc/sys/minix_rs.c +./minix/lib/libc/sys/mkdir.c +./minix/lib/libc/sys/mkfifo.c +./minix/lib/libc/sys/mknod.c +./minix/lib/libc/sys/mmap.c +./minix/lib/libc/sys/mount.c +./minix/lib/libc/sys/nanosleep.c +./minix/lib/libc/sys/open.c +./minix/lib/libc/sys/pathconf.c +./minix/lib/libc/sys/pipe.c +./minix/lib/libc/sys/posix_spawn.c +./minix/lib/libc/sys/pread.c +./minix/lib/libc/sys/priority.c +./minix/lib/libc/sys/ptrace.c +./minix/lib/libc/sys/pwrite.c +./minix/lib/libc/sys/read.c +./minix/lib/libc/sys/readlink.c +./minix/lib/libc/sys/reboot.c +./minix/lib/libc/sys/recvfrom.c +./minix/lib/libc/sys/recvmsg.c +./minix/lib/libc/sys/rename.c +./minix/lib/libc/sys/rmdir.c +./minix/lib/libc/sys/sbrk.c +./minix/lib/libc/sys/select.c +./minix/lib/libc/sys/sem.c +./minix/lib/libc/sys/sendmsg.c +./minix/lib/libc/sys/sendto.c +./minix/lib/libc/sys/setgid.c +./minix/lib/libc/sys/setgroups.c +./minix/lib/libc/sys/setitimer.c +./minix/lib/libc/sys/setpgid.c +./minix/lib/libc/sys/setrlimit.c +./minix/lib/libc/sys/setsid.c +./minix/lib/libc/sys/setsockopt.c +./minix/lib/libc/sys/settimeofday.c +./minix/lib/libc/sys/setuid.c +./minix/lib/libc/sys/shmat.c +./minix/lib/libc/sys/shmctl.c +./minix/lib/libc/sys/shmget.c +./minix/lib/libc/sys/shutdown.c +./minix/lib/libc/sys/sigaction.c +./minix/lib/libc/sys/sigpending.c +./minix/lib/libc/sys/sigprocmask.c +./minix/lib/libc/sys/sigreturn.c +./minix/lib/libc/sys/sigsuspend.c +./minix/lib/libc/sys/sizeup.c +./minix/lib/libc/sys/socket.c +./minix/lib/libc/sys/socketpair.c +./minix/lib/libc/sys/sprofile.c +./minix/lib/libc/sys/stat.c +./minix/lib/libc/sys/statvfs.c +./minix/lib/libc/sys/stime.c +./minix/lib/libc/sys/svrctl.c +./minix/lib/libc/sys/symlink.c +./minix/lib/libc/sys/sync.c +./minix/lib/libc/sys/syscall.c +./minix/lib/libc/sys/truncate.c +./minix/lib/libc/sys/umask.c +./minix/lib/libc/sys/unlink.c +./minix/lib/libc/sys/utimensat.c +./minix/lib/libc/sys/utimes.c +./minix/lib/libc/sys/vectorio.c +./minix/lib/libc/sys/vfork.c +./minix/lib/libc/sys/wait4.c +./minix/lib/libc/sys/write.c +./minix/lib/libchardriver/Makefile +./minix/lib/libchardriver/chardriver.c +./minix/lib/libclkconf/Makefile +./minix/lib/libclkconf/clkconf.c +./minix/lib/libddekit/Makefile +./minix/lib/libddekit/build/Makefile +./minix/lib/libddekit/src/common.h +./minix/lib/libddekit/src/condvar.c +./minix/lib/libddekit/src/dde.c +./minix/lib/libddekit/src/dde.h +./minix/lib/libddekit/src/debug.h +./minix/lib/libddekit/src/initcall.c +./minix/lib/libddekit/src/irq.c +./minix/lib/libddekit/src/irq.h +./minix/lib/libddekit/src/lock.c +./minix/lib/libddekit/src/mem.c +./minix/lib/libddekit/src/msg_queue.c +./minix/lib/libddekit/src/panic.c +./minix/lib/libddekit/src/pci.c +./minix/lib/libddekit/src/pgtab.c +./minix/lib/libddekit/src/printf.c +./minix/lib/libddekit/src/resource.c +./minix/lib/libddekit/src/semaphore.c +./minix/lib/libddekit/src/thread.c +./minix/lib/libddekit/src/thread.h +./minix/lib/libddekit/src/timer.c +./minix/lib/libddekit/src/timer.h +./minix/lib/libddekit/src/usb_client.c +./minix/lib/libddekit/src/usb_server.c +./minix/lib/libddekit/src/util.h +./minix/lib/libdevman/Makefile +./minix/lib/libdevman/generic.c +./minix/lib/libdevman/local.h +./minix/lib/libdevman/usb.c +./minix/lib/libexec/Makefile +./minix/lib/libexec/exec_elf.c +./minix/lib/libexec/exec_general.c +./minix/lib/libexec/libexec.h +./minix/lib/libfsdriver/Makefile +./minix/lib/libfsdriver/call.c +./minix/lib/libfsdriver/dentry.c +./minix/lib/libfsdriver/fsdriver.c +./minix/lib/libfsdriver/fsdriver.h +./minix/lib/libfsdriver/lookup.c +./minix/lib/libfsdriver/table.c +./minix/lib/libfsdriver/utility.c +./minix/lib/libgcc_s_empty/Makefile +./minix/lib/libgcc_s_empty/empty.c +./minix/lib/libgcc_s_empty/libgcc_s_empty.map +./minix/lib/libgcc_s_empty/shlib_version +./minix/lib/libgpio/Makefile +./minix/lib/libgpio/gpio_omap.c +./minix/lib/libgpio/gpio_omap.h +./minix/lib/libhgfs/Makefile +./minix/lib/libhgfs/attr.c +./minix/lib/libhgfs/backdoor.S +./minix/lib/libhgfs/channel.c +./minix/lib/libhgfs/const.h +./minix/lib/libhgfs/dir.c +./minix/lib/libhgfs/error.c +./minix/lib/libhgfs/file.c +./minix/lib/libhgfs/glo.h +./minix/lib/libhgfs/hgfs.c +./minix/lib/libhgfs/inc.h +./minix/lib/libhgfs/info.c +./minix/lib/libhgfs/link.c +./minix/lib/libhgfs/path.c +./minix/lib/libhgfs/proto.h +./minix/lib/libhgfs/rpc.c +./minix/lib/libhgfs/time.c +./minix/lib/libhgfs/type.h +./minix/lib/libi2cdriver/Makefile +./minix/lib/libi2cdriver/i2cdriver.c +./minix/lib/libinputdriver/Makefile +./minix/lib/libinputdriver/inputdriver.c +./minix/lib/liblwip/Makefile +./minix/lib/liblwip/dist/CHANGELOG +./minix/lib/liblwip/dist/COPYING +./minix/lib/liblwip/dist/FILES +./minix/lib/liblwip/dist/README +./minix/lib/liblwip/dist/UPGRADING +./minix/lib/liblwip/dist/doc/FILES +./minix/lib/liblwip/dist/doc/NO_SYS_SampleCode.c +./minix/lib/liblwip/dist/doc/contrib.txt +./minix/lib/liblwip/dist/doc/doxygen/generate.bat +./minix/lib/liblwip/dist/doc/doxygen/generate.sh +./minix/lib/liblwip/dist/doc/doxygen/lwip.Doxyfile +./minix/lib/liblwip/dist/doc/doxygen/main_page.h +./minix/lib/liblwip/dist/doc/doxygen/output/index.html +./minix/lib/liblwip/dist/doc/mdns.txt +./minix/lib/liblwip/dist/doc/mqtt_client.txt +./minix/lib/liblwip/dist/doc/ppp.txt +./minix/lib/liblwip/dist/doc/rawapi.txt +./minix/lib/liblwip/dist/doc/savannah.txt +./minix/lib/liblwip/dist/doc/sys_arch.txt +./minix/lib/liblwip/dist/src/FILES +./minix/lib/liblwip/dist/src/Filelists.mk +./minix/lib/liblwip/dist/src/api/api_lib.c +./minix/lib/liblwip/dist/src/api/api_msg.c +./minix/lib/liblwip/dist/src/api/err.c +./minix/lib/liblwip/dist/src/api/if_api.c +./minix/lib/liblwip/dist/src/api/netbuf.c +./minix/lib/liblwip/dist/src/api/netdb.c +./minix/lib/liblwip/dist/src/api/netifapi.c +./minix/lib/liblwip/dist/src/api/sockets.c +./minix/lib/liblwip/dist/src/api/tcpip.c +./minix/lib/liblwip/dist/src/apps/httpd/fs.c +./minix/lib/liblwip/dist/src/apps/httpd/fs/404.html +./minix/lib/liblwip/dist/src/apps/httpd/fs/img/sics.gif +./minix/lib/liblwip/dist/src/apps/httpd/fs/index.html +./minix/lib/liblwip/dist/src/apps/httpd/fsdata.c +./minix/lib/liblwip/dist/src/apps/httpd/fsdata.h +./minix/lib/liblwip/dist/src/apps/httpd/httpd.c +./minix/lib/liblwip/dist/src/apps/httpd/httpd_structs.h +./minix/lib/liblwip/dist/src/apps/httpd/makefsdata/makefsdata +./minix/lib/liblwip/dist/src/apps/httpd/makefsdata/makefsdata.c +./minix/lib/liblwip/dist/src/apps/httpd/makefsdata/readme.txt +./minix/lib/liblwip/dist/src/apps/lwiperf/lwiperf.c +./minix/lib/liblwip/dist/src/apps/mdns/mdns.c +./minix/lib/liblwip/dist/src/apps/mqtt/mqtt.c +./minix/lib/liblwip/dist/src/apps/netbiosns/netbiosns.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_asn1.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_asn1.h +./minix/lib/liblwip/dist/src/apps/snmp/snmp_core.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_core_priv.h +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_icmp.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_interfaces.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_ip.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_snmp.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_system.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_tcp.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_mib2_udp.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_msg.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_msg.h +./minix/lib/liblwip/dist/src/apps/snmp/snmp_netconn.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_pbuf_stream.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_pbuf_stream.h +./minix/lib/liblwip/dist/src/apps/snmp/snmp_raw.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_scalar.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_snmpv2_framework.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_snmpv2_usm.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_table.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_threadsync.c +./minix/lib/liblwip/dist/src/apps/snmp/snmp_traps.c +./minix/lib/liblwip/dist/src/apps/snmp/snmpv3.c +./minix/lib/liblwip/dist/src/apps/snmp/snmpv3_mbedtls.c +./minix/lib/liblwip/dist/src/apps/snmp/snmpv3_priv.h +./minix/lib/liblwip/dist/src/apps/sntp/sntp.c +./minix/lib/liblwip/dist/src/apps/tftp/tftp_server.c +./minix/lib/liblwip/dist/src/core/def.c +./minix/lib/liblwip/dist/src/core/dns.c +./minix/lib/liblwip/dist/src/core/inet_chksum.c +./minix/lib/liblwip/dist/src/core/init.c +./minix/lib/liblwip/dist/src/core/ip.c +./minix/lib/liblwip/dist/src/core/ipv4/autoip.c +./minix/lib/liblwip/dist/src/core/ipv4/dhcp.c +./minix/lib/liblwip/dist/src/core/ipv4/etharp.c +./minix/lib/liblwip/dist/src/core/ipv4/icmp.c +./minix/lib/liblwip/dist/src/core/ipv4/igmp.c +./minix/lib/liblwip/dist/src/core/ipv4/ip4.c +./minix/lib/liblwip/dist/src/core/ipv4/ip4_addr.c +./minix/lib/liblwip/dist/src/core/ipv4/ip4_frag.c +./minix/lib/liblwip/dist/src/core/ipv6/dhcp6.c +./minix/lib/liblwip/dist/src/core/ipv6/ethip6.c +./minix/lib/liblwip/dist/src/core/ipv6/icmp6.c +./minix/lib/liblwip/dist/src/core/ipv6/inet6.c +./minix/lib/liblwip/dist/src/core/ipv6/ip6.c +./minix/lib/liblwip/dist/src/core/ipv6/ip6_addr.c +./minix/lib/liblwip/dist/src/core/ipv6/ip6_frag.c +./minix/lib/liblwip/dist/src/core/ipv6/mld6.c +./minix/lib/liblwip/dist/src/core/ipv6/nd6.c +./minix/lib/liblwip/dist/src/core/mem.c +./minix/lib/liblwip/dist/src/core/memp.c +./minix/lib/liblwip/dist/src/core/netif.c +./minix/lib/liblwip/dist/src/core/pbuf.c +./minix/lib/liblwip/dist/src/core/raw.c +./minix/lib/liblwip/dist/src/core/stats.c +./minix/lib/liblwip/dist/src/core/sys.c +./minix/lib/liblwip/dist/src/core/tcp.c +./minix/lib/liblwip/dist/src/core/tcp_in.c +./minix/lib/liblwip/dist/src/core/tcp_out.c +./minix/lib/liblwip/dist/src/core/timeouts.c +./minix/lib/liblwip/dist/src/core/udp.c +./minix/lib/liblwip/dist/src/include/lwip/api.h +./minix/lib/liblwip/dist/src/include/lwip/apps/FILES +./minix/lib/liblwip/dist/src/include/lwip/apps/fs.h +./minix/lib/liblwip/dist/src/include/lwip/apps/httpd.h +./minix/lib/liblwip/dist/src/include/lwip/apps/httpd_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/lwiperf.h +./minix/lib/liblwip/dist/src/include/lwip/apps/mdns.h +./minix/lib/liblwip/dist/src/include/lwip/apps/mdns_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/mdns_priv.h +./minix/lib/liblwip/dist/src/include/lwip/apps/mqtt.h +./minix/lib/liblwip/dist/src/include/lwip/apps/mqtt_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/netbiosns.h +./minix/lib/liblwip/dist/src/include/lwip/apps/netbiosns_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_core.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_mib2.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_scalar.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_snmpv2_framework.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_snmpv2_usm.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_table.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmp_threadsync.h +./minix/lib/liblwip/dist/src/include/lwip/apps/snmpv3.h +./minix/lib/liblwip/dist/src/include/lwip/apps/sntp.h +./minix/lib/liblwip/dist/src/include/lwip/apps/sntp_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/tftp_opts.h +./minix/lib/liblwip/dist/src/include/lwip/apps/tftp_server.h +./minix/lib/liblwip/dist/src/include/lwip/arch.h +./minix/lib/liblwip/dist/src/include/lwip/autoip.h +./minix/lib/liblwip/dist/src/include/lwip/debug.h +./minix/lib/liblwip/dist/src/include/lwip/def.h +./minix/lib/liblwip/dist/src/include/lwip/dhcp.h +./minix/lib/liblwip/dist/src/include/lwip/dhcp6.h +./minix/lib/liblwip/dist/src/include/lwip/dns.h +./minix/lib/liblwip/dist/src/include/lwip/err.h +./minix/lib/liblwip/dist/src/include/lwip/errno.h +./minix/lib/liblwip/dist/src/include/lwip/etharp.h +./minix/lib/liblwip/dist/src/include/lwip/ethip6.h +./minix/lib/liblwip/dist/src/include/lwip/icmp.h +./minix/lib/liblwip/dist/src/include/lwip/icmp6.h +./minix/lib/liblwip/dist/src/include/lwip/if_api.h +./minix/lib/liblwip/dist/src/include/lwip/igmp.h +./minix/lib/liblwip/dist/src/include/lwip/inet.h +./minix/lib/liblwip/dist/src/include/lwip/inet_chksum.h +./minix/lib/liblwip/dist/src/include/lwip/init.h +./minix/lib/liblwip/dist/src/include/lwip/ip.h +./minix/lib/liblwip/dist/src/include/lwip/ip4.h +./minix/lib/liblwip/dist/src/include/lwip/ip4_addr.h +./minix/lib/liblwip/dist/src/include/lwip/ip4_frag.h +./minix/lib/liblwip/dist/src/include/lwip/ip6.h +./minix/lib/liblwip/dist/src/include/lwip/ip6_addr.h +./minix/lib/liblwip/dist/src/include/lwip/ip6_frag.h +./minix/lib/liblwip/dist/src/include/lwip/ip6_zone.h +./minix/lib/liblwip/dist/src/include/lwip/ip_addr.h +./minix/lib/liblwip/dist/src/include/lwip/mem.h +./minix/lib/liblwip/dist/src/include/lwip/memp.h +./minix/lib/liblwip/dist/src/include/lwip/mld6.h +./minix/lib/liblwip/dist/src/include/lwip/nd6.h +./minix/lib/liblwip/dist/src/include/lwip/netbuf.h +./minix/lib/liblwip/dist/src/include/lwip/netdb.h +./minix/lib/liblwip/dist/src/include/lwip/netif.h +./minix/lib/liblwip/dist/src/include/lwip/netifapi.h +./minix/lib/liblwip/dist/src/include/lwip/opt.h +./minix/lib/liblwip/dist/src/include/lwip/pbuf.h +./minix/lib/liblwip/dist/src/include/lwip/priv/api_msg.h +./minix/lib/liblwip/dist/src/include/lwip/priv/memp_priv.h +./minix/lib/liblwip/dist/src/include/lwip/priv/memp_std.h +./minix/lib/liblwip/dist/src/include/lwip/priv/nd6_priv.h +./minix/lib/liblwip/dist/src/include/lwip/priv/sockets_priv.h +./minix/lib/liblwip/dist/src/include/lwip/priv/tcp_priv.h +./minix/lib/liblwip/dist/src/include/lwip/priv/tcpip_priv.h +./minix/lib/liblwip/dist/src/include/lwip/prot/autoip.h +./minix/lib/liblwip/dist/src/include/lwip/prot/dhcp.h +./minix/lib/liblwip/dist/src/include/lwip/prot/dns.h +./minix/lib/liblwip/dist/src/include/lwip/prot/etharp.h +./minix/lib/liblwip/dist/src/include/lwip/prot/ethernet.h +./minix/lib/liblwip/dist/src/include/lwip/prot/icmp.h +./minix/lib/liblwip/dist/src/include/lwip/prot/icmp6.h +./minix/lib/liblwip/dist/src/include/lwip/prot/igmp.h +./minix/lib/liblwip/dist/src/include/lwip/prot/ip.h +./minix/lib/liblwip/dist/src/include/lwip/prot/ip4.h +./minix/lib/liblwip/dist/src/include/lwip/prot/ip6.h +./minix/lib/liblwip/dist/src/include/lwip/prot/mld6.h +./minix/lib/liblwip/dist/src/include/lwip/prot/nd6.h +./minix/lib/liblwip/dist/src/include/lwip/prot/tcp.h +./minix/lib/liblwip/dist/src/include/lwip/prot/udp.h +./minix/lib/liblwip/dist/src/include/lwip/raw.h +./minix/lib/liblwip/dist/src/include/lwip/sio.h +./minix/lib/liblwip/dist/src/include/lwip/snmp.h +./minix/lib/liblwip/dist/src/include/lwip/sockets.h +./minix/lib/liblwip/dist/src/include/lwip/stats.h +./minix/lib/liblwip/dist/src/include/lwip/sys.h +./minix/lib/liblwip/dist/src/include/lwip/tcp.h +./minix/lib/liblwip/dist/src/include/lwip/tcpip.h +./minix/lib/liblwip/dist/src/include/lwip/timeouts.h +./minix/lib/liblwip/dist/src/include/lwip/udp.h +./minix/lib/liblwip/dist/src/include/netif/etharp.h +./minix/lib/liblwip/dist/src/include/netif/ethernet.h +./minix/lib/liblwip/dist/src/include/netif/lowpan6.h +./minix/lib/liblwip/dist/src/include/netif/lowpan6_opts.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ccp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/chap-md5.h +./minix/lib/liblwip/dist/src/include/netif/ppp/chap-new.h +./minix/lib/liblwip/dist/src/include/netif/ppp/chap_ms.h +./minix/lib/liblwip/dist/src/include/netif/ppp/eap.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ecp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/eui64.h +./minix/lib/liblwip/dist/src/include/netif/ppp/fsm.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ipcp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ipv6cp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/lcp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/magic.h +./minix/lib/liblwip/dist/src/include/netif/ppp/mppe.h +./minix/lib/liblwip/dist/src/include/netif/ppp/polarssl/arc4.h +./minix/lib/liblwip/dist/src/include/netif/ppp/polarssl/des.h +./minix/lib/liblwip/dist/src/include/netif/ppp/polarssl/md4.h +./minix/lib/liblwip/dist/src/include/netif/ppp/polarssl/md5.h +./minix/lib/liblwip/dist/src/include/netif/ppp/polarssl/sha1.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ppp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ppp_impl.h +./minix/lib/liblwip/dist/src/include/netif/ppp/ppp_opts.h +./minix/lib/liblwip/dist/src/include/netif/ppp/pppapi.h +./minix/lib/liblwip/dist/src/include/netif/ppp/pppcrypt.h +./minix/lib/liblwip/dist/src/include/netif/ppp/pppdebug.h +./minix/lib/liblwip/dist/src/include/netif/ppp/pppol2tp.h +./minix/lib/liblwip/dist/src/include/netif/ppp/pppos.h +./minix/lib/liblwip/dist/src/include/netif/ppp/upap.h +./minix/lib/liblwip/dist/src/include/netif/ppp/vj.h +./minix/lib/liblwip/dist/src/include/netif/slipif.h +./minix/lib/liblwip/dist/src/include/posix/errno.h +./minix/lib/liblwip/dist/src/include/posix/net/if.h +./minix/lib/liblwip/dist/src/include/posix/netdb.h +./minix/lib/liblwip/dist/src/include/posix/sys/socket.h +./minix/lib/liblwip/dist/src/netif/FILES +./minix/lib/liblwip/dist/src/netif/ethernet.c +./minix/lib/liblwip/dist/src/netif/ethernetif.c +./minix/lib/liblwip/dist/src/netif/lowpan6.c +./minix/lib/liblwip/dist/src/netif/ppp/PPPD_FOLLOWUP +./minix/lib/liblwip/dist/src/netif/ppp/auth.c +./minix/lib/liblwip/dist/src/netif/ppp/ccp.c +./minix/lib/liblwip/dist/src/netif/ppp/chap-md5.c +./minix/lib/liblwip/dist/src/netif/ppp/chap-new.c +./minix/lib/liblwip/dist/src/netif/ppp/chap_ms.c +./minix/lib/liblwip/dist/src/netif/ppp/demand.c +./minix/lib/liblwip/dist/src/netif/ppp/eap.c +./minix/lib/liblwip/dist/src/netif/ppp/ecp.c +./minix/lib/liblwip/dist/src/netif/ppp/eui64.c +./minix/lib/liblwip/dist/src/netif/ppp/fsm.c +./minix/lib/liblwip/dist/src/netif/ppp/ipcp.c +./minix/lib/liblwip/dist/src/netif/ppp/ipv6cp.c +./minix/lib/liblwip/dist/src/netif/ppp/lcp.c +./minix/lib/liblwip/dist/src/netif/ppp/magic.c +./minix/lib/liblwip/dist/src/netif/ppp/mppe.c +./minix/lib/liblwip/dist/src/netif/ppp/multilink.c +./minix/lib/liblwip/dist/src/netif/ppp/polarssl/README +./minix/lib/liblwip/dist/src/netif/ppp/polarssl/arc4.c +./minix/lib/liblwip/dist/src/netif/ppp/polarssl/des.c +./minix/lib/liblwip/dist/src/netif/ppp/polarssl/md4.c +./minix/lib/liblwip/dist/src/netif/ppp/polarssl/md5.c +./minix/lib/liblwip/dist/src/netif/ppp/polarssl/sha1.c +./minix/lib/liblwip/dist/src/netif/ppp/ppp.c +./minix/lib/liblwip/dist/src/netif/ppp/pppapi.c +./minix/lib/liblwip/dist/src/netif/ppp/pppcrypt.c +./minix/lib/liblwip/dist/src/netif/ppp/pppol2tp.c +./minix/lib/liblwip/dist/src/netif/ppp/pppos.c +./minix/lib/liblwip/dist/src/netif/ppp/upap.c +./minix/lib/liblwip/dist/src/netif/ppp/utils.c +./minix/lib/liblwip/dist/src/netif/ppp/vj.c +./minix/lib/liblwip/dist/src/netif/slipif.c +./minix/lib/liblwip/dist/test/fuzz/Makefile +./minix/lib/liblwip/dist/test/fuzz/README +./minix/lib/liblwip/dist/test/fuzz/config.h +./minix/lib/liblwip/dist/test/fuzz/fuzz.c +./minix/lib/liblwip/dist/test/fuzz/inputs/arp/arp_req.bin +./minix/lib/liblwip/dist/test/fuzz/inputs/icmp/icmp_ping.bin +./minix/lib/liblwip/dist/test/fuzz/inputs/ipv6/neighbor_solicitation.bin +./minix/lib/liblwip/dist/test/fuzz/inputs/ipv6/router_adv.bin +./minix/lib/liblwip/dist/test/fuzz/inputs/tcp/tcp_syn.bin +./minix/lib/liblwip/dist/test/fuzz/inputs/udp/udp_port_5000.bin +./minix/lib/liblwip/dist/test/fuzz/lwipopts.h +./minix/lib/liblwip/dist/test/fuzz/output_to_pcap.sh +./minix/lib/liblwip/dist/test/unit/core/test_mem.c +./minix/lib/liblwip/dist/test/unit/core/test_mem.h +./minix/lib/liblwip/dist/test/unit/core/test_pbuf.c +./minix/lib/liblwip/dist/test/unit/core/test_pbuf.h +./minix/lib/liblwip/dist/test/unit/dhcp/test_dhcp.c +./minix/lib/liblwip/dist/test/unit/dhcp/test_dhcp.h +./minix/lib/liblwip/dist/test/unit/etharp/test_etharp.c +./minix/lib/liblwip/dist/test/unit/etharp/test_etharp.h +./minix/lib/liblwip/dist/test/unit/lwip_check.h +./minix/lib/liblwip/dist/test/unit/lwip_unittests.c +./minix/lib/liblwip/dist/test/unit/lwipopts.h +./minix/lib/liblwip/dist/test/unit/mdns/test_mdns.c +./minix/lib/liblwip/dist/test/unit/mdns/test_mdns.h +./minix/lib/liblwip/dist/test/unit/tcp/tcp_helper.c +./minix/lib/liblwip/dist/test/unit/tcp/tcp_helper.h +./minix/lib/liblwip/dist/test/unit/tcp/test_tcp.c +./minix/lib/liblwip/dist/test/unit/tcp/test_tcp.h +./minix/lib/liblwip/dist/test/unit/tcp/test_tcp_oos.c +./minix/lib/liblwip/dist/test/unit/tcp/test_tcp_oos.h +./minix/lib/liblwip/dist/test/unit/udp/test_udp.c +./minix/lib/liblwip/dist/test/unit/udp/test_udp.h +./minix/lib/liblwip/lib/arch/cc.h +./minix/lib/liblwip/lib/core/Makefile.inc +./minix/lib/liblwip/lib/lwiphooks.h +./minix/lib/liblwip/lib/lwipopts.h +./minix/lib/liblwip/lib/netif/Makefile.inc +./minix/lib/liblwip/patches/0001-MINIX-3-only-mark-various-functions-as-weak.patch +./minix/lib/liblwip/patches/0003-MINIX-3-only-ignore-IPv6-Router-Advertisements.patch +./minix/lib/liblwip/patches/0004-MINIX-3-only-avoid-large-contiguous-allocations.patch +./minix/lib/libmagicrt/include/common/ut/uthash.h +./minix/lib/libmagicrt/include/common/ut/utlist.h +./minix/lib/libmagicrt/include/magic.h +./minix/lib/libmagicrt/include/magic_analysis.h +./minix/lib/libmagicrt/include/magic_asr.h +./minix/lib/libmagicrt/include/magic_def.h +./minix/lib/libmagicrt/include/magic_eval.h +./minix/lib/libmagicrt/include/magic_eval_lib.h +./minix/lib/libmagicrt/include/magic_extern.h +./minix/lib/libmagicrt/include/magic_mem.h +./minix/lib/libmagicrt/include/magic_range.h +./minix/lib/libmagicrt/include/magic_real_mem.h +./minix/lib/libmagicrt/include/magic_selement.h +./minix/lib/libmagicrt/include/magic_sentry.h +./minix/lib/libmagicrt/include/magic_splay_tree.h +./minix/lib/libmagicrt/include/magic_structs.h +./minix/lib/libmagicrt/include/st/callback.h +./minix/lib/libmagicrt/include/st/cb_template.h +./minix/lib/libmagicrt/include/st/metadata_transfer.h +./minix/lib/libmagicrt/include/st/os_callback.h +./minix/lib/libmagicrt/include/st/private.h +./minix/lib/libmagicrt/include/st/special.h +./minix/lib/libmagicrt/include/st/state_transfer.h +./minix/lib/libmagicrt/include/st/typedefs.h +./minix/lib/libmagicrt/magic.c +./minix/lib/libmagicrt/magic_analysis.c +./minix/lib/libmagicrt/magic_asr.c +./minix/lib/libmagicrt/magic_ds.c +./minix/lib/libmagicrt/magic_eval.c +./minix/lib/libmagicrt/magic_eval_lib.c +./minix/lib/libmagicrt/magic_mem.c +./minix/lib/libmagicrt/magic_range.c +./minix/lib/libmagicrt/magic_selement.c +./minix/lib/libmagicrt/magic_sentry.c +./minix/lib/libmagicrt/magic_splay_tree.c +./minix/lib/libmagicrt/magic_st.c +./minix/lib/libmagicrt/magic_util.c +./minix/lib/libminc/_snprintf.c +./minix/lib/libminc/arch/i386/Makefile.libc.inc +./minix/lib/libminc/atoi.c +./minix/lib/libminc/fputs.c +./minix/lib/libminc/strtol.c +./minix/lib/libminixfs/Makefile +./minix/lib/libminixfs/bio.c +./minix/lib/libminixfs/cache.c +./minix/lib/libminixfs/inc.h +./minix/lib/libmthread/Makefile +./minix/lib/libmthread/allocate.c +./minix/lib/libmthread/attribute.c +./minix/lib/libmthread/condition.c +./minix/lib/libmthread/event.c +./minix/lib/libmthread/global.h +./minix/lib/libmthread/key.c +./minix/lib/libmthread/misc.c +./minix/lib/libmthread/mutex.c +./minix/lib/libmthread/proto.h +./minix/lib/libmthread/pthread_compat.c +./minix/lib/libmthread/queue.c +./minix/lib/libmthread/rwlock.c +./minix/lib/libmthread/scheduler.c +./minix/lib/libmthread/shlib_version +./minix/lib/libnetdriver/Makefile +./minix/lib/libnetdriver/netdriver.c +./minix/lib/libnetdriver/netdriver.h +./minix/lib/libnetdriver/portio.c +./minix/lib/libpuffs/const.h +./minix/lib/libpuffs/fs.h +./minix/lib/libpuffs/glo.h +./minix/lib/libpuffs/inode.c +./minix/lib/libpuffs/link.c +./minix/lib/libpuffs/main.c +./minix/lib/libpuffs/misc.c +./minix/lib/libpuffs/mount.c +./minix/lib/libpuffs/open.c +./minix/lib/libpuffs/path.c +./minix/lib/libpuffs/protect.c +./minix/lib/libpuffs/proto.h +./minix/lib/libpuffs/read.c +./minix/lib/libpuffs/stadir.c +./minix/lib/libpuffs/table.c +./minix/lib/libpuffs/time.c +./minix/lib/libpuffs/utility.c +./minix/lib/libsffs/Makefile +./minix/lib/libsffs/const.h +./minix/lib/libsffs/dentry.c +./minix/lib/libsffs/glo.h +./minix/lib/libsffs/handle.c +./minix/lib/libsffs/inc.h +./minix/lib/libsffs/inode.c +./minix/lib/libsffs/inode.h +./minix/lib/libsffs/link.c +./minix/lib/libsffs/lookup.c +./minix/lib/libsffs/main.c +./minix/lib/libsffs/misc.c +./minix/lib/libsffs/mount.c +./minix/lib/libsffs/name.c +./minix/lib/libsffs/path.c +./minix/lib/libsffs/proto.h +./minix/lib/libsffs/read.c +./minix/lib/libsffs/stat.c +./minix/lib/libsffs/table.c +./minix/lib/libsffs/verify.c +./minix/lib/libsffs/write.c +./minix/lib/libsockdriver/Makefile +./minix/lib/libsockevent/sockevent_proc.c +./minix/lib/libsockevent/sockevent_proc.h +./minix/lib/libsys/alloc_util.c +./minix/lib/libsys/arch/earm/frclock_util.c +./minix/lib/libsys/arch/earm/spin.c +./minix/lib/libsys/arch/earm/tsc_util.c +./minix/lib/libsys/arch/i386/Makefile.inc +./minix/lib/libsys/arch/i386/get_randomness.c +./minix/lib/libsys/arch/i386/getidle.c +./minix/lib/libsys/arch/i386/ser_putc.c +./minix/lib/libsys/arch/i386/spin.c +./minix/lib/libsys/arch/i386/sys_eniop.c +./minix/lib/libsys/arch/i386/sys_in.c +./minix/lib/libsys/arch/i386/sys_out.c +./minix/lib/libsys/arch/i386/sys_readbios.c +./minix/lib/libsys/arch/i386/sys_sdevio.c +./minix/lib/libsys/arch/i386/sys_umap_remote.c +./minix/lib/libsys/arch/i386/sys_vinb.c +./minix/lib/libsys/arch/i386/sys_vinl.c +./minix/lib/libsys/arch/i386/sys_vinw.c +./minix/lib/libsys/arch/i386/sys_voutb.c +./minix/lib/libsys/arch/i386/sys_voutl.c +./minix/lib/libsys/arch/i386/sys_voutw.c +./minix/lib/libsys/arch/i386/tsc_util.c +./minix/lib/libsys/arch/i386/vbox.c +./minix/lib/libsys/assert.c +./minix/lib/libsys/asynsend.c +./minix/lib/libsys/clock_time.c +./minix/lib/libsys/closenb.c +./minix/lib/libsys/copyfd.c +./minix/lib/libsys/ds.c +./minix/lib/libsys/env_get_prm.c +./minix/lib/libsys/env_panic.c +./minix/lib/libsys/env_parse.c +./minix/lib/libsys/fkey_ctl.c +./minix/lib/libsys/gcov.c +./minix/lib/libsys/getepinfo.c +./minix/lib/libsys/getprocnr.c +./minix/lib/libsys/getsysinfo.c +./minix/lib/libsys/getticks.c +./minix/lib/libsys/getuptime.c +./minix/lib/libsys/kernel_call.c +./minix/lib/libsys/kprintf.c +./minix/lib/libsys/kputc.c +./minix/lib/libsys/kputs.c +./minix/lib/libsys/llvm_gcov.c +./minix/lib/libsys/mapdriver.c +./minix/lib/libsys/optset.c +./minix/lib/libsys/panic.c +./minix/lib/libsys/pci.h +./minix/lib/libsys/pci_attr_r16.c +./minix/lib/libsys/pci_attr_r32.c +./minix/lib/libsys/pci_attr_r8.c +./minix/lib/libsys/pci_attr_w16.c +./minix/lib/libsys/pci_attr_w32.c +./minix/lib/libsys/pci_attr_w8.c +./minix/lib/libsys/pci_del_acl.c +./minix/lib/libsys/pci_dev_name.c +./minix/lib/libsys/pci_find_dev.c +./minix/lib/libsys/pci_first_dev.c +./minix/lib/libsys/pci_get_bar.c +./minix/lib/libsys/pci_ids.c +./minix/lib/libsys/pci_init.c +./minix/lib/libsys/pci_next_dev.c +./minix/lib/libsys/pci_rescan_bus.c +./minix/lib/libsys/pci_reserve.c +./minix/lib/libsys/pci_set_acl.c +./minix/lib/libsys/pci_slot_name.c +./minix/lib/libsys/proceventmask.c +./minix/lib/libsys/safecopies.c +./minix/lib/libsys/sched_start.c +./minix/lib/libsys/sched_stop.c +./minix/lib/libsys/sef.c +./minix/lib/libsys/sef_fi.c +./minix/lib/libsys/sef_gcov.c +./minix/lib/libsys/sef_init.c +./minix/lib/libsys/sef_liveupdate.c +./minix/lib/libsys/sef_llvm.c +./minix/lib/libsys/sef_ping.c +./minix/lib/libsys/sef_signal.c +./minix/lib/libsys/sef_st.c +./minix/lib/libsys/shlib_version +./minix/lib/libsys/socketpath.c +./minix/lib/libsys/sqrt_approx.c +./minix/lib/libsys/srv_fork.c +./minix/lib/libsys/srv_kill.c +./minix/lib/libsys/stacktrace.c +./minix/lib/libsys/sys_abort.c +./minix/lib/libsys/sys_clear.c +./minix/lib/libsys/sys_diagctl.c +./minix/lib/libsys/sys_endsig.c +./minix/lib/libsys/sys_exec.c +./minix/lib/libsys/sys_exit.c +./minix/lib/libsys/sys_fork.c +./minix/lib/libsys/sys_getinfo.c +./minix/lib/libsys/sys_getsig.c +./minix/lib/libsys/sys_hz.c +./minix/lib/libsys/sys_irqctl.c +./minix/lib/libsys/sys_kill.c +./minix/lib/libsys/sys_mcontext.c +./minix/lib/libsys/sys_memset.c +./minix/lib/libsys/sys_padconf.c +./minix/lib/libsys/sys_physcopy.c +./minix/lib/libsys/sys_privctl.c +./minix/lib/libsys/sys_runctl.c +./minix/lib/libsys/sys_safecopy.c +./minix/lib/libsys/sys_safememset.c +./minix/lib/libsys/sys_schedctl.c +./minix/lib/libsys/sys_schedule.c +./minix/lib/libsys/sys_setalarm.c +./minix/lib/libsys/sys_setgrant.c +./minix/lib/libsys/sys_settime.c +./minix/lib/libsys/sys_sigreturn.c +./minix/lib/libsys/sys_sigsend.c +./minix/lib/libsys/sys_sprof.c +./minix/lib/libsys/sys_statectl.c +./minix/lib/libsys/sys_stime.c +./minix/lib/libsys/sys_times.c +./minix/lib/libsys/sys_trace.c +./minix/lib/libsys/sys_umap.c +./minix/lib/libsys/sys_update.c +./minix/lib/libsys/sys_vircopy.c +./minix/lib/libsys/sys_vmctl.c +./minix/lib/libsys/sys_vsafecopy.c +./minix/lib/libsys/sys_vtimer.c +./minix/lib/libsys/sys_vumap.c +./minix/lib/libsys/syslib.h +./minix/lib/libsys/sysutil.h +./minix/lib/libsys/taskcall.c +./minix/lib/libsys/tickdelay.c +./minix/lib/libsys/timers.c +./minix/lib/libsys/vm_cache.c +./minix/lib/libsys/vm_exit.c +./minix/lib/libsys/vm_fork.c +./minix/lib/libsys/vm_getrusage.c +./minix/lib/libsys/vm_info.c +./minix/lib/libsys/vm_map_phys.c +./minix/lib/libsys/vm_memctl.c +./minix/lib/libsys/vm_prepare.c +./minix/lib/libsys/vm_procctl.c +./minix/lib/libsys/vm_set_priv.c +./minix/lib/libsys/vm_update.c +./minix/lib/libtimers/Makefile +./minix/lib/libtimers/tmrs_clr.c +./minix/lib/libtimers/tmrs_exp.c +./minix/lib/libtimers/tmrs_set.c +./minix/lib/libusb/Makefile +./minix/lib/libusb/usb.c +./minix/lib/libvassert/Makefile +./minix/lib/libvassert/backdoor.S +./minix/lib/libvassert/vassert.c +./minix/lib/libvassert/vassert.h +./minix/lib/libvboxfs/Makefile +./minix/lib/libvboxfs/attr.c +./minix/lib/libvboxfs/dir.c +./minix/lib/libvboxfs/file.c +./minix/lib/libvboxfs/glo.h +./minix/lib/libvboxfs/handle.c +./minix/lib/libvboxfs/inc.h +./minix/lib/libvboxfs/info.c +./minix/lib/libvboxfs/link.c +./minix/lib/libvboxfs/path.c +./minix/lib/libvboxfs/proto.h +./minix/lib/libvboxfs/vboxfs.c +./minix/lib/libvboxfs/vboxfs.h +./minix/lib/libvirtio/Makefile +./minix/lib/libvirtio/virtio.c +./minix/lib/libvirtio/virtio_ring.h +./minix/lib/libvtreefs/Makefile +./minix/lib/libvtreefs/extra.c +./minix/lib/libvtreefs/file.c +./minix/lib/libvtreefs/glo.h +./minix/lib/libvtreefs/inc.h +./minix/lib/libvtreefs/inode.c +./minix/lib/libvtreefs/inode.h +./minix/lib/libvtreefs/link.c +./minix/lib/libvtreefs/mount.c +./minix/lib/libvtreefs/path.c +./minix/lib/libvtreefs/proto.h +./minix/lib/libvtreefs/sdbm.c +./minix/lib/libvtreefs/stadir.c +./minix/lib/libvtreefs/table.c +./minix/lib/libvtreefs/vtreefs.c +./minix/llvm/Makefile +./minix/llvm/Makefile.inc +./minix/llvm/include/common/util/stdlib.h +./minix/llvm/include/common/util/util_def.h +./minix/llvm/include/magic_common.h +./minix/llvm/passes/Makefile.inc +./minix/llvm/passes/WeakAliasModuleOverride/Makefile +./minix/llvm/passes/WeakAliasModuleOverride/WeakAliasModuleOverride.cpp +./minix/llvm/passes/asr/ASRPass.cpp +./minix/llvm/passes/asr/Makefile +./minix/llvm/passes/hello/Makefile +./minix/llvm/passes/hello/hello.cpp +./minix/llvm/passes/include/asr/ASRPass.h +./minix/llvm/passes/include/common/pass_common.h +./minix/llvm/passes/include/common/qprof_common.h +./minix/llvm/passes/include/magic/MagicCTLazyCheckpointPass.h +./minix/llvm/passes/include/magic/MagicCheckpointPass.h +./minix/llvm/passes/include/magic/MagicLTLazyCheckpointPass.h +./minix/llvm/passes/include/magic/MagicPass.h +./minix/llvm/passes/include/magic/magic.h +./minix/llvm/passes/include/magic/support/BitFieldAggregation.h +./minix/llvm/passes/include/magic/support/EDIType.h +./minix/llvm/passes/include/magic/support/MagicDebugFunction.h +./minix/llvm/passes/include/magic/support/MagicMemFunction.h +./minix/llvm/passes/include/magic/support/MagicMmapCtlFunction.h +./minix/llvm/passes/include/magic/support/MagicUtil.h +./minix/llvm/passes/include/magic/support/SmartType.h +./minix/llvm/passes/include/magic/support/TypeInfo.h +./minix/llvm/passes/include/magic/support/TypeUtil.h +./minix/llvm/passes/include/magic/support/VariableRefs.h +./minix/llvm/passes/include/pass.h +./minix/llvm/passes/include/sectionify/SectionifyPass.h +./minix/llvm/passes/magic/MagicPass.cpp +./minix/llvm/passes/magic/Makefile +./minix/llvm/passes/magic/support/BitFieldAggregation.cpp +./minix/llvm/passes/magic/support/EDIType.cpp +./minix/llvm/passes/magic/support/MagicUtil.cpp +./minix/llvm/passes/magic/support/SmartType.cpp +./minix/llvm/passes/magic/support/TypeUtil.cpp +./minix/llvm/passes/magic/support/VariableRefs.cpp +./minix/llvm/passes/sectionify/Makefile +./minix/llvm/passes/sectionify/SectionifyPass.cpp +./minix/man/Makefile +./minix/man/Makefile.inc +./minix/man/man2/Makefile +./minix/man/man2/accept.2 +./minix/man/man2/access.2 +./minix/man/man2/bind.2 +./minix/man/man2/brk.2 +./minix/man/man2/chdir.2 +./minix/man/man2/chmod.2 +./minix/man/man2/chown.2 +./minix/man/man2/chroot.2 +./minix/man/man2/close.2 +./minix/man/man2/connect.2 +./minix/man/man2/creat.2 +./minix/man/man2/dup.2 +./minix/man/man2/execve.2 +./minix/man/man2/exit.2 +./minix/man/man2/fcntl.2 +./minix/man/man2/fork.2 +./minix/man/man2/getgid.2 +./minix/man/man2/getitimer.2 +./minix/man/man2/getpeername.2 +./minix/man/man2/getpid.2 +./minix/man/man2/getpriority.2 +./minix/man/man2/getsockname.2 +./minix/man/man2/getsockopt.2 +./minix/man/man2/gettimeofday.2 +./minix/man/man2/getuid.2 +./minix/man/man2/intro.2 +./minix/man/man2/ioctl.2 +./minix/man/man2/kill.2 +./minix/man/man2/link.2 +./minix/man/man2/listen.2 +./minix/man/man2/lseek.2 +./minix/man/man2/mkdir.2 +./minix/man/man2/mknod.2 +./minix/man/man2/mount.2 +./minix/man/man2/open.2 +./minix/man/man2/ptrace.2 +./minix/man/man2/read.2 +./minix/man/man2/readlink.2 +./minix/man/man2/recv.2 +./minix/man/man2/recvfrom.2 +./minix/man/man2/recvmsg.2 +./minix/man/man2/rename.2 +./minix/man/man2/rmdir.2 +./minix/man/man2/select.2 +./minix/man/man2/send.2 +./minix/man/man2/sendmsg.2 +./minix/man/man2/sendto.2 +./minix/man/man2/setsid.2 +./minix/man/man2/setsockopt.2 +./minix/man/man2/setuid.2 +./minix/man/man2/shutdown.2 +./minix/man/man2/sigaction.2 +./minix/man/man2/sigpending.2 +./minix/man/man2/sigprocmask.2 +./minix/man/man2/sigsuspend.2 +./minix/man/man2/socket.2 +./minix/man/man2/socketpair.2 +./minix/man/man2/svrctl.2 +./minix/man/man2/symlink.2 +./minix/man/man2/sync.2 +./minix/man/man2/time.2 +./minix/man/man2/truncate.2 +./minix/man/man2/umask.2 +./minix/man/man2/uname.2 +./minix/man/man2/unlink.2 +./minix/man/man2/utime.2 +./minix/man/man2/wait.2 +./minix/man/man2/write.2 +./minix/man/man4/Makefile +./minix/man/man4/console.4 +./minix/man/man4/controller.4 +./minix/man/man4/dev.4 +./minix/man/man4/fd.4 +./minix/man/man4/lp.4 +./minix/man/man4/mtio.4 +./minix/man/man4/tty.4 +./minix/man/man5/Makefile +./minix/man/man5/TZ.5 +./minix/man/man5/configfile.5 +./minix/man/man5/crontab.5 +./minix/man/man5/fstab.5 +./minix/man/man5/keymap.5 +./minix/man/man5/passwd.5 +./minix/man/man5/termcap.5 +./minix/man/man5/ttytab.5 +./minix/man/man5/utmp.5 +./minix/man/man7/Makefile +./minix/man/man7/ascii.7 +./minix/man/man7/environ.7 +./minix/man/man7/hier.7 +./minix/man/man7/man.7 +./minix/man/man8/Makefile +./minix/man/man8/config.8 +./minix/man/man8/usage.8 +./minix/man/man9/Makefile +./minix/man/man9/macros.9 +./minix/net/Makefile +./minix/net/Makefile.inc +./minix/net/lwip/addr.h +./minix/net/lwip/bpfdev.h +./minix/net/lwip/ethif.h +./minix/net/lwip/ifaddr.h +./minix/net/lwip/ipsock.h +./minix/net/lwip/lldata.h +./minix/net/lwip/lnksock.c +./minix/net/lwip/lwip.c +./minix/net/lwip/lwip.conf +./minix/net/lwip/mcast.c +./minix/net/lwip/mcast.h +./minix/net/lwip/mempool.c +./minix/net/lwip/mibtree.c +./minix/net/lwip/ndev.c +./minix/net/lwip/ndev.h +./minix/net/lwip/pchain.c +./minix/net/lwip/pktsock.h +./minix/net/lwip/route.h +./minix/net/lwip/rtsock.h +./minix/net/lwip/rttree.c +./minix/net/lwip/rttree.h +./minix/net/lwip/tcpisn.c +./minix/net/lwip/tcpisn.h +./minix/net/lwip/util.c +./minix/net/lwip/util.h +./minix/net/uds/Makefile +./minix/net/uds/uds.conf +./minix/net/uds/uds.h +./minix/net/uds/unix.8 +./minix/servers/Makefile +./minix/servers/Makefile.inc +./minix/servers/devman/Makefile +./minix/servers/devman/bind.c +./minix/servers/devman/buf.c +./minix/servers/devman/device.c +./minix/servers/devman/devinfo.h +./minix/servers/devman/devman.h +./minix/servers/devman/main.c +./minix/servers/devman/proto.h +./minix/servers/ds/Makefile +./minix/servers/ds/inc.h +./minix/servers/ds/main.c +./minix/servers/ds/proto.h +./minix/servers/ds/store.c +./minix/servers/ds/store.h +./minix/servers/input/Makefile +./minix/servers/input/input.c +./minix/servers/input/input.h +./minix/servers/ipc/Makefile +./minix/servers/ipc/ipc.conf +./minix/servers/ipc/utility.c +./minix/servers/is/dmp.c +./minix/servers/is/dmp_ds.c +./minix/servers/is/dmp_fs.c +./minix/servers/is/dmp_kernel.c +./minix/servers/is/dmp_pm.c +./minix/servers/is/dmp_rs.c +./minix/servers/is/dmp_vm.c +./minix/servers/is/glo.h +./minix/servers/is/inc.h +./minix/servers/is/main.c +./minix/servers/is/proto.h +./minix/servers/mib/hw.c +./minix/servers/mib/minix.c +./minix/servers/mib/remote.c +./minix/servers/pm/alarm.c +./minix/servers/pm/const.h +./minix/servers/pm/event.c +./minix/servers/pm/exec.c +./minix/servers/pm/forkexit.c +./minix/servers/pm/glo.h +./minix/servers/pm/main.c +./minix/servers/pm/mcontext.c +./minix/servers/pm/misc.c +./minix/servers/pm/mproc.h +./minix/servers/pm/pm.h +./minix/servers/pm/profile.c +./minix/servers/pm/proto.h +./minix/servers/pm/schedule.c +./minix/servers/pm/signal.c +./minix/servers/pm/table.c +./minix/servers/pm/time.c +./minix/servers/pm/trace.c +./minix/servers/pm/type.h +./minix/servers/pm/utility.c +./minix/servers/rs/const.h +./minix/servers/rs/error.c +./minix/servers/rs/exec.c +./minix/servers/rs/glo.h +./minix/servers/rs/inc.h +./minix/servers/rs/main.c +./minix/servers/rs/manager.c +./minix/servers/rs/proto.h +./minix/servers/rs/request.c +./minix/servers/rs/table.c +./minix/servers/rs/type.h +./minix/servers/rs/update.c +./minix/servers/rs/utility.c +./minix/servers/sched/Makefile +./minix/servers/sched/main.c +./minix/servers/sched/proto.h +./minix/servers/sched/sched.h +./minix/servers/sched/schedproc.h +./minix/servers/sched/schedule.c +./minix/servers/sched/utility.c +./minix/servers/vfs/Makefile +./minix/servers/vfs/README +./minix/servers/vfs/bdev.c +./minix/servers/vfs/cdev.c +./minix/servers/vfs/comm.c +./minix/servers/vfs/const.h +./minix/servers/vfs/coredump.c +./minix/servers/vfs/device.c +./minix/servers/vfs/dmap.c +./minix/servers/vfs/dmap.h +./minix/servers/vfs/exec.c +./minix/servers/vfs/file.h +./minix/servers/vfs/filedes.c +./minix/servers/vfs/fproc.h +./minix/servers/vfs/fs.h +./minix/servers/vfs/gcov.c +./minix/servers/vfs/glo.h +./minix/servers/vfs/link.c +./minix/servers/vfs/lock.c +./minix/servers/vfs/lock.h +./minix/servers/vfs/main.c +./minix/servers/vfs/misc.c +./minix/servers/vfs/mount.c +./minix/servers/vfs/open.c +./minix/servers/vfs/path.h +./minix/servers/vfs/pipe.c +./minix/servers/vfs/protect.c +./minix/servers/vfs/proto.h +./minix/servers/vfs/read.c +./minix/servers/vfs/request.c +./minix/servers/vfs/request.h +./minix/servers/vfs/sdev.c +./minix/servers/vfs/select.c +./minix/servers/vfs/smap.c +./minix/servers/vfs/socket.c +./minix/servers/vfs/table.c +./minix/servers/vfs/threads.h +./minix/servers/vfs/time.c +./minix/servers/vfs/tll.c +./minix/servers/vfs/tll.h +./minix/servers/vfs/type.h +./minix/servers/vfs/utility.c +./minix/servers/vfs/vmnt.c +./minix/servers/vfs/vmnt.h +./minix/servers/vfs/vnode.c +./minix/servers/vfs/vnode.h +./minix/servers/vfs/worker.c +./minix/servers/vfs/write.c +./minix/servers/vm/acl.c +./minix/servers/vm/alloc.c +./minix/servers/vm/arch/earm/Makefile.inc +./minix/servers/vm/arch/earm/pagetable.h +./minix/servers/vm/arch/earm/vm.lds +./minix/servers/vm/arch/i386/Makefile.inc +./minix/servers/vm/arch/i386/pagetable.h +./minix/servers/vm/break.c +./minix/servers/vm/cache.c +./minix/servers/vm/cache.h +./minix/servers/vm/cavl_if.h +./minix/servers/vm/cavl_impl.h +./minix/servers/vm/exit.c +./minix/servers/vm/fdref.c +./minix/servers/vm/fdref.h +./minix/servers/vm/fork.c +./minix/servers/vm/glo.h +./minix/servers/vm/main.c +./minix/servers/vm/mem_anon.c +./minix/servers/vm/mem_anon_contig.c +./minix/servers/vm/mem_cache.c +./minix/servers/vm/mem_directphys.c +./minix/servers/vm/mem_file.c +./minix/servers/vm/mem_shared.c +./minix/servers/vm/memlist.h +./minix/servers/vm/memtype.h +./minix/servers/vm/mmap.c +./minix/servers/vm/pagefaults.c +./minix/servers/vm/pagetable.c +./minix/servers/vm/pb.c +./minix/servers/vm/phys_region.h +./minix/servers/vm/proto.h +./minix/servers/vm/pt.h +./minix/servers/vm/region.c +./minix/servers/vm/region.h +./minix/servers/vm/regionavl.c +./minix/servers/vm/regionavl.h +./minix/servers/vm/regionavl_defs.h +./minix/servers/vm/rs.c +./minix/servers/vm/sanitycheck.h +./minix/servers/vm/slaballoc.c +./minix/servers/vm/unavl.h +./minix/servers/vm/util.h +./minix/servers/vm/utility.c +./minix/servers/vm/vfs.c +./minix/servers/vm/vm.h +./minix/servers/vm/vmproc.h +./minix/share/Makefile +./minix/share/Makefile.inc +./minix/share/beaglebone/Makefile +./minix/share/beaglebone/Makefile.inc +./minix/share/beaglebone/weather/LICENSE +./minix/share/beaglebone/weather/Makefile +./minix/share/beaglebone/weather/README.txt +./minix/share/beaglebone/weather/index.html +./minix/share/beaglebone/weather/jquery.js +./minix/share/beaglebone/weather/processing.js +./minix/share/beaglebone/weather/spin.js +./minix/share/beaglebone/weather/style.css +./minix/share/beaglebone/weather/weatherstation.js +./minix/share/beaglebone/weather/weatherstation.lua +./minix/tests/Makefile.inc +./minix/tests/arch/earm/Makefile.inc +./minix/tests/arch/earm/test_arm_segfault.S +./minix/tests/arch/earm/test_arm_unaligned.S +./minix/tests/arch/i386/Makefile.inc +./minix/tests/blocktest/Makefile +./minix/tests/blocktest/Makefile.inc +./minix/tests/blocktest/README +./minix/tests/blocktest/blocktest.c +./minix/tests/blocktest/support.sh +./minix/tests/blocktest/system.conf +./minix/tests/blocktest/test.sh +./minix/tests/check-install +./minix/tests/common-socket.c +./minix/tests/common-socket.h +./minix/tests/common.c +./minix/tests/common.h +./minix/tests/ddekit/Makefile +./minix/tests/ddekit/ddekittest.sh +./minix/tests/ddekit/ddekittest_driver.c +./minix/tests/ddekit/system.conf +./minix/tests/ds/Makefile +./minix/tests/ds/Makefile.inc +./minix/tests/ds/README +./minix/tests/ds/dstest.c +./minix/tests/ds/inc.h +./minix/tests/ds/run +./minix/tests/ds/subs.c +./minix/tests/ds/system.conf +./minix/tests/fbdtest/Makefile +./minix/tests/fbdtest/rwblocks.c +./minix/tests/fbdtest/test.sh +./minix/tests/kernel/run +./minix/tests/kernel/sys_padconf/padconftest.c +./minix/tests/kernel/sys_padconf/run +./minix/tests/kernel/sys_padconf/system.conf +./minix/tests/kernel/sys_vumap/Makefile +./minix/tests/kernel/sys_vumap/Makefile.inc +./minix/tests/kernel/sys_vumap/com.h +./minix/tests/kernel/sys_vumap/run +./minix/tests/kernel/sys_vumap/system.conf +./minix/tests/kernel/sys_vumap/vumaprelay.c +./minix/tests/kernel/sys_vumap/vumaptest.c +./minix/tests/magic.h +./minix/tests/mod.c +./minix/tests/rmibtest/Makefile +./minix/tests/rmibtest/rmibtest.c +./minix/tests/rmibtest/rmibtest.conf +./minix/tests/run +./minix/tests/safecopy/Makefile +./minix/tests/safecopy/README +./minix/tests/safecopy/down +./minix/tests/safecopy/grantor.c +./minix/tests/safecopy/inc.h +./minix/tests/safecopy/requestor.c +./minix/tests/safecopy/run +./minix/tests/safecopy/system.conf +./minix/tests/socklib.c +./minix/tests/socklib.h +./minix/tests/t10a.c +./minix/tests/t11a.c +./minix/tests/t11b.c +./minix/tests/t40a.c +./minix/tests/t40b.c +./minix/tests/t40c.c +./minix/tests/t40d.c +./minix/tests/t40e.c +./minix/tests/t40f.c +./minix/tests/t40g.c +./minix/tests/t60a.c +./minix/tests/t60b.c +./minix/tests/t67a.c +./minix/tests/t67b.c +./minix/tests/t68a.c +./minix/tests/t68b.c +./minix/tests/t84_h_nonexec.sh +./minix/tests/test1.c +./minix/tests/test10.c +./minix/tests/test11.c +./minix/tests/test12.c +./minix/tests/test13.c +./minix/tests/test14.c +./minix/tests/test15.c +./minix/tests/test16.c +./minix/tests/test17.c +./minix/tests/test18.c +./minix/tests/test19.c +./minix/tests/test2.c +./minix/tests/test20.c +./minix/tests/test21.c +./minix/tests/test22.c +./minix/tests/test23.c +./minix/tests/test24.c +./minix/tests/test25.c +./minix/tests/test26.c +./minix/tests/test29.c +./minix/tests/test3.c +./minix/tests/test30.c +./minix/tests/test31.c +./minix/tests/test32.c +./minix/tests/test33.c +./minix/tests/test34.c +./minix/tests/test35.c +./minix/tests/test36.c +./minix/tests/test37.c +./minix/tests/test38.c +./minix/tests/test39.c +./minix/tests/test4.c +./minix/tests/test40.c +./minix/tests/test41.c +./minix/tests/test42.c +./minix/tests/test43.c +./minix/tests/test44.c +./minix/tests/test45.c +./minix/tests/test45.h +./minix/tests/test46.c +./minix/tests/test47.c +./minix/tests/test49.c +./minix/tests/test5.c +./minix/tests/test50.c +./minix/tests/test51.c +./minix/tests/test52.c +./minix/tests/test53.c +./minix/tests/test54.c +./minix/tests/test55.c +./minix/tests/test57.c +./minix/tests/test57loop.S +./minix/tests/test58.c +./minix/tests/test59.c +./minix/tests/test6.c +./minix/tests/test60.c +./minix/tests/test61.c +./minix/tests/test62.c +./minix/tests/test63.c +./minix/tests/test64.c +./minix/tests/test65.c +./minix/tests/test66.c +./minix/tests/test66expected.h +./minix/tests/test67.c +./minix/tests/test69.c +./minix/tests/test7.c +./minix/tests/test70.c +./minix/tests/test71.c +./minix/tests/test72.c +./minix/tests/test73.c +./minix/tests/test74.c +./minix/tests/test75.c +./minix/tests/test76.c +./minix/tests/test78.c +./minix/tests/test79.c +./minix/tests/test8.c +./minix/tests/test80.c +./minix/tests/test81.c +./minix/tests/test82.c +./minix/tests/test83.c +./minix/tests/test85.c +./minix/tests/test86.c +./minix/tests/test89.c +./minix/tests/test9.c +./minix/tests/test91.c +./minix/tests/test93.c +./minix/tests/testcache.c +./minix/tests/testcache.h +./minix/tests/testinterp.sh +./minix/tests/testisofs.sh +./minix/tests/testkyua.sh +./minix/tests/testmfs.sh +./minix/tests/testrelpol.sh +./minix/tests/testrmib.sh +./minix/tests/testsh1.sh +./minix/tests/testsh2.sh +./minix/tests/testvm.c +./minix/tests/testvm.conf +./minix/tests/testvm.h +./minix/tests/testvnd.sh +./minix/tests/tvnd.c +./minix/usr.bin/.DS_Store +./minix/usr.bin/Makefile +./minix/usr.bin/Makefile.inc +./minix/usr.bin/diff/Makefile +./minix/usr.bin/diff/diff.1 +./minix/usr.bin/diff/diff.c +./minix/usr.bin/diff/diff.h +./minix/usr.bin/diff/diffdir.c +./minix/usr.bin/diff/diffreg.c +./minix/usr.bin/diff/pathnames.h +./minix/usr.bin/diff/xmalloc.c +./minix/usr.bin/diff/xmalloc.h +./minix/usr.bin/eepromread/Makefile +./minix/usr.bin/eepromread/board_info.c +./minix/usr.bin/eepromread/eepromread.1 +./minix/usr.bin/eepromread/eepromread.c +./minix/usr.bin/eepromread/eepromread.h +./minix/usr.bin/grep/Makefile +./minix/usr.bin/grep/binary.c +./minix/usr.bin/grep/file.c +./minix/usr.bin/grep/grep.1 +./minix/usr.bin/grep/grep.c +./minix/usr.bin/grep/grep.h +./minix/usr.bin/grep/mmfile.c +./minix/usr.bin/grep/queue.c +./minix/usr.bin/grep/util.c +./minix/usr.bin/mined/Makefile +./minix/usr.bin/mined/mined.1 +./minix/usr.bin/mined/mined.h +./minix/usr.bin/mined/mined1.c +./minix/usr.bin/mined/mined2.c +./minix/usr.bin/ministat/Makefile +./minix/usr.bin/ministat/README +./minix/usr.bin/ministat/chameleon +./minix/usr.bin/ministat/iguana +./minix/usr.bin/ministat/ministat.1 +./minix/usr.bin/ministat/ministat.c +./minix/usr.bin/mtop/Makefile +./minix/usr.bin/mtop/mtop.c +./minix/usr.bin/trace/NOTES +./minix/usr.bin/trace/call.c +./minix/usr.bin/trace/error.awk +./minix/usr.bin/trace/escape.c +./minix/usr.bin/trace/format.c +./minix/usr.bin/trace/inc.h +./minix/usr.bin/trace/ioctl/block.c +./minix/usr.bin/trace/ioctl/char.c +./minix/usr.bin/trace/ioctl/net.c +./minix/usr.bin/trace/ioctl/svrctl.c +./minix/usr.bin/trace/kernel.c +./minix/usr.bin/trace/mem.c +./minix/usr.bin/trace/output.c +./minix/usr.bin/trace/proc.c +./minix/usr.bin/trace/proc.h +./minix/usr.bin/trace/proto.h +./minix/usr.bin/trace/service/ipc.c +./minix/usr.bin/trace/service/pm.c +./minix/usr.bin/trace/service/rs.c +./minix/usr.bin/trace/service/vfs.c +./minix/usr.bin/trace/service/vm.c +./minix/usr.bin/trace/signal.awk +./minix/usr.bin/trace/trace.1 +./minix/usr.bin/trace/trace.c +./minix/usr.bin/trace/type.h +./minix/usr.sbin/Makefile +./minix/usr.sbin/Makefile.inc +./minix/usr.sbin/btrace/Makefile +./minix/usr.sbin/btrace/btrace.8 +./minix/usr.sbin/btrace/btrace.c +./minix/usr.sbin/diskctl/Makefile +./minix/usr.sbin/diskctl/diskctl.8 +./minix/usr.sbin/diskctl/diskctl.c +./minix/usr.sbin/fbdctl/Makefile +./minix/usr.sbin/fbdctl/fbdctl.8 +./minix/usr.sbin/fbdctl/fbdctl.c +./minix/usr.sbin/mkfs.mfs/Makefile +./minix/usr.sbin/mkfs.mfs/Makefile.mkfs +./minix/usr.sbin/mkfs.mfs/mfs3v2/Makefile +./minix/usr.sbin/mkfs.mfs/mfs3v2/const.h +./minix/usr.sbin/mkfs.mfs/mfs3v2/mfsdir.h +./minix/usr.sbin/mkfs.mfs/mfs3v2/super.h +./minix/usr.sbin/mkfs.mfs/mfs3v2/type.h +./minix/usr.sbin/mkfs.mfs/v1/Makefile +./minix/usr.sbin/mkfs.mfs/v1/const.h +./minix/usr.sbin/mkfs.mfs/v1/mfsdir.h +./minix/usr.sbin/mkfs.mfs/v1/super.h +./minix/usr.sbin/mkfs.mfs/v1/type.h +./minix/usr.sbin/mkfs.mfs/v1l/Makefile +./minix/usr.sbin/mkfs.mfs/v1l/const.h +./minix/usr.sbin/mkfs.mfs/v1l/mfsdir.h +./minix/usr.sbin/mkfs.mfs/v1l/super.h +./minix/usr.sbin/mkfs.mfs/v1l/type.h +./minix/usr.sbin/mkfs.mfs/v2/Makefile +./minix/usr.sbin/mkfs.mfs/v2/const.h +./minix/usr.sbin/mkfs.mfs/v2/mfsdir.h +./minix/usr.sbin/mkfs.mfs/v2/super.h +./minix/usr.sbin/mkfs.mfs/v2/type.h +./minix/usr.sbin/mkfs.mfs/v2l/Makefile +./minix/usr.sbin/mkfs.mfs/v2l/const.h +./minix/usr.sbin/mkfs.mfs/v2l/mfsdir.h +./minix/usr.sbin/mkfs.mfs/v2l/super.h +./minix/usr.sbin/mkfs.mfs/v2l/type.h +./minix/usr.sbin/mkfs.mfs/v3/Makefile +./minix/usr.sbin/mkfs.mfs/v3/const.h +./minix/usr.sbin/mkfs.mfs/v3/mfsdir.h +./minix/usr.sbin/mkfs.mfs/v3/mkfs.mfs.1 +./minix/usr.sbin/mkfs.mfs/v3/super.h +./minix/usr.sbin/mkfs.mfs/v3/type.h +./minix/usr.sbin/mkproto/Makefile +./minix/usr.sbin/mkproto/mkproto.1 +./minix/usr.sbin/mkproto/mkproto.c +./releasetools/fetch_u-boot.sh +./releasetools/gen_uEnv.txt.sh +./releasetools/image.defaults +./releasetools/image.functions +./releasetools/mkboot +./releasetools/packages.install +./releasetools/release.functions +./releasetools/release.sh +./releasetools/release/cd/README.TXT +./releasetools/release/cd/etc/issue +./releasetools/release/ramdisk/etc/issue +./releasetools/sort_set.pl diff --git a/minix/commands/cdprobe/Makefile b/minix/commands/cdprobe/Makefile deleted file mode 100644 index 3d8b42d4e..000000000 --- a/minix/commands/cdprobe/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -PROG= cdprobe -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/fs -MAN= cdprobe.8 - -.include diff --git a/minix/commands/crontab/Makefile b/minix/commands/crontab/Makefile deleted file mode 100644 index b2b30b990..000000000 --- a/minix/commands/crontab/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Makefile for crontab. - -.include - -PROG= crontab -SRCS= crontab.c tab.c misc.c -CPPFLAGS+= -I${.CURDIR} -I${NETBSDSRCDIR}/minix/commands/cron -BINMODE= 4755 - -.PATH: ${NETBSDSRCDIR}/minix/commands/cron - -.include diff --git a/minix/commands/fetch/fetch.c b/minix/commands/fetch/fetch.c deleted file mode 100644 index 55d0007c9..000000000 --- a/minix/commands/fetch/fetch.c +++ /dev/null @@ -1,1131 +0,0 @@ -/*- - * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif -#if !defined(NETBSD) && !defined(__minix) -#include -#endif - -#if HAVE_SYS_PARAM_H -#include -#endif -#if HAVE_SYS_IOCTL_H -#include -#endif -#if HAVE_SYS_SOCKET_H -#include -#endif -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TIME_H -#include -#endif -#if HAVE_UTIME_H -#include -#endif -#include -#if HAVE_ERR_H -#include -#endif -#include -#include -#if HAVE_STDINT_H -#include -#endif -#include -#include -#include -#if HAVE_TERMIOS_H -#include -#endif -#include - -#include - -#if HAVE_SYSEXITS_H -#include -#endif - -#ifndef EX_USAGE -#define EX_USAGE 64 -#endif - -#ifndef EX_IOERR -#define EX_IOERR 74 -#endif - -#define MINBUFSIZE 4096 - -/* Option flags */ -int A_flag; /* -A: do not follow 302 redirects */ -int a_flag; /* -a: auto retry */ -off_t B_size; /* -B: buffer size */ -int d_flag; /* -d: direct connection */ -int F_flag; /* -F: restart without checking mtime */ -int i_flag; /* -i: fetch file if modified */ -int l_flag; /* -l: link rather than copy file: URLs */ -int m_flag; /* -[Mm]: mirror mode */ -char *N_filename; /* -N: netrc file name */ -int n_flag; /* -n: do not preserve modification time */ -int o_flag; /* -o: specify output file */ -int o_directory; /* output file is a directory */ -char *o_filename; /* name of output file */ -int o_stdout; /* output file is stdout */ -int once_flag; /* -1: stop at first successful file */ -int R_flag; /* -R: don't delete partially transferred files */ -int r_flag; /* -r: restart previously interrupted transfer */ -off_t S_size; /* -S: require size to match */ -int s_flag; /* -s: show size, don't fetch */ -long T_secs = 120; /* -T: transfer timeout in seconds */ -int U_flag; /* -U: do not use high ports */ -int v_level = 1; /* -v: verbosity level */ -int v_tty; /* stdout is a tty */ -pid_t pgrp; /* our process group */ -long w_secs; /* -w: retry delay */ -int family = PF_UNSPEC; /* -[46]: address family to use */ - -volatile int sigalrm; /* SIGALRM received */ -#ifdef SIGINFO -volatile int siginfo; /* SIGINFO received */ -#endif -volatile int sigint; /* SIGINT received */ - -long ftp_timeout; /* default timeout for FTP transfers */ -long http_timeout; /* default timeout for HTTP transfers */ -char *buf; /* transfer buffer */ - - -/* - * Signal handler - */ -static void -sig_handler(int sig) -{ - switch (sig) { - case SIGALRM: - fetchRestartCalls = 0; - sigalrm = 1; - break; -#ifdef SIGINFO - case SIGINFO: - siginfo = 1; - break; -#endif - case SIGINT: - fetchRestartCalls = 0; - sigint = 1; - break; - } -} - -struct xferstat { - char name[64]; - struct timeval start; - struct timeval last; - off_t size; - off_t offset; - off_t rcvd; -}; - -/* - * Compute and display ETA - */ -static const char * -stat_eta(struct xferstat *xs) -{ - static char str[16]; - long elapsed, eta; - off_t received, expected; - - elapsed = xs->last.tv_sec - xs->start.tv_sec; - received = xs->rcvd - xs->offset; - expected = xs->size - xs->rcvd; - eta = (long)((double)elapsed * expected / received); - if (eta > 3600) - snprintf(str, sizeof str, "%02ldh%02ldm", - eta / 3600, (eta % 3600) / 60); - else - snprintf(str, sizeof str, "%02ldm%02lds", - eta / 60, eta % 60); - return (str); -} - -/* - * Format a number as "xxxx YB" where Y is ' ', 'k', 'M'... - */ -static const char *prefixes = " kMGTP"; -static const char * -stat_bytes(off_t bytes) -{ - static char str[16]; - const char *prefix = prefixes; - - while (bytes > 9999 && prefix[1] != '\0') { - bytes /= 1024; - prefix++; - } - snprintf(str, sizeof str, "%4jd %cB", (intmax_t)bytes, *prefix); - return (str); -} - -/* - * Compute and display transfer rate - */ -static const char * -stat_bps(struct xferstat *xs) -{ - static char str[16]; - double delta, bps; - - delta = (xs->last.tv_sec + (xs->last.tv_usec / 1.e6)) - - (xs->start.tv_sec + (xs->start.tv_usec / 1.e6)); - if (delta == 0.0) { - snprintf(str, sizeof str, "?? Bps"); - } else { - bps = (xs->rcvd - xs->offset) / delta; - snprintf(str, sizeof str, "%sps", stat_bytes((off_t)bps)); - } - return (str); -} - -/* - * Update the stats display - */ -static void -stat_display(struct xferstat *xs, int force) -{ - struct timeval now; -#if !defined(__minix) - int ctty_pgrp; -#endif /* !defined(__minix) */ - - /* Minix returns "Not a typewriter error" */ -#if defined(TIOCGPGRP) && !defined(__minix) - /* check if we're the foreground process */ - if (ioctl(STDERR_FILENO, TIOCGPGRP, &ctty_pgrp) == -1 || - (pid_t)ctty_pgrp != pgrp) - return; -#endif - - gettimeofday(&now, NULL); - if (!force && now.tv_sec <= xs->last.tv_sec) - return; - xs->last = now; - - fprintf(stderr, "\r%-46.46s", xs->name); - if (xs->size <= 0) { -#if HAVE_SETPROCTITLE - setproctitle("%s [%s]", xs->name, stat_bytes(xs->rcvd)); -#endif - fprintf(stderr, " %s", stat_bytes(xs->rcvd)); - } else { -#if HAVE_SETPROCTITLE - setproctitle("%s [%d%% of %s]", xs->name, - (int)((100.0 * xs->rcvd) / xs->size), - stat_bytes(xs->size)); -#endif - fprintf(stderr, "%3d%% of %s", - (int)((100.0 * xs->rcvd) / xs->size), - stat_bytes(xs->size)); - } - fprintf(stderr, " %s", stat_bps(xs)); - if (xs->size > 0 && xs->rcvd > 0 && - xs->last.tv_sec >= xs->start.tv_sec + 10) - fprintf(stderr, " %s", stat_eta(xs)); - fflush(stderr); -} - -/* - * Initialize the transfer statistics - */ -static void -stat_start(struct xferstat *xs, const char *name, off_t size, off_t offset) -{ - snprintf(xs->name, sizeof xs->name, "%s", name); - gettimeofday(&xs->start, NULL); - xs->last.tv_sec = xs->last.tv_usec = 0; - xs->size = size; - xs->offset = offset; - xs->rcvd = offset; - if (v_tty && v_level > 0) - stat_display(xs, 1); - else if (v_level > 0) - fprintf(stderr, "%-46s", xs->name); -} - -/* - * Update the transfer statistics - */ -static void -stat_update(struct xferstat *xs, off_t rcvd) -{ - xs->rcvd = rcvd; - if (v_tty && v_level > 0) - stat_display(xs, 0); -} - -/* - * Finalize the transfer statistics - */ -static void -stat_end(struct xferstat *xs) -{ - gettimeofday(&xs->last, NULL); - if (v_tty && v_level > 0) { - stat_display(xs, 1); - putc('\n', stderr); - } else if (v_level > 0) { - fprintf(stderr, " %s %s\n", - stat_bytes(xs->size), stat_bps(xs)); - } -} - -#if HAVE_TERMIOS_H && !defined(PREFER_GETPASS) -static int -read_password(const char *prompt, char *pwbuf, size_t pwbuf_len) -{ - struct termios tios; - tcflag_t saved_flags; - int nopwd; - - fprintf(stderr, "%s", prompt); - if (tcgetattr(STDIN_FILENO, &tios) != 0) - return (fgets(pwbuf, pwbuf_len, stdin) == NULL); - - saved_flags = tios.c_lflag; - tios.c_lflag &= ~ECHO; - tios.c_lflag |= ECHONL|ICANON; -#ifndef __minix - tcsetattr(STDIN_FILENO, TCSAFLUSH|TCSASOFT, &tios); -#else - tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios); -#endif - nopwd = (fgets(pwbuf, pwbuf_len, stdin) == NULL); - tios.c_lflag = saved_flags; -#ifndef __minix - tcsetattr(STDIN_FILENO, TCSANOW|TCSASOFT, &tios); -#else - tcsetattr(STDIN_FILENO, TCSANOW, &tios); -#endif - - return nopwd; -} -#elif HAVE_GETPASSPHRASE || HAVE_GETPASS -static int -read_password(const char *prompt, char *pwbuf, size_t pwbuf_len) -{ - char *pass; - -#if HAVE_GETPASSPHRASE && !defined(PREFER_GETPASS) - pass = getpassphrase(prompt); -#else - pass = getpass(prompt); -#endif - if (pass == NULL || strlen(pass) >= pwbuf_len) - return 1; - strcpy(pwbuf, pass); - return 0; -} -#else -static int -read_password(const char *prompt, char *pwbuf, size_t pwbuf_len) -{ - - fprintf(stderr, prompt); - return (fgets(pwbuf, pwbuf_len, stdin) == NULL); -} -#endif - -/* - * Ask the user for authentication details - */ -static int -query_auth(struct url *URL) -{ - int i, nopwd; - - fprintf(stderr, "Authentication required for <%s://%s:%d/>!\n", - URL->scheme, URL->host, URL->port); - - fprintf(stderr, "Login: "); - if (fgets(URL->user, sizeof URL->user, stdin) == NULL) - return (-1); - for (i = strlen(URL->user); i >= 0; --i) - if (URL->user[i] == '\r' || URL->user[i] == '\n') - URL->user[i] = '\0'; - - nopwd = read_password("Password: ", URL->pwd, sizeof(URL->pwd)); - - if (nopwd) - return (-1); - for (i = strlen(URL->pwd); i >= 0; --i) - if (URL->pwd[i] == '\r' || URL->pwd[i] == '\n') - URL->pwd[i] = '\0'; - - return (0); -} - -/* - * Fetch a file - */ -static int -fetch(char *URL, const char *path) -{ - struct url *url; - struct url_stat us; - struct stat sb, nsb; - struct xferstat xs; - FILE *of; - fetchIO *f; - size_t size, wr; - ssize_t ssize; - off_t count; - char flags[8]; - char *tmppath; - int r; - unsigned timeout; - char *ptr; - - f = NULL; - of = NULL; - tmppath = NULL; - - timeout = 0; - *flags = 0; - count = 0; - - /* set verbosity level */ - if (v_level > 1) - strcat(flags, "v"); - if (v_level > 2) - fetchDebug = 1; - - /* parse URL */ - if ((url = fetchParseURL(URL)) == NULL) { - warnx("%s: parse error", URL); - goto failure; - } - - /* if no scheme was specified, take a guess */ - if (!*url->scheme) { - if (!*url->host) - strcpy(url->scheme, SCHEME_FILE); - else if (strncasecmp(url->host, "ftp.", 4) == 0) - strcpy(url->scheme, SCHEME_FTP); - else if (strncasecmp(url->host, "www.", 4) == 0) - strcpy(url->scheme, SCHEME_HTTP); - } - - /* common flags */ - switch (family) { - case PF_INET: - strcat(flags, "4"); - break; -#ifndef __minix - case PF_INET6: - strcat(flags, "6"); - break; -#endif - } - - /* Protocol independent flags */ - if (i_flag) { - if (stat(path, &sb) == 0) { - url->last_modified = sb.st_mtime; - strcat(flags, "i"); - } else if (errno != ENOENT) { - warn("%s: stat()", path); - goto failure; - } - } - - /* FTP specific flags */ - if (strcmp(url->scheme, SCHEME_FTP) == 0) { - if (d_flag) - strcat(flags, "d"); - if (U_flag) - strcat(flags, "l"); - timeout = T_secs ? T_secs : ftp_timeout; - } - - /* HTTP specific flags */ - if (strcmp(url->scheme, SCHEME_HTTP) == 0) { - if (d_flag) - strcat(flags, "d"); - if (A_flag) - strcat(flags, "A"); - timeout = T_secs ? T_secs : http_timeout; - } - - /* set the protocol timeout. */ - fetchTimeout = timeout; - - /* just print size */ - if (s_flag) { - if (timeout) - alarm(timeout); - r = fetchStat(url, &us, flags); - if (timeout) - alarm(0); - if (sigalrm || sigint) - goto signal; - if (r == -1) { - warnx("%s", fetchLastErrString); - goto failure; - } - if (us.size == -1) - printf("Unknown\n"); - else - printf("%jd\n", (intmax_t)us.size); - goto success; - } - - /* - * If the -r flag was specified, we have to compare the local - * and remote files, so we should really do a fetchStat() - * first, but I know of at least one HTTP server that only - * sends the content size in response to GET requests, and - * leaves it out of replies to HEAD requests. Also, in the - * (frequent) case that the local and remote files match but - * the local file is truncated, we have sufficient information - * before the compare to issue a correct request. Therefore, - * we always issue a GET request as if we were sure the local - * file was a truncated copy of the remote file; we can drop - * the connection later if we change our minds. - */ - sb.st_size = -1; - if (!o_stdout) { - r = stat(path, &sb); - if (r == 0 && r_flag && S_ISREG(sb.st_mode)) { - url->offset = sb.st_size; - } else if (r == -1 || !S_ISREG(sb.st_mode)) { - /* - * Whatever value sb.st_size has now is either - * wrong (if stat(2) failed) or irrelevant (if the - * path does not refer to a regular file) - */ - sb.st_size = -1; - } - if (r == -1 && errno != ENOENT) { - warnx("%s: stat()", path); - goto failure; - } - } - - /* start the transfer */ - if (timeout) - alarm(timeout); - f = fetchXGet(url, &us, flags); - if (timeout) - alarm(0); - if (sigalrm || sigint) - goto signal; - if (f == NULL && i_flag && fetchLastErrCode == FETCH_UNCHANGED) { - /* URL was not modified, return OK. */ - printf("%s: not modified\n", URL); - r = 0; - goto done; - } - if (f == NULL) { - warnx("%s: %s", URL, fetchLastErrString); - goto failure; - } - if (sigint) - goto signal; - - /* check that size is as expected */ - if (S_size) { - if (us.size == -1) { - warnx("%s: size unknown", URL); - } else if (us.size != S_size) { - warnx("%s: size mismatch: expected %jd, actual %jd", - URL, (intmax_t)S_size, (intmax_t)us.size); - goto failure; - } - } - - /* symlink instead of copy */ - if (l_flag && strcmp(url->scheme, "file") == 0 && !o_stdout) { - char *name = fetchUnquotePath(url); - if (name == NULL) { - warnx("Can't unquote URL"); - goto failure; - } - if (symlink(name, path) == -1) { - warn("%s: symlink()", path); - free(name); - goto failure; - } - free(name); - goto success; - } - - if (us.size == -1 && !o_stdout && v_level > 0) - warnx("%s: size of remote file is not known", URL); - if (v_level > 1) { - if (sb.st_size != -1) - fprintf(stderr, "local size / mtime: %jd / %ld\n", - (intmax_t)sb.st_size, (long)sb.st_mtime); - if (us.size != -1) - fprintf(stderr, "remote size / mtime: %jd / %ld\n", - (intmax_t)us.size, (long)us.mtime); - } - - /* open output file */ - if (o_stdout) { - /* output to stdout */ - of = stdout; - } else if (r_flag && sb.st_size != -1) { - /* resume mode, local file exists */ - if (!F_flag && us.mtime && sb.st_mtime != us.mtime) { - /* no match! have to refetch */ - fetchIO_close(f); - /* if precious, warn the user and give up */ - if (R_flag) { - warnx("%s: local modification time " - "does not match remote", path); - goto failure_keep; - } - } else if (us.size != -1) { - if (us.size == sb.st_size) - /* nothing to do */ - goto success; - if (sb.st_size > us.size) { - /* local file too long! */ - warnx("%s: local file (%jd bytes) is longer " - "than remote file (%jd bytes)", path, - (intmax_t)sb.st_size, (intmax_t)us.size); - goto failure; - } - /* we got it, open local file */ - if ((of = fopen(path, "a")) == NULL) { - warn("%s: fopen()", path); - goto failure; - } - /* check that it didn't move under our feet */ - if (fstat(fileno(of), &nsb) == -1) { - /* can't happen! */ - warn("%s: fstat()", path); - goto failure; - } - if (nsb.st_dev != sb.st_dev || - nsb.st_ino != nsb.st_ino || - nsb.st_size != sb.st_size) { - warnx("%s: file has changed", URL); - fclose(of); - of = NULL; - sb = nsb; - } - } - } else if (m_flag && sb.st_size != -1) { - /* mirror mode, local file exists */ - if (sb.st_size == us.size && sb.st_mtime == us.mtime) - goto success; - } - - if (of == NULL) { - /* - * We don't yet have an output file; either this is a - * vanilla run with no special flags, or the local and - * remote files didn't match. - */ - - if (url->offset > 0) { - /* - * We tried to restart a transfer, but for - * some reason gave up - so we have to restart - * from scratch if we want the whole file - */ - url->offset = 0; - if ((f = fetchXGet(url, &us, flags)) == NULL) { - warnx("%s: %s", URL, fetchLastErrString); - goto failure; - } - if (sigint) - goto signal; - } - - /* construct a temp file name */ - if (sb.st_size != -1 && S_ISREG(sb.st_mode)) { -#ifndef __minix - asprintf(&tmppath, "%s.fetch.XXXXXX", path); -#else - { - int len; - if((tmppath = malloc(sizeof(char)*MINBUFSIZE)) != NULL) { - len = snprintf(tmppath, MINBUFSIZE, "%s.fetch.XXXXXX", path); - if(len >= MINBUFSIZE) { - free(tmppath); - tmppath = NULL; - } - } - } -#endif - - if (tmppath != NULL) { - int fd; - - fd = mkstemp(tmppath); - if (fd == -1) { - warn("%s: mkstemp failed", tmppath); - goto failure; - } - fchown(fd, sb.st_uid, sb.st_gid); - fchmod(fd, sb.st_mode & ALLPERMS); - of = fdopen(fd, "w"); - if (of == NULL) { - close(fd); - unlink(tmppath); - free(tmppath); - tmppath = NULL; - } - } - } - if (of == NULL) - of = fopen(path, "w"); - if (of == NULL) { - warn("%s: open()", path); - goto failure; - } - } - count = url->offset; - - /* start the counter */ - stat_start(&xs, path, us.size, count); - - sigalrm = sigint = 0; - - /* suck in the data */ -#ifdef SIGINFO - siginfo = 0; - signal(SIGINFO, sig_handler); -#endif - while (!sigint) { - if (us.size != -1 && us.size - count < B_size && - us.size - count >= 0) - size = us.size - count; - else - size = B_size; -#ifdef SIGINFO - if (siginfo) { - stat_display(&xs, 1); - siginfo = 0; - } -#else - /* Constant info is better than none. */ - if (v_level) { - stat_display(&xs, 1); - } -#endif - if ((ssize = fetchIO_read(f, buf, B_size)) == 0) - break; - if (ssize == -1 && errno == EINTR) - continue; - if (ssize == -1) - break; - size = ssize; - stat_update(&xs, count += size); - for (ptr = buf; size > 0; ptr += wr, size -= wr) { - if ((wr = fwrite(ptr, 1, size, of)) < size) { - if (ferror(of) && errno == EINTR && !sigint) - clearerr(of); - else - break; - } - } - if (size != 0) - break; - } - if (!sigalrm) - sigalrm = 0; -#ifdef SIGINFO - signal(SIGINFO, SIG_DFL); -#endif - - stat_end(&xs); - - /* - * If the transfer timed out or was interrupted, we still want to - * set the mtime in case the file is not removed (-r or -R) and - * the user later restarts the transfer. - */ - signal: - /* set mtime of local file */ - if (!n_flag && us.mtime && !o_stdout && of != NULL && - (stat(path, &sb) != -1) && sb.st_mode & S_IFREG) { - struct timeval tv[2]; - - fflush(of); - tv[0].tv_sec = (long)(us.atime ? us.atime : us.mtime); - tv[1].tv_sec = (long)us.mtime; - tv[0].tv_usec = tv[1].tv_usec = 0; - if (utimes(tmppath ? tmppath : path, tv)) - warn("%s: utimes()", tmppath ? tmppath : path); - } - - /* timed out or interrupted? */ - if (fetchLastErrCode == FETCH_TIMEOUT) - sigalrm = 1; - if (sigalrm) - warnx("transfer timed out"); - if (sigint) { - warnx("transfer interrupted"); - goto failure; - } - - /* timeout / interrupt before connection completley established? */ - if (f == NULL) - goto failure; - - if (!sigalrm && ferror(of)) { - /* check the status of our files */ - warn("writing to %s failed", path); - goto failure; - } - - /* did the transfer complete normally? */ - if (us.size != -1 && count < us.size) { - warnx("%s appears to be truncated: %jd/%jd bytes", - path, (intmax_t)count, (intmax_t)us.size); - goto failure_keep; - } - - /* - * If the transfer timed out and we didn't know how much to - * expect, assume the worst (i.e. we didn't get all of it) - */ - if (sigalrm && us.size == -1) { - warnx("%s may be truncated", path); - goto failure_keep; - } - - success: - r = 0; - if (tmppath != NULL && rename(tmppath, path) == -1) { - warn("%s: rename()", path); - goto failure_keep; - } - goto done; - failure: - if (of && of != stdout && !R_flag && !r_flag) - if (stat(path, &sb) != -1 && (sb.st_mode & S_IFREG)) - unlink(tmppath ? tmppath : path); - if (R_flag && tmppath != NULL && sb.st_size == -1) - rename(tmppath, path); /* ignore errors here */ - failure_keep: - r = -1; - goto done; - done: - if (f) - fetchIO_close(f); - if (of && of != stdout) - fclose(of); - if (url) - fetchFreeURL(url); - if (tmppath != NULL) - free(tmppath); - return (r); -} - -static void -usage(void) -{ -#ifndef __minix - fprintf(stderr, "%s\n%s\n%s\n", - "usage: fetch [-146AFMPRUadilmnpqrsv] [-N netrc] [-o outputfile]", - " [-S bytes] [-B bytes] [-T seconds] [-w seconds]", - " [-h host -f file [-c dir] | URL ...]"); -#else - fprintf(stderr, "%s\n%s\n%s\n", - "usage: fetch [-146AFMPRUadilmnpqrsv] [-N netrc] [-o outputfile]", - " [-S bytes] [-B bytes] [-T seconds] [-w seconds]", - " [-h host -f file [-c dir] | URL ...]"); -#endif -} - - -/* - * Entry point - */ -int -main(int argc, char *argv[]) -{ - struct stat sb; - struct sigaction sa; - const char *p, *s; - char *end, *q; - int c, e, r; -#ifndef __minix - while ((c = getopt(argc, argv, - "14AaB:dFilMmN:no:qRrS:sT:Uvw:")) != -1) -#else - while ((c = getopt(argc, argv, - "146AaB:dFilMmN:no:qRrS:sT:Uvw:")) != -1) -#endif - switch (c) { - case '1': - once_flag = 1; - break; - case '4': - family = PF_INET; - break; -#ifndef __minix - case '6': - family = PF_INET6; - break; -#endif - case 'A': - A_flag = 1; - break; - case 'a': - a_flag = 1; - break; - case 'B': - B_size = (off_t)strtol(optarg, &end, 10); - if (*optarg == '\0' || *end != '\0') - errx(1, "invalid buffer size (%s)", optarg); - break; - case 'd': - d_flag = 1; - break; - case 'F': - F_flag = 1; - break; - case 'i': - i_flag = 1; - break; - case 'l': - l_flag = 1; - break; - case 'o': - o_flag = 1; - o_filename = optarg; - break; - case 'M': - case 'm': - if (r_flag) - errx(1, "the -m and -r flags " - "are mutually exclusive"); - m_flag = 1; - break; - case 'N': - N_filename = optarg; - break; - case 'n': - n_flag = 1; - break; - case 'q': - v_level = 0; - break; - case 'R': - R_flag = 1; - break; - case 'r': - if (m_flag) - errx(1, "the -m and -r flags " - "are mutually exclusive"); - r_flag = 1; - break; - case 'S': - S_size = (off_t)strtol(optarg, &end, 10); - if (*optarg == '\0' || *end != '\0') - errx(1, "invalid size (%s)", optarg); - break; - case 's': - s_flag = 1; - break; - case 'T': - T_secs = strtol(optarg, &end, 10); - if (*optarg == '\0' || *end != '\0') - errx(1, "invalid timeout (%s)", optarg); - break; - case 'U': - U_flag = 1; - break; - case 'v': - v_level++; - break; - case 'w': - a_flag = 1; - w_secs = strtol(optarg, &end, 10); - if (*optarg == '\0' || *end != '\0') - errx(1, "invalid delay (%s)", optarg); - break; - default: - usage(); - exit(EX_USAGE); - } - - argc -= optind; - argv += optind; - - if (!argc) { - usage(); - exit(EX_USAGE); - } - - fetchConnectionCacheInit(10, 1); - - /* allocate buffer */ - if (B_size < MINBUFSIZE) - B_size = MINBUFSIZE; - if ((buf = malloc(B_size)) == NULL) - errx(1, "%s", strerror(ENOMEM)); - - /* timeouts */ - if ((s = getenv("FTP_TIMEOUT")) != NULL) { - ftp_timeout = strtol(s, &end, 10); - if (*s == '\0' || *end != '\0' || ftp_timeout < 0) { - warnx("FTP_TIMEOUT (%s) is not a positive integer", s); - ftp_timeout = 0; - } - } - if ((s = getenv("HTTP_TIMEOUT")) != NULL) { - http_timeout = strtol(s, &end, 10); - if (*s == '\0' || *end != '\0' || http_timeout < 0) { - warnx("HTTP_TIMEOUT (%s) is not a positive integer", s); - http_timeout = 0; - } - } - - /* signal handling */ - sa.sa_flags = 0; - sa.sa_handler = sig_handler; - sigemptyset(&sa.sa_mask); - sigaction(SIGALRM, &sa, NULL); - sa.sa_flags = SA_RESETHAND; - sigaction(SIGINT, &sa, NULL); - - /* output file */ - if (o_flag) { - if (strcmp(o_filename, "-") == 0) { - o_stdout = 1; - if (i_flag) { - warnx("-i and -o - are incompatible, dropping -i"); - i_flag = 0; - } - } else if (stat(o_filename, &sb) == -1) { - if (errno == ENOENT) { - if (argc > 1) - errx(EX_USAGE, "%s is not a directory", - o_filename); - } else { - err(EX_IOERR, "%s", o_filename); - } - } else { - if (sb.st_mode & S_IFDIR) - o_directory = 1; - } - } - - /* check if output is to a tty (for progress report) */ - v_tty = isatty(STDERR_FILENO); - if (v_tty) - pgrp = getpgrp(); - - r = 0; - - /* authentication */ - if (v_tty) - fetchAuthMethod = query_auth; - if (N_filename != NULL) - setenv("NETRC", N_filename, 1); - - while (argc) { - if ((p = strrchr(*argv, '/')) == NULL) - p = *argv; - else - p++; - - if (!*p) - p = "fetch.out"; - - fetchLastErrCode = 0; - - if (o_flag) { - if (o_stdout) { - e = fetch(*argv, "-"); - } else if (o_directory) { -#ifndef __minix - asprintf(&q, "%s/%s", o_filename, p); -#else - { - int len; - - if ((q = malloc(sizeof(char)*MINBUFSIZE)) != NULL) { - len = snprintf(q, MINBUFSIZE, "%s/%s", o_filename, p); - if (len >= MINBUFSIZE) { - free(q); - q = NULL; - } - }else{ - err(1, "Unable to allocate memory"); - } - } -#endif - e = fetch(*argv, q); - free(q); - } else { - e = fetch(*argv, o_filename); - } - } else { - e = fetch(*argv, p); - } - - if (sigint) - kill(getpid(), SIGINT); - - if (e == 0 && once_flag) - exit(0); - - if (e) { - r = 1; - if ((fetchLastErrCode - && fetchLastErrCode != FETCH_UNAVAIL - && fetchLastErrCode != FETCH_MOVED - && fetchLastErrCode != FETCH_URL - && fetchLastErrCode != FETCH_RESOLV - && fetchLastErrCode != FETCH_UNKNOWN)) { - if (w_secs && v_level) - fprintf(stderr, "Waiting %ld seconds " - "before retrying\n", w_secs); - if (w_secs) - sleep(w_secs); - if (a_flag) - continue; - } - } - - argc--, argv++; - } - - exit(r); -} diff --git a/minix/commands/fsck.mfs/Makefile b/minix/commands/fsck.mfs/Makefile deleted file mode 100644 index a1482444b..000000000 --- a/minix/commands/fsck.mfs/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -FSCK= ${NETBSDSRCDIR}/sbin/fsck -PROG= fsck_mfs -SRCS= fsck.c -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/fs -I${FSCK} -BINDIR= /sbin -MAN= fsck.mfs.1 - -.include diff --git a/minix/commands/partition/Makefile b/minix/commands/partition/Makefile deleted file mode 100644 index 89b1747a4..000000000 --- a/minix/commands/partition/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= partition -MAN= partition.8 - -# We need this to find our partition.h while compiling natively -# on non-Minix. -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/include/arch/${MACHINE_ARCH}/include - -.include diff --git a/minix/commands/writeisofs/Makefile b/minix/commands/writeisofs/Makefile deleted file mode 100644 index bb88f5852..000000000 --- a/minix/commands/writeisofs/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -PROG= writeisofs -MAN= - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/include/arch/${MACHINE_ARCH}/include - -.include diff --git a/minix/drivers/bus/pci/Makefile b/minix/drivers/bus/pci/Makefile deleted file mode 100644 index 94c4dccfb..000000000 --- a/minix/drivers/bus/pci/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -.include - -# Makefile for PCI support -PROG= pci -SRCS= main.c pci.c pci_table.c - -# Directly taken from sys/dev/pci -SRCS+= dev_verbose.c pci_subr.c - -.PATH.c: ${NETBSDSRCDIR}/sys/dev/pci -.PATH.c: ${NETBSDSRCDIR}/sys/dev - -CPPFLAGS+= -I ${NETBSDSRCDIR}/sys -CPPFLAGS.pci_subr.c+= -D_PCI_SERVER - -CWARNFLAGS.clang=-Wno-unused - -DPADD+= ${LIBCHARDRIVER} -LDADD+= -lchardriver - -DPADD+= ${LIBACPI} -LDADD+= -lacpi - -WARNS= 3 - -.include diff --git a/minix/drivers/eeprom/cat24c256/Makefile b/minix/drivers/eeprom/cat24c256/Makefile deleted file mode 100644 index 457d33961..000000000 --- a/minix/drivers/eeprom/cat24c256/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile for the i2c eeprom commonly found on the BeagleBone (CAT24C256) -PROG= cat24c256 -SRCS= cat24c256.c - -DPADD+= ${LIBI2CDRIVER} ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lblockdriver -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/drivers/net/ip1000/Makefile b/minix/drivers/net/ip1000/Makefile deleted file mode 100644 index d8ac6c81c..000000000 --- a/minix/drivers/net/ip1000/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Makefile for the Ethernet drivers -PROG= ip1000 -SRCS= ip1000.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBNETDRIVER} ${LIBSYS} -LDADD+= -lnetdriver -lsys - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -.include diff --git a/minix/drivers/net/rtl8139/Makefile b/minix/drivers/net/rtl8139/Makefile deleted file mode 100644 index dfba27e70..000000000 --- a/minix/drivers/net/rtl8139/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for the Realtek RTL8139 ethernet driver (RTL8139) -PROG= rtl8139 -SRCS= rtl8139.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBNETDRIVER} ${LIBSYS} -LDADD+= -lnetdriver -lsys - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -WARNS?= 5 - -.include diff --git a/minix/drivers/net/rtl8169/Makefile b/minix/drivers/net/rtl8169/Makefile deleted file mode 100644 index d4861ac10..000000000 --- a/minix/drivers/net/rtl8169/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for the Realtek RTL8169 ethernet driver (RTL8169) -PROG= rtl8169 -SRCS= rtl8169.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBNETDRIVER} ${LIBSYS} -LDADD+= -lnetdriver -lsys - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -WARNS?= 5 - -.include diff --git a/minix/drivers/net/vt6105/Makefile b/minix/drivers/net/vt6105/Makefile deleted file mode 100644 index 8ac42452f..000000000 --- a/minix/drivers/net/vt6105/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Makefile for the VIA Technology 6105/6106S Ethernet driver (vt6105) -PROG= vt6105 -SRCS= vt6105.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBNETDRIVER} ${LIBSYS} -LDADD+= -lnetdriver -lsys - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -.include diff --git a/minix/drivers/power/tps65217/Makefile b/minix/drivers/power/tps65217/Makefile deleted file mode 100644 index d79636b86..000000000 --- a/minix/drivers/power/tps65217/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile for the tps65217 Power Management IC found on the BeagleBones -PROG= tps65217 -SRCS= tps65217.c - -DPADD+= ${LIBI2CDRIVER} ${LIBCLKCONF} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lclkconf -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/drivers/power/tps65950/Makefile b/minix/drivers/power/tps65950/Makefile deleted file mode 100644 index 027aa8b36..000000000 --- a/minix/drivers/power/tps65950/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile for the tps65950 PMIC found on the BeagleBoard-xM. -PROG= tps65950 -SRCS= tps65950.c tps65950.h rtc.c rtc.h - -DPADD+= ${LIBI2CDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/drivers/sensors/bmp085/Makefile b/minix/drivers/sensors/bmp085/Makefile deleted file mode 100644 index 8f3f9cd4b..000000000 --- a/minix/drivers/sensors/bmp085/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# Makefile for the bmp085 pressure and temp sensor found on the Weather Cape. - -PROG= bmp085 -SRCS= bmp085.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBI2CDRIVER} ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lchardriver -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/drivers/sensors/sht21/Makefile b/minix/drivers/sensors/sht21/Makefile deleted file mode 100644 index c1676b31c..000000000 --- a/minix/drivers/sensors/sht21/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# Makefile for the sht21 humidity and temp sensor found on the Weather Cape. - -PROG= sht21 -SRCS= sht21.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBI2CDRIVER} ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lchardriver -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/drivers/sensors/tsl2550/Makefile b/minix/drivers/sensors/tsl2550/Makefile deleted file mode 100644 index 6afbbecd5..000000000 --- a/minix/drivers/sensors/tsl2550/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# Makefile for the tsl2550 ambient light sensor found on the Weather Cape. - -PROG= tsl2550 -SRCS= tsl2550.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -DPADD+= ${LIBI2CDRIVER} ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lchardriver -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/drivers/storage/memory/Makefile b/minix/drivers/storage/memory/Makefile deleted file mode 100644 index 860b5e79e..000000000 --- a/minix/drivers/storage/memory/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Makefile for memory driver (MEMORY) -.include - -USE_BITCODE:=no - -PROG= memory -SRCS= memory.c imgrd.mfs -OBJS= ${SRCS:N*.h:R:S/$/.o/g} -MKBUILDEXT2RD?= no - -RAMDISK_PATH= ${NETBSDSRCDIR}/minix/drivers/storage/ramdisk -DPADD+= ${LIBBLOCKDRIVER} ${LIBCHARDRIVER} -LDADD+= -lblockdriver -lchardriver - -CPPFLAGS.memory.c+= -I${NETBSDSRCDIR}/minix - -imgrd.d: touch-genfiles -touch-genfiles: - [ -e ../ramdisk/image ] || touch -t 197001020000.00 ../ramdisk/image - - -.SUFFIXES: .mfs .c .o - -.mfs.o: - ${_MKTARGET_CREATE} - ${OBJCOPY} -Ibinary -B${MACHINE_CPU} -O${MACHINE_GNU_PLATFORM} $< $@ - -CLEANFILES+= ../ramdisk/image -# BJG - don't invoke parallel Makes -#../ramdisk/image: .PHONY -# ${MAKE} -C ${RAMDISK_PATH} image - -CLEANFILES+= imgrd.mfs -imgrd.mfs: ../ramdisk/image - ${HOST_LN} -fs ../ramdisk/image $@ - -.include diff --git a/minix/drivers/storage/ramdisk/Makefile b/minix/drivers/storage/ramdisk/Makefile deleted file mode 100644 index db0a1da21..000000000 --- a/minix/drivers/storage/ramdisk/Makefile +++ /dev/null @@ -1,218 +0,0 @@ -# Makefile for ramdisk image -.include - -USE_BITCODE:=no - -install: - -all: - -# Add a few defines we are going to use during the image -# creation to determine what features and binaries to include -# in the final image -# ACPI do we have/include the acpi binary -# RAMDISK_SMALL is the script called with MKSMALL=yes -# DYNAMIC does the ramdisk contain dynamic binaries? -RAMDISK_INC_ACPI= 0 -RAMDISK_SMALL= 0 -RAMDISK_DYNAMIC= 0 - -RAMDISK_DEFINES= \ - -DRAMDISK_INC_ACPI=${RAMDISK_INC_ACPI} \ - -DRAMDISK_SMALL=${RAMDISK_SMALL} \ - -DRAMDISK_DYNAMIC=${RAMDISK_DYNAMIC} - -# The name of the proto file to use -PROTO= proto - -# Common to all architectures -ETC= system.conf group -EXTRA= rc -PROTO_FILES= proto.common.etc -PROTO_FILES+= proto.common.dynamic -PROGRAMS= # defined -PROGRAMS+= fsck_mfs -dir.fsck_mfs:= minix/commands/fsck.mfs -PROGRAMS+= grep -dir.grep:= minix/usr.bin/grep -PROGRAMS+= input -dir.input:= minix/servers/input -PROGRAMS+= loadramdisk -dir.loadramdisk:= minix/commands/loadramdisk -PROGRAMS+= mfs -dir.mfs:= minix/fs/mfs -PROGRAMS+= mount -dir.mount:= minix/commands/mount -PROGRAMS+= procfs -dir.procfs:= minix/fs/procfs -PROGRAMS+= minix-service -dir.minix-service:= minix/commands/minix-service -PROGRAMS+= sh -dir.sh:= bin/sh -PROGRAMS+= sysenv -dir.sysenv:= minix/commands/sysenv -PROGRAMS+= umount -dir.umount:= minix/commands/umount - -.if ${MKSMALL} != "yes" -RAMDISK_SMALL= 1 -.endif - -.if ${MACHINE_ARCH} == "i386" -ETC+= rs.single -PROGRAMS+= at_wini -dir.at_wini:= minix/drivers/storage/at_wini -PROGRAMS+= floppy -dir.floppy:= minix/drivers/storage/floppy -PROGRAMS+= pci -dir.pci:= minix/drivers/bus/pci -PROGRAMS+= pckbd -dir.pckbd:= minix/drivers/hid/pckbd -PROGRAMS+= cdprobe -dir.cdprobe:= minix/commands/cdprobe -PROGRAMS+= pwd_mkdb -dir.pwd_mkdb:= usr.sbin/pwd_mkdb -PROGRAMS+= isofs -dir.isofs:= minix/fs/isofs - -.if ${MKSMALL} != "yes" -PROGRAMS+= ahci -dir.ahci:= minix/drivers/storage/ahci -PROGRAMS+= virtio_blk -dir.virtio_blk:= minix/drivers/storage/virtio_blk -PROGRAMS+= ext2 -dir.ext2:= minix/fs/ext2 -.endif - -.if ${MKACPI} != "no" -RAMDISK_INC_ACPI= 1 -PROGRAMS+= acpi -dir.acpi:= minix/drivers/power/acpi -.endif -.endif # ${MACHINE_ARCH} == "i386" - -.if ${MACHINE_ARCH} == "earm" -PROGRAMS+= mmc -dir.mmc:= minix/drivers/storage/mmc -.endif # ${MACHINE_ARCH} == "earm" - -.if ${LDSTATIC} == "-dynamic" -RAMDISK_DYNAMIC= 1 -PROGRAMS+= ld.elf_so -PROG_LIBS+= libc -PROG_MINIXLIBS+= libterminfo -.endif - -CPPFLAGS+= -I${NETBSDSRCDIR}/servers - -# LSC We have to take care of not erasing the source file, so never add EXTRA -# to CLEANFILES -CLEANFILES += ${PROGRAMS} ${SCRIPTS} ${ETC} image image.c -CLEANFILES += proto.gen proto.dev proto.dev.mtree -CLEANFILES += ${PROG_LIBEXEC} -CLEANFILES += ${.OBJDIR}/etc/* - -############################################################# -# LSC Below this point the rules should not be modified -############################################################# - -# Tool to bootstrap the password db -TOOL_PWD_MKDB?= ${NETBSDSRCDIR}/usr.sbin/pwd_mkdb/pwd_mkdb - -# Remove "drivers/storage/ramdisk" component from path -PROGROOT:= ${.OBJDIR:S,/minix/drivers/storage/ramdisk,,} - -# Generate dependencies rules for config files -.for etc in ${ETC} -etc/${etc}: ${NETBSDSRCDIR}/etc/${etc} - mkdir -p ${.OBJDIR}/etc - ${INSTALL} $> $@ -.endfor - -# LSC Force the regeneration of the proto file as it seems sometimes -# they are not copied over as needed. -# LSC ramdisk rc file != /etc/rc -# BJG if ${.CURDIR} == ${.OBJDIR}, we are building in-tree and install -# shouldn't try to install the originals over the originals. Otherwise -# we are building out-of-tree and the contents should be copied -# unconditionally in case the contents have changed after the first copy. -.if ${.CURDIR} != ${.OBJDIR} -.for file in ${EXTRA} ${PROTO} ${PROTO_FILES} -CLEANFILES += ${.OBJDIR}/${file} -${file}: ${NETBSDSRCDIR}/minix/drivers/storage/ramdisk/${file} .PHONY - ${INSTALL} $> $@ -.endfor -.endif - -# Generate dependencies rules for dynamic libraries, if needed -.for lib in ${PROG_LIBS} -PROGRAMS+= ${lib}.so.0 -CLEANFILES += ${lib}.so.0 -${lib}.so.0:${PROGROOT}/lib/${lib}/${lib}.so.0 - ${INSTALL} $> $@ - -# BJG - Don't invoke parallel Makes -#${PROGROOT}/lib/${lib}/${lib}.so.0: -# ${MAKE} -C ${NETBSDSRCDIR}/lib/${lib} all -.endfor - -.for lib in ${PROG_MINIXLIBS} -PROGRAMS+= ${lib}.so.0 -CLEANFILES += ${lib}.so.0 -${lib}.so.0:${PROGROOT}/minix/lib/${lib}/${lib}.so.0 - ${INSTALL} $> $@ - -# BJG - Don't invoke parallel Makes -#${PROGROOT}/minix/lib/${lib}/${lib}.so.0: -# ${MAKE} -C ${NETBSDSRCDIR}/minix/lib/${lib} all -.endfor - -# Generate dependencies rules for binaries -.for prog in ${PROGRAMS} -${prog}: ${PROGROOT}/${dir.${prog}}/${prog} - ${INSTALL} $> $@ - -# BJG - don't invoke parallel Makes -#${PROGROOT}/${dir.${prog}}/${prog}: -# ${MAKE} -C ${NETBSDSRCDIR}/${dir.${prog}} all -.endfor # prog - -realall image: proto.gen ${ETC:C/^/etc\//} ${EXTRA} \ - etc/master.passwd etc/pwd.db etc/spwd.db etc/passwd etc/group - ${_MKMSG_CREATE} "Generating ramdisk image" - ${TOOL_MKFSMFS} image proto.gen || { rm -f image; false; } - -etc/pwd.db etc/spwd.db etc/passwd: etc/master.passwd - -etc/master.passwd: ${NETBSDSRCDIR}/etc/master.passwd - mkdir -p ${.OBJDIR}/etc - ${INSTALL} $> $@ - ${TOOL_PWD_MKDB} -V 0 -p -d . etc/master.passwd - -proto.dev.mtree: - @echo ". type=dir uname=root gname=wheel mode=0755" \ - >${.TARGET}.tmp && \ - echo "./dev type=dir uname=root gname=wheel mode=0755" \ - >>${.TARGET}.tmp && \ - ${NETBSDSRCDIR}/minix/commands/MAKEDEV/MAKEDEV.sh -m -r \ - >> ${.TARGET}.tmp && mv ${.TARGET}.tmp ${.TARGET} - -# We have to remove the two first entries of the generated proto file, as -# well as the two last ones (closing $). -# Do not forget to double $ so that make doesn't try to expand it. -proto.dev: proto.dev.mtree etc/pwd.db etc/spwd.db etc/passwd etc/group - ${TOOL_MTREE} -f ${.TARGET}.mtree -N ${.OBJDIR}/etc -C -K device | \ - ${TOOL_TOPROTO} | ${TOOL_SED} -e '1,4d' | \ - ${TOOL_SED} -e '$$d' |${TOOL_SED} -e '$$d' > ${.TARGET}.tmp - grep console ${.TARGET}.tmp # sanity check; is there a console entry? - mv ${.TARGET}.tmp ${.TARGET} - -proto.gen: ${PROTO} ${PROTO_FILES} proto.dev ${PROGRAMS} - ${STRIP} ${PROGRAMS} - # We are using the c preprocessor to generate proto.gen - # used in the mkfs tool. - ${TOOL_CAT} ${PROTO} | ${CC} \ - ${RAMDISK_DEFINES} \ - -E - | grep -v "^$$" | grep -v "#" >${.TARGET} - -.include diff --git a/minix/drivers/system/random/Makefile b/minix/drivers/system/random/Makefile deleted file mode 100644 index 00c96af5a..000000000 --- a/minix/drivers/system/random/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for random driver (RANDOM) -PROG= random -SRCS= main.c random.c rijndael_api.c rijndael_alg.c - -FILES=${PROG}.conf -FILESNAME=${PROG} -FILESDIR= /etc/system.conf.d - -.PATH: ${.CURDIR}/aes - -DPADD+= ${LIBCHARDRIVER} ${LIBSYS} -LDADD+= -lchardriver -lsys - -CPPFLAGS.random.c+= -I${NETBSDSRCDIR}/minix - -.include diff --git a/minix/drivers/tty/tty/Makefile b/minix/drivers/tty/tty/Makefile deleted file mode 100644 index cdcda983f..000000000 --- a/minix/drivers/tty/tty/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Makefile for terminal driver (TTY) -PROG= tty - -.include "arch/${MACHINE_ARCH}/Makefile.inc" - -SRCS += tty.c - -DPADD+= ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -lchardriver -lsys -ltimers - -SUBDIR= keymaps - -# Needs kernel/const.h, etc -CPPFLAGS+= -I${.CURDIR} -I${NETBSDSRCDIR} - -.include -.include diff --git a/minix/drivers/tty/tty/keymaps/Makefile b/minix/drivers/tty/tty/keymaps/Makefile deleted file mode 100644 index 2f835ac7d..000000000 --- a/minix/drivers/tty/tty/keymaps/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# Generate binary keymaps. - -.include - -FILES= dvorak.map french.map german.map hungarian.map italian.map \ - japanese.map latin-america.map norwegian.map polish.map \ - russian-cp866.map russian.map scandinavian.map \ - spanish.map uk.map us-std.map us-swap.map russian-cp1251.map \ - ukraine-koi8-u.map portuguese.map abnt2.map colemak.map - -FILESDIR= /usr/lib/keymaps - -.SUFFIXES: .src .map - -HOST_CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -.src.map: - ${_MKTARGET_CREATE} - ${HOST_CC} ${HOST_CFLAGS} ${HOST_CPPFLAGS} ${HOST_LDFLAGS} -DKEYSRC=\"$<\" -o ${.OBJDIR}/${.TARGET}_genmap ${.CURDIR}/genmap.c - ${.OBJDIR}/${.TARGET}_genmap > ${.OBJDIR}/${.TARGET} - rm -f ${.OBJDIR}/${.TARGET}_genmap - -realall: ${FILES} - -CLEANFILES+= ${FILES} - -.include diff --git a/minix/drivers/video/tda19988/Makefile b/minix/drivers/video/tda19988/Makefile deleted file mode 100644 index fe4358dc7..000000000 --- a/minix/drivers/video/tda19988/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile for the tda19988 HDMI framer found on the BeagleBone Black. -PROG= tda19988 -SRCS= tda19988.c - -DPADD+= ${LIBI2CDRIVER} ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBTIMERS} -LDADD+= -li2cdriver -lblockdriver -lsys -ltimers - -CPPFLAGS+= -I${NETBSDSRCDIR} - -.include diff --git a/minix/fs/procfs/Makefile b/minix/fs/procfs/Makefile deleted file mode 100644 index 8fb44e97b..000000000 --- a/minix/fs/procfs/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Makefile for ProcFS server -.include - -PROG= procfs -SRCS= buf.c cpuinfo.c main.c pid.c root.c service.c tree.c util.c - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/fs -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/servers - -DPADD+= ${LIBVTREEFS} ${LIBFSDRIVER} -LDADD+= -lvtreefs -lfsdriver - -.include diff --git a/minix/include/minix/driver.h b/minix/include/minix/driver.h deleted file mode 100644 index 2995fef45..000000000 --- a/minix/include/minix/driver.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _MINIX_DRIVER_H -#define _MINIX_DRIVER_H - -/* Types and constants shared between block and character drivers. */ - -#define _POSIX_SOURCE 1 /* tell headers to include POSIX stuff */ -#define _NETBSD_SOURCE 1 /* tell headers to include MINIX stuff */ -#define _SYSTEM 1 /* get negative error number in */ - -/* The following are so basic, all the *.c files get them automatically. */ -#include /* MUST be first */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Base and size of a partition in bytes. */ -struct device { - u64_t dv_base; - u64_t dv_size; -}; - -/* Generic receive function for all drivers. */ -#ifndef driver_receive -#define driver_receive sef_receive_status -#endif - -/* Maximum supported number of concurrently opened minor devices. */ -#define MAX_NR_OPEN_DEVICES 256 - -#endif /* _MINIX_DRIVER_H */ diff --git a/minix/include/minix/drivers.h b/minix/include/minix/drivers.h deleted file mode 100644 index da94fef14..000000000 --- a/minix/include/minix/drivers.h +++ /dev/null @@ -1,45 +0,0 @@ -/* This is the master header for all device drivers. It includes some other - * files and defines the principal constants. - */ - -#ifndef _INC_DRIVERS_H -#define _INC_DRIVERS_H - -#define _POSIX_SOURCE 1 /* tell headers to include POSIX stuff */ -#define _NETBSD_SOURCE 1 /* tell headers to include MINIX stuff */ -#define _SYSTEM 1 /* get negative error number in */ - -/* The following are so basic, all the *.c files get them automatically. */ -#include /* MUST be first */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* IRQ vectors and miscellaneous ports */ -#if defined(__i386__) -#include /* BIOS index numbers */ -#include /* Well-known ports */ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/minix/kernel/Makefile b/minix/kernel/Makefile deleted file mode 100644 index ec4c160fa..000000000 --- a/minix/kernel/Makefile +++ /dev/null @@ -1,113 +0,0 @@ -# Makefile for kernel -.include - -PROG= kernel -BINDIR= /usr/sbin -MAN= - -.if ${MACHINE_ARCH} == "earm" && ${MKLLVM:Uno} == "yes" -# BJG - problems with optimisation of the kernel by llvm -DBG=-O0 -.endif - -.include "arch/${MACHINE_ARCH}/Makefile.inc" - -SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \ - table.c utility.c usermapped_data.c - -LDADD+= -ltimers -lsys -lexec - -LINKERSCRIPT= ${.CURDIR}/arch/${MACHINE_ARCH}/kernel.lds - -.if ${HAVE_GOLD:U} != "" -CFLAGS+= -fno-common -.endif -LDFLAGS+= -T ${LINKERSCRIPT} -LDFLAGS+= -nostdlib -L${DESTDIR}/usr/lib -CFLAGS += -fno-stack-protector - -CPPFLAGS+= -D__kernel__ - -# kernel headers are always called through kernel/*.h -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -# kernel headers are always called through kernel/*.h, this -# time for generated headers, during cross compilation -CPPFLAGS+= -I${.OBJDIR}/.. - -# Machine-dependent headers, order is important! -CPPFLAGS+= -I${.CURDIR}/arch/${MACHINE_ARCH} -CPPFLAGS+= -I${.CURDIR}/arch/${MACHINE_ARCH}/include -CPPFLAGS+= -I${.CURDIR}/arch/${MACHINE_ARCH}/bsp/include -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/include/arch/${MACHINE_ARCH}/include - -.include "system/Makefile.inc" - -.if ${MKPAE:Uno} != "no" -CPPFLAGS+= -DPAE=1 -.endif - -.ifdef CONFIG_SMP -SRCS+= smp.c -.endif - -.if ${USE_WATCHDOG} != "no" -SRCS+= watchdog.c -CPPFLAGS+= -DUSE_WATCHDOG=1 -.endif - -# Extra debugging routines -.if ${USE_SYSDEBUG} != "no" -SRCS+= debug.c -CPPFLAGS+= -DUSE_SYSDEBUG=1 -.endif - -# These come last, so the profiling buffer is at the end of the data segment -SRCS+= profile.c do_sprofile.c - -.if ${USE_LIVEUPDATE} != "no" -CPPFLAGS+= -DUSE_UPDATE=1 -.endif - -CLEANFILES+=extracted-errno.h extracted-mfield.h extracted-mtype.h procoffsets.h - -debug.o debug.d: extracted-errno.h extracted-mfield.h extracted-mtype.h - -extracted-errno.h: extract-errno.sh ../../include/errno.h - ${_MKTARGET_CREATE} - cd ${.CURDIR} ; ${HOST_SH} extract-errno.sh > ${.OBJDIR}/extracted-errno.h - -extracted-mfield.h: extract-mfield.sh ../lib/libc/sys/*.c ../lib/libsys/*.c - ${_MKTARGET_CREATE} - cd ${.CURDIR} ; ${HOST_SH} extract-mfield.sh > ${.OBJDIR}/extracted-mfield.h - -extracted-mtype.h: extract-mtype.sh ../include/minix/com.h - ${_MKTARGET_CREATE} - cd ${.CURDIR} ; ${HOST_SH} extract-mtype.sh > ${.OBJDIR}/extracted-mtype.h - -.if ${USE_BITCODE:Uno} == "yes" -# dcvmoole: this is a copy of the "${_P}: ${_P}.bcl.o" block from bsd.prog.mk, -# with two changes: 1) ${OBJS} is added so as to link in objects that have not -# been compiled with bitcode, and 2) we are directly loading the gold plugin -# rather than through ${BITCODE_LD_FLAGS_2ND.kernel}, because LLVMgold will -# not load libLTO when no LTO can be performed (due to the non- bitcode -# objects), causing it to fail on unrecognized -disable-opt/-disable-inlining -# options. At least I think that's what's going on? I'm no expert here.. -kernel: kernel.bcl.o - ${_MKTARGET_LINK} - ${_CCLINK.kernel} \ - ${_LDFLAGS.kernel} \ - -L${DESTDIR}/usr/lib \ - ${_LDSTATIC.kernel} -o ${.TARGET} \ - ${.TARGET}.bcl.o ${OBJS} ${_PROGLDOPTS} ${_LDADD.kernel} \ - -Wl,-plugin=${GOLD_PLUGIN} \ - -Wl,--allow-multiple-definition -.endif - -# Disable magic and ASR passes for the kernel. -USE_MAGIC=no - -# Disable coverage profiling for the kernel, at least for now. -MKCOVERAGE=no - -.include diff --git a/minix/kernel/arch/earm/Makefile.inc b/minix/kernel/arch/earm/Makefile.inc deleted file mode 100644 index ccb3a8dc2..000000000 --- a/minix/kernel/arch/earm/Makefile.inc +++ /dev/null @@ -1,98 +0,0 @@ -# Makefile for arch-dependent kernel code -.include - -HERE=${.CURDIR}/arch/${MACHINE_ARCH} -.PATH: ${HERE} - -# objects we want unpaged from -lc -MINLIB_OBJS_UNPAGED= get_bp.o -get_bp.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/arm/get_bp.S - -# objects we want unpaged from -lsys -SYS_OBJS_UNPAGED=assert.o stacktrace.o -assert.o: ${NETBSDSRCDIR}/minix/lib/libsys/assert.c -stacktrace.o: ${NETBSDSRCDIR}/minix/lib/libsys/stacktrace.c - -# objects we want unpaged from -lminc -MINC_OBJS_UNPAGED= atoi.o \ - printf.o subr_prf.o \ - strcmp.o strcpy.o strlen.o strncmp.o \ - memcpy.o memmove.o memset.o -MINC_OBJS_UNPAGED+= divmodsi4.o divsi3.o udivsi3.o umodsi3.o \ - umoddi3.o udivmoddi4.o __aeabi_idiv0.o aeabi_idivmod.o aeabi_uidivmod.o \ - udivmodsi4.o aeabi_uldivmod.o -atoi.o: ${NETBSDSRCDIR}/minix/lib/libminc/atoi.c -printf.o: ${NETBSDSRCDIR}/sys/lib/libsa/printf.c -subr_prf.o: ${NETBSDSRCDIR}/sys/lib/libsa/subr_prf.c -memcpy.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/memcpy.S -memmove.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/memmove.S -memset.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/memset.S -strlen.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strlen.S -strcpy.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcpy.S -strcmp.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcmp.S -__aeabi_idiv0.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/__aeabi_idiv0.c -CPPFLAGS.__aeabi_idiv0.c+= -D_STANDALONE -I${NETBSDSRCDIR}/sys - -divsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/divsi3.c -udivsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/udivsi3.c -umodsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/umodsi3.c -umoddi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/umoddi3.c -udivmoddi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/udivmoddi4.c -divmodsi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/divmodsi4.S -udivmodsi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/udivmodsi4.S -aeabi_idivmod.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/aeabi_idivmod.S -aeabi_uidivmod.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/aeabi_uidivmod.S -aeabi_uldivmod.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/aeabi_uldivmod.S - -# the following is required by pre_init.c -strncmp.o: ${NETBSDSRCDIR}/common/lib/libc/string/strncmp.c - -# LSC: putchar and kputc have the same signature. A bit hackish. -CPPFLAGS.subr_prf.c+= -Dputchar=kputc - -# Activate optional support, may be deactivated. -CPPFLAGS.subr_prf.c+= -DLIBSA_PRINTF_LONGLONG_SUPPORT -DLIBSA_PRINTF_WIDTH_SUPPORT - -.include "bsp/ti/Makefile.inc" - -# some object files we give a symbol prefix (or namespace) of __k_unpaged_ -# that must live in their own unique namespace. -# -.for unpaged_obj in head.o pre_init.o direct_tty_utils.o \ - pg_utils.o klib.o utility.o arch_reset.o \ - ${MINLIB_OBJS_UNPAGED} ${MINC_OBJS_UNPAGED} ${SYS_OBJS_UNPAGED} ${BSP_OBJS_UNPAGED} -unpaged_${unpaged_obj}: ${unpaged_obj} - ${OBJCOPY} --prefix-symbols=__k_unpaged_ ${.OBJDIR}/${unpaged_obj} $@ -UNPAGED_OBJS += unpaged_${unpaged_obj} -ORIG_UNPAGED_OBJS += ${unpaged_obj} -.endfor - - -CLEANFILES+= ${ORIG_UNPAGED_OBJS} - -SRCS+= mpx.S arch_clock.c arch_do_vmctl.c arch_system.c do_padconf.c \ - exception.c hw_intr.c klib.S memory.c \ - protect.c direct_tty_utils.c arch_reset.c \ - pg_utils.c phys_copy.S phys_memset.S exc.S - -OBJS.kernel+= ${UNPAGED_OBJS} - -klib.o mpx.o head.o: procoffsets.h - -SRCS+= procoffsets.h - -PROCOFFSETSCF=procoffsets.cf - -.PATH: ${NETBSDSRCDIR}/minix/include/arch/${MACHINE_ARCH}/include - -procoffsets.h: ${PROCOFFSETSCF} kernel.h proc.h stackframe.h archtypes.h - ${_MKTARGET_CREATE} - ${TOOL_CAT} ${HERE}/${PROCOFFSETSCF} | \ - ${TOOL_GENASSYM} -- ${CC} ${CFLAGS:N-Wa,*} \ - ${CPPFLAGS} ${PROF} ${${USE_BITCODE:Uno} == "yes":? -fno-lto:} \ - ${GENASSYM_CPPFLAGS} >$@.tmp && \ - mv -f $@.tmp $@ - -sconst.h: procoffsets.h -apic_asm.o head.o klib.o mpx.o: sconst.h - diff --git a/minix/kernel/arch/i386/Makefile.inc b/minix/kernel/arch/i386/Makefile.inc deleted file mode 100644 index 2e13ce45e..000000000 --- a/minix/kernel/arch/i386/Makefile.inc +++ /dev/null @@ -1,126 +0,0 @@ -# Makefile for arch-dependent kernel code -.include - -HERE=${.CURDIR}/arch/${MACHINE_ARCH} -.PATH: ${HERE} - -# objects we want unpaged from -lc -MINLIB_OBJS_UNPAGED= _cpufeature.o _cpuid.o get_bp.o -_cpufeature.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/_cpufeature.c -_cpuid.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/_cpuid.S -get_bp.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/get_bp.S - -# objects we want unpaged from -lsys -SYS_OBJS_UNPAGED=assert.o stacktrace.o -assert.o: ${NETBSDSRCDIR}/minix/lib/libsys/assert.c -stacktrace.o: ${NETBSDSRCDIR}/minix/lib/libsys/stacktrace.c - -# objects we want unpaged from -lminc -MINC_OBJS_UNPAGED= atoi.o \ - printf.o subr_prf.o \ - strcmp.o strcpy.o strlen.o strncmp.o \ - memcpy.o memmove.o memset.o \ - udivdi3.o umoddi3.o qdivrem.o -atoi.o: ${NETBSDSRCDIR}/minix/lib/libminc/atoi.c -printf.o: ${NETBSDSRCDIR}/sys/lib/libsa/printf.c -subr_prf.o: ${NETBSDSRCDIR}/sys/lib/libsa/subr_prf.c -memcpy.o: ${NETBSDSRCDIR}/common/lib/libc/arch/i386/string/memcpy.S -memmove.o: ${NETBSDSRCDIR}/common/lib/libc/arch/i386/string/memmove.S -memset.o: ${NETBSDSRCDIR}/common/lib/libc/arch/i386/string/memset.S -strlen.o: ${NETBSDSRCDIR}/common/lib/libc/arch/i386/string/strlen.S -strcpy.o: ${NETBSDSRCDIR}/common/lib/libc/arch/i386/string/strcpy.S -strcmp.o: ${NETBSDSRCDIR}/common/lib/libc/arch/i386/string/strcmp.S - -# the following is required by pre_init.c -strncmp.o: ${NETBSDSRCDIR}/common/lib/libc/string/strncmp.c - -# these are required by kprintn.o: -udivdi3.o: ${NETBSDSRCDIR}/common/lib/libc/quad/udivdi3.c -umoddi3.o: ${NETBSDSRCDIR}/common/lib/libc/quad/umoddi3.c -qdivrem.o: ${NETBSDSRCDIR}/common/lib/libc/quad/qdivrem.c - -# LSC: putchar and kputc have the same signature. A bit hackish. -CPPFLAGS.subr_prf.c+= -Dputchar=kputc - -# Activate optional support, may be deactivated. -CPPFLAGS.subr_prf.c+= -DLIBSA_PRINTF_LONGLONG_SUPPORT -DLIBSA_PRINTF_WIDTH_SUPPORT - -# some object files we give a symbol prefix (or namespace) of __k_unpaged_ -# that must live in their own unique namespace. -# -.for unpaged_obj in head.o pre_init.o direct_tty_utils.o \ - pg_utils.o klib.o utility.o arch_reset.o \ - io_inb.o io_outb.o \ - ${MINLIB_OBJS_UNPAGED} ${MINC_OBJS_UNPAGED} ${SYS_OBJS_UNPAGED} - -CLEANFILES+=${unpaged_obj}.bin -.if ${USE_BITCODE:Uno} == "yes" -unpaged_${unpaged_obj}: ${unpaged_obj} - if file -b ${.OBJDIR}/${unpaged_obj} | grep -q '^LLVM'; then \ - ${LLC} -O1 -march=x86 -mcpu=i586 -filetype=obj -o ${.OBJDIR}/${unpaged_obj}.bin ${.OBJDIR}/${unpaged_obj}; \ - else \ - cp ${.OBJDIR}/${unpaged_obj} ${.OBJDIR}/${unpaged_obj}.bin; \ - fi - ${OBJCOPY} --prefix-symbols=__k_unpaged_ ${.OBJDIR}/${unpaged_obj}.bin $@ -.else -unpaged_${unpaged_obj}: ${unpaged_obj} - ${OBJCOPY} --prefix-symbols=__k_unpaged_ ${.OBJDIR}/${unpaged_obj} $@ -.endif -UNPAGED_OBJS += unpaged_${unpaged_obj} -ORIG_UNPAGED_OBJS += ${unpaged_obj} -.endfor - -CLEANFILES+= ${ORIG_UNPAGED_OBJS} - -SRCS+= mpx.S arch_clock.c arch_do_vmctl.c arch_system.c \ - klib.S memory.c protect.c direct_tty_utils.c arch_reset.c pg_utils.c - -SRCS+= do_iopenable.c do_readbios.c do_sdevio.c exception.c i8259.c oxpcie.c \ - usermapped_data_arch.c \ - io_inb.S io_inl.S io_intr.S io_inw.S io_outb.S io_outl.S io_outw.S \ - usermapped_glo_ipc.S - -OBJS.kernel+= ${UNPAGED_OBJS} - -.ifdef CONFIG_SMP -SRCS += arch_smp.c trampoline.S -.endif - -.if ${USE_ACPI} != "no" -SRCS+= acpi.c -CPPFLAGS+= -DUSE_ACPI -.endif - -.if ${USE_APIC} != "no" -SRCS+= apic.c apic_asm.S -CPPFLAGS+= -DUSE_APIC -.endif - -.if ${USE_DEBUGREG} != "no" -SRCS+= breakpoints.c debugreg.S -.endif - -.if ${USE_WATCHDOG} != "no" -SRCS+= arch_watchdog.c -CPPFLAGS+= -DUSE_WATCHDOG -.endif - -klib.o mpx.o head.o: procoffsets.h - -SRCS+= procoffsets.h - -PROCOFFSETSCF=procoffsets.cf - -.PATH: ${NETBSDSRCDIR}/minix/include/arch/${MACHINE_ARCH}/include - -procoffsets.h: ${PROCOFFSETSCF} kernel.h proc.h stackframe.h archtypes.h - ${_MKTARGET_CREATE} - ${TOOL_CAT} ${HERE}/${PROCOFFSETSCF} | \ - ${TOOL_GENASSYM} -- ${CC} ${CFLAGS:N-Wa,*} \ - ${CPPFLAGS} ${PROF} ${${USE_BITCODE:Uno} == "yes":? -fno-lto:} \ - ${GENASSYM_CPPFLAGS} >$@.tmp && \ - mv -f $@.tmp $@ - -sconst.h: procoffsets.h -apic_asm.o head.o klib.o mpx.o: sconst.h - diff --git a/minix/lib/libmagicrt/Makefile b/minix/lib/libmagicrt/Makefile deleted file mode 100644 index 0151e54de..000000000 --- a/minix/lib/libmagicrt/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# Makefile for libmagicrt -# -# The magic runtime library is the runtime state transfer component for live -# update. It is not a regular library. First of all, it is only built when -# MKMAGIC is enabled, which also implies that we are building bitcode. -# Second, the produced file is a single bitcode object containing basically the -# concatenation of the individual bitcode objects produced from the source -# files. The final bitcode object is used to link against system services -# during the rest of the compilation process. It is installed only because -# this makes it easier to refer to it during the rest of the compilation -# process. However, both the library's generation and its installation cannot -# be done with regular bsd.lib.mk rules, which is why this Makefile is rather -# nonstandard. - -.include - -LIBNAME= libmagicrt.bcc - -SRCS= magic.c magic_analysis.c magic_asr.c magic_ds.c -SRCS+= magic_eval.c magic_eval_lib.c magic_mem.c magic_range.c -SRCS+= magic_selement.c magic_sentry.c magic_splay_tree.c -SRCS+= magic_st.c magic_util.c - -OBJS= ${SRCS:.c=.bc} - -CPPFLAGS+= -D__MINIX -D_MINIX_SYSTEM -D_SYSTEM -CPPFLAGS+= -I${.CURDIR}/include -CPPFLAGS+= -I${NETBSDSRCDIR}/minix/llvm/include # for magic_common.h -CPPFLAGS.magic_ds.c+= -I${NETBSDSRCDIR}/minix/servers # for ds/store.h - -# XXX: there is essential code in assert() statements, so force asserts on.. -CPPFLAGS+= -UNDEBUG - -# All functions and data must be assigned to nonstandard sections. However, -# the magic_st module has different rules from the rest. -SECTIONIFY= -sectionify-no-override \ - -sectionify-data-section-map=^_____magic_instr_.*/magic_instr_data,.*/magic_data \ - -sectionify-function-section-map=.*/magic_functions -SECTIONIFY.magic_st.c= \ - -sectionify-data-section-map=.*/magic_data_st \ - -sectionify-function-section-map=.*/magic_functions_st - -# HACK: keep the "temporary" .bc.o files generated as part of running the -# sectionify pass, so that we can trick clang into taking bitcode objects -# during the linking phase, because its driver refuses to take objects with -# the .bc suffix even when using the gold plugin. This works only because -# we are using sectionify on all objects here, and because bsd.lib.mk uses -# temporary names convenient for us. See also the comment in bsd.lib.mk. -SECTIONIFYMV=cp - -LDFLAGS+=-nostdlib -rdynamic -shared -Wl,--plugin \ - -Wl,${NETBSDSRCDIR}/minix/llvm/bin/LLVMgold.so \ - -Wl,-plugin-opt=-disable-fp-elim -Wl,-plugin-opt=emit-llvm - -realall: ${LIBNAME} - -${LIBNAME}: ${OBJS} - ${_MKTARGET_LINK} - ${LINK.c} -o ${.TARGET} ${OBJS:.bc=.bc.o} - -# The following block is a modified copy of similar blocks in bsd.lib.mk. -_LIB=${DESTDIR}/${LIBDIR}/${LIBNAME} -libinstall:: ${_LIB} -.PRECIOUS: ${_LIB} -.if ${MKUPDATE} == "no" -.if !defined(BUILD) && !make(all) && !make(${LIBNAME}) -${_LIB}! .MADE -.endif -${_LIB}! ${LIBNAME} __archiveinstall -.else -.if !defined(BUILD) && !make(all) && !make(${LIBNAME}) -${_LIB}: .MADE -.endif -${_LIB}: ${LIBNAME} __archiveinstall -.endif - -CLEANFILES+= ${LIBNAME} ${OBJS:.bc=.bc.o} - -.include diff --git a/minix/lib/libminc/Makefile b/minix/lib/libminc/Makefile deleted file mode 100644 index e9bab6a73..000000000 --- a/minix/lib/libminc/Makefile +++ /dev/null @@ -1,346 +0,0 @@ -# -# Minimal libc for servers and drivers. -# - -# LSC: TODO: Explaination of how this works -#.for f in \ -#${f} ${f:C/\.o/.bc/}: ${NETBSDSRCDIR}//${f:C/\.o/.S/} -#OBJS+= ${f} ${f:C/\.o/.bc/} -#CLEANFILES+= ${f} ${f:C/\.o/.bc/} -# -#.if ${USE_BITCODE:Uno} == "yes" -#OBJS+= ${f:C/\.o/.bc/} -#CLEANFILES+= ${f:C/\.o/.bc/} -#.endif # ${USE_BITCODE:Uno} == "yes" - -#.endfor - -.include - -LIB= minc - -MKPIC= no # Never used as a dynamic library - -LIBSADIR= ${NETBSDSRCDIR}/sys/lib/libsa -LIBSYSDIR= ${NETBSDSRCDIR}/minix/lib/libsys -LIBMINIXCDIR= ${NETBSDSRCDIR}/minix/lib/libc -LIBMINIXCARCHDIR= ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_CPU} -LIBCDIR= ${NETBSDSRCDIR}/lib/libc -LIBCARCHDIR= ${LIBCDIR}/arch/${MACHINE_CPU} -LIBCOMMONCDIR= ${NETBSDSRCDIR}/common/lib/libc -LIBCOMMONCARCHDIR= ${LIBCOMMONCDIR}/arch/${MACHINE_CPU} - -CPPFLAGS+= -I${LIBCDIR}/include -I${LIBCDIR} -CPPFLAGS+= -D_LIBMINC - -CFLAGS+= -fno-builtin - -# -# Customized versions of libc functions. -# -SRCS+= atoi.c fputs.c _snprintf.c strtol.c -CPPFLAGS._snprintf.c+= -I${LIBSADIR} - -CPPFLAGS.strtol.c+= -D_STANDALONE -CPPFLAGS.strtol.c+= -I${LIBCOMMONCDIR}/stdlib -CPPFLAGS.strtol.c+= -I${NETBSDSRCDIR}/sys - -######################################################################## -# -# Functions imported from libsa (StandAlone) -# -.for f in \ - errno.o printf.o strerror.o subr_prf.o -${f} ${f:C/\.o/.bc/}: ${LIBSADIR}/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBSADIR}/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -CPPFLAGS.fslib.c+= -I${NETBSDSRCDIR}/minix/fs - -# LSC: I would like not to have to copy te file, but I can't -# have libsa appear first in the .PATH, for a lot of files -# would be taken from there, which is not the intention ATM. -CPPFLAGS.strerror.c+= -I${LIBSADIR} - -# LSC: putchar and kputc have the same role / signature. -CPPFLAGS.subr_prf.c+= -Dputchar=kputc - -# Activate optional support, may be deactivated. -CPPFLAGS.subr_prf.c+= -DLIBSA_PRINTF_LONGLONG_SUPPORT -CPPFLAGS.subr_prf.c+= -DLIBSA_PRINTF_WIDTH_SUPPORT - -######################################################################## -# -# Imports from libsys -# -.for f in \ - kputc.o sys_diagctl.o -${f} ${f:C/\.o/.bc/}: ${LIBSYSDIR}/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBSYSDIR}/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -######################################################################## -# -# Shared libc with userspace (/common/lib/libc) -# - -.for f in \ - bswap64.o rb.o -${f} ${f:C/\.o/.bc/}: ${LIBCOMMONCDIR}/gen/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCDIR}/gen/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -CPPFLAGS.rb.c+= -D_LIBC - -.for f in \ - sha2.o -${f} ${f:C/\.o/.bc/}: ${LIBCOMMONCDIR}/hash/sha2/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCDIR}/hash/sha2/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -CPPFLAGS.sha2.c+= -I${NETBSDSRCDIR}/sys - -.for f in \ - ashrdi3.o divdi3.o lshrdi3.o moddi3.o \ - udivdi3.o umoddi3.o umodsi3.o udivsi3.o \ - udivmoddi4.o divsi3.o modsi3.o divmoddi4.o \ - divmodsi4.o udivmodsi4.o #qdivrem.o lshldi3.o -${f} ${f:C/\.o/.bc/}: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -COPTS+= -Wno-missing-prototypes \ - -Wno-old-style-definition \ - -Wno-strict-prototypes \ - -Wno-uninitialized \ - -Wno-cast-qual - - - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -.for f in \ - random.o strtoul.o -${f} ${f:C/\.o/.bc/}: ${LIBCOMMONCDIR}/stdlib/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCDIR}/stdlib/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -CPPFLAGS.strtoul.c+= -D_STANDALONE -CPPFLAGS.strtoul.c+= -I${NETBSDSRCDIR}/sys - -.for f in \ - strcasecmp.o strcspn.o strncasecmp.o strnlen.o strlcat.o -${f} ${f:C/\.o/.bc/}: ${LIBCOMMONCDIR}/string/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCDIR}/string/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -######################################################################## -# -# Functions imported directly from libc. -# - -.include "${.CURDIR}/arch/${MACHINE_ARCH}/Makefile.libc.inc" - -# This file is specifically generated -SRCS+= errlist.c - -errlist.c: ${LIBCDIR}/gen/errlist.awk \ - ${NETBSDSRCDIR}/sys/sys/errno.h - ${TOOL_CAT} ${NETBSDSRCDIR}/sys/sys/errno.h | ${TOOL_SED} 's/(_SIGN//' | ${TOOL_AWK} -f ${LIBCDIR}/gen/errlist.awk > ${.TARGET} -CLEANFILES+= errlist.c - -.for f in \ - _errno.o \ - getprogname.o setprogname.o execle.o sleep.o time.o \ - ctype_.o tolower_.o toupper_.o usleep.o waitpid.o sigsetops.o -${f} ${f:C/\.o/.bc/}: ${LIBCDIR}/gen/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/gen/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -CPPFLAGS.ctype_.c+= -I${LIBCDIR}/locale -CPPFLAGS.isctype.c+= -I${LIBCDIR}/locale -CPPFLAGS.tolower_.c+= -I${LIBCDIR}/locale -CPPFLAGS.toupper_.c+= -I${LIBCDIR}/locale - -.for f in \ - read_tsc_64.o fslib.o itoa.o -${f} ${f:C/\.o/.bc/}: ${LIBMINIXCDIR}/gen/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBMINIXCDIR}/gen/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -.for f in \ - initfini.o stack_protector.o -${f} ${f:C/\.o/.bc/}: ${LIBCDIR}/misc/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/misc/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -CPPFLAGS.stack_protector.c+= -Dxprintf=printf - -.for f in \ - regcomp.o regerror.o regexec.o regfree.o -${f} ${f:C/\.o/.bc/}: ${LIBCDIR}/regex/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/regex/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -.for f in \ - abort.o atexit.o _env.o exit.o getenv.o \ - ldiv.o malloc.o setenv.o \ - reallocarr.o _rand48.o lrand48.o srand48.o -${f} ${f:C/\.o/.bc/}: ${LIBCDIR}/stdlib/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/stdlib/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" - -# LSC FIXME: Try to get this out of the loop -CPPFLAGS.${i}+= -I${LIBCDIR}/stdlib -.endfor - -CPPFLAGS.malloc.c+= -D_LIBSYS -# Avoid magic instrumentation of the malloc data variables, since the heap is -# reconstructed upon state transfer. We do need to instrument the malloc -# functions, since we need to hook their mmap/munmap calls. -SECTIONIFY.malloc.c+= -sectionify-no-override \ - -sectionify-data-section-map=.*/magic_malloc_data - -.for f in \ - strdup.o -${f} ${f:C/\.o/.bc/}: ${LIBCDIR}/string/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/string/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -.for f in \ - access.o brk.o close.o environ.o execve.o fork.o fsync.o \ - getgid.o getpid.o geteuid.o getuid.o gettimeofday.o getvfsstat.o \ - init.o kernel_utils.o kill.o link.o loadname.o lseek.o _mcontext.o \ - minix_rs.o mknod.o mmap.o nanosleep.o open.o pread.o pwrite.o read.o \ - sbrk.o select.o setuid.o sigprocmask.o stack_utils.o \ - stat.o stime.o svrctl.o syscall.o __sysctl.o _ucontext.o umask.o \ - unlink.o wait4.o write.o -${f} ${f:C/\.o/.bc/}: ${LIBMINIXCDIR}/sys/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBMINIXCDIR}/sys/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -.for f in \ - brksize.o _do_kernel_call_intr.o ipc_minix_kerninfo.o _ipc.o ucontext.o -${f} ${f:C/\.o/.bc/}: ${LIBMINIXCARCHDIR}/sys/${f:C/\.o/.S/} -${f} ${f:C/\.o/.go/}: ${LIBMINIXCARCHDIR}/sys/${f:C/\.o/.S/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -.for f in \ - localtime.o -${f} ${f:C/\.o/.bc/}: ${LIBCDIR}/time/${f:C/\.o/.c/} -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/time/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} - -.if ${USE_BITCODE:Uno} == "yes" -OBJS+= ${f:C/\.o/.bc/} -CLEANFILES+= ${f:C/\.o/.bc/} -.endif # ${USE_BITCODE:Uno} == "yes" -.endfor - -ARCHSUBDIR=${MACHINE_CPU} -.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_CPU}/Makefile.inc" - -.include diff --git a/minix/lib/libminc/arch/earm/Makefile.libc.inc b/minix/lib/libminc/arch/earm/Makefile.libc.inc deleted file mode 100644 index 353fd325a..000000000 --- a/minix/lib/libminc/arch/earm/Makefile.libc.inc +++ /dev/null @@ -1,111 +0,0 @@ -######################################################################## -# -# Shared libc with userspace (/common/lib/libc) -# - -.for f in \ - memchr.o -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCDIR}/string/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.for f in \ - lshldi3.o -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCDIR}/quad/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.for f in \ - byte_swap_2.o byte_swap_4.o -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCARCHDIR}/gen/${f:C/\.o/.S/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.for f in \ - __aeabi_idiv0.o __aeabi_ldiv0.o -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCARCHDIR}/gen/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -CPPFLAGS.__aeabi_idiv0.c+= -D_STANDALONE -I${NETBSDSRCDIR}/sys -CPPFLAGS.__aeabi_ldiv0.c+= -D_STANDALONE -I${NETBSDSRCDIR}/sys - -#.for f in \ -# __aeabi_ldivmod.o __aeabi_uldivmod.o -#${f} ${f:C/\.o/.go/}: ${LIBCOMMONCARCHDIR}/quad/${f:C/\.o/.S/} -#OBJS+= ${f} -#CLEANFILES+= ${f} -#.endfor - -.for f in \ - memcmp.o memcpy.o memmove.o memset.o \ - strcat.o strchr.o strcmp.o strcpy.o strlcpy.o strlen.o strncpy.o \ - strncmp.o strrchr.o strcpy_arm.o -${f} ${f:C/\.o/.go/}: ${LIBCOMMONCARCHDIR}/string/${f:C/\.o/.S/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -CPPFLAGS.strcpy_arm.S+= -DSTRLCPY -D_LIBC - -######################################################################## -# -# Functions imported directly from libc. -# -.for f in \ - alloca.o -${f} ${f:C/\.o/.go/}: ${LIBCARCHDIR}/gen/${f:C/\.o/.S/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.for f in \ - __aeabi_dcmpeq.o __aeabi_fcmpeq.o \ - __aeabi_dcmpge.o __aeabi_fcmpge.o \ - __aeabi_dcmpgt.o __aeabi_fcmpgt.o \ - __aeabi_dcmple.o __aeabi_fcmple.o \ - __aeabi_dcmplt.o __aeabi_fcmplt.o \ - __aeabi_dcmpun.o __aeabi_fcmpun.o -CPPFLAGS.${f:C/\.o/.c/}+= -I${LIBCARCHDIR}/softfloat -I${LIBCDIR}/softfloat -CPPFLAGS.${f:C/\.o/.c/}+= -DSOFTFLOAT_FOR_GCC -${f} ${f:C/\.o/.go/}: ${LIBCARCHDIR}/softfloat/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.for f in \ - aeabi_uidivmod.o aeabi_ldivmod.o aeabi_uldivmod.o aeabi_idivmod.o -${f} ${f:C/\.o/.go/}: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/${f:C/\.o/.S/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.for f in \ - fpgetround.o fpsetround.o fpgetmask.o fpsetmask.o \ - fpgetsticky.o fpsetsticky.o -CPPFLAGS.${f:C/\.o/.c/}+= -I${LIBCARCHDIR}/softfloat -I${LIBCDIR}/softfloat -CPPFLAGS.${f:C/\.o/.c/}+= -DSOFTFLOAT_FOR_GCC -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/softfloat/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -SOFTFLOAT_BITS?=64 -.for f in \ - softfloat.o -CPPFLAGS.${f:C/\.o/.c/}+= -I${LIBCARCHDIR}/softfloat -I${LIBCDIR}/softfloat -CPPFLAGS.${f:C/\.o/.c/}+= -DSOFTFLOAT_FOR_GCC -${f} ${f:C/\.o/.go/}: ${LIBCDIR}/softfloat/bits${SOFTFLOAT_BITS}/${f:C/\.o/.c/} -OBJS+= ${f} -CLEANFILES+= ${f} -.endfor - -.if defined(HAVE_GCC) && ${HAVE_GCC} >= 45 -.if (${MACHINE_CPU} == "arm") -COPTS.softfloat.c+= -Wno-enum-compare -fno-tree-vrp -.endif -.endif diff --git a/minix/lib/libsockdriver/sockdriver.c b/minix/lib/libsockdriver/sockdriver.c deleted file mode 100644 index 46243c86b..000000000 --- a/minix/lib/libsockdriver/sockdriver.c +++ /dev/null @@ -1,1150 +0,0 @@ -/* The protocol family independent socket driver framework. */ -/* - * The table below lists all supported socket driver requests, along with - * information on whether the request handler may suspend the call for later - * processing, and which message layout is to be used for the request and reply - * messages for each call. - * - * Type May suspend Request layout Reply layout - * ---- ----------- -------------- ------------ - * SDEV_SOCKET no socket socket_reply - * SDEV_SOCKETPAIR no socket socket_reply - * SDEV_BIND yes addr reply - * SDEV_CONNECT yes addr reply - * SDEV_LISTEN no simple reply - * SDEV_ACCEPT yes addr accept_reply - * SDEV_SEND yes sendrecv reply - * SDEV_RECV yes sendrecv recv_reply - * SDEV_IOCTL yes ioctl reply - * SDEV_SETSOCKOPT no getset reply - * SDEV_GETSOCKOPT no getset reply - * SDEV_GETSOCKNAME no getset reply - * SDEV_GETPEERNAME no getset reply - * SDEV_SHUTDOWN no simple reply - * SDEV_CLOSE yes simple reply - * SDEV_CANCEL n/a simple - - * SDEV_SELECT yes (special) select select_reply - * - * The request message layouts are prefixed with "m_vfs_lsockdriver_". The - * reply message layouts are prefixed with "m_lsockdriver_vfs_", and use - * message types of the format SDEV_{,SOCKET_,ACCEPT_,RECV_}REPLY, matching the - * listed reply layout. One exception is SDEV_CANCEL, which itself has no - * reply at all. The other exception is SDEV_SELECT, which has two reply - * codes: SDEV_SELECT1_REPLY (for immediate replies) and SDEV_SELECT2_REPLY - * (for late replies), both using the select_reply reply layout. - */ - -#include -#include -#include - -static int running; - -/* - * Announce that we are up and running, after a fresh start or a restart. - */ -void -sockdriver_announce(void) -{ - static const char *sockdriver_prefix = "drv.sck."; - char key[DS_MAX_KEYLEN], label[DS_MAX_KEYLEN]; - int r; - - /* Publish a driver up event. */ - if ((r = ds_retrieve_label_name(label, sef_self())) != OK) - panic("sockdriver: unable to get own label: %d", r); - - snprintf(key, sizeof(key), "%s%s", sockdriver_prefix, label); - if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK) - panic("sockdriver: unable to publish driver up event: %d", r); -} - -/* - * Copy data from the caller into the local address space. Return OK or a - * negative error code. - */ -int -sockdriver_copyin(const struct sockdriver_data * __restrict data, size_t off, - void * __restrict ptr, size_t len) -{ - - assert(data != NULL); - assert(off + len <= data->_sd_len); - assert(data->_sd_endpt != SELF); - assert(GRANT_VALID(data->_sd_grant)); - - return sys_safecopyfrom(data->_sd_endpt, data->_sd_grant, off, - (vir_bytes)ptr, len); -} - -/* - * Copy data from the local address space to the caller. Return OK or a - * negative error code. - */ -int -sockdriver_copyout(const struct sockdriver_data * __restrict data, size_t off, - const void * __restrict ptr, size_t len) -{ - - assert(data != NULL); - assert(off + len <= data->_sd_len); - assert(data->_sd_endpt != SELF); - assert(GRANT_VALID(data->_sd_grant)); - - return sys_safecopyto(data->_sd_endpt, data->_sd_grant, off, - (vir_bytes)ptr, len); -} - -/* - * Copy data between the caller and the local address space, using a vector of - * at most SOCKDRIVER_IOV_MAX buffers. Return OK or an error code. - */ -static int -sockdriver_vcopy(const struct sockdriver_data * __restrict data, size_t off, - const iovec_t * __restrict iov, unsigned int iovcnt, int copyin) -{ - static struct vscp_vec vec[SOCKDRIVER_IOV_MAX]; - unsigned int i; - - assert(iov != NULL); - assert(iovcnt <= __arraycount(vec)); - - /* We allow zero-element vectors, because we are nice. */ - if (iovcnt == 0) - return OK; - - /* - * Do not use a vector copy operation for single-element copies, as - * this saves the kernel from having to copy in the vector itself. - */ - if (iovcnt == 1) { - if (copyin) - return sockdriver_copyin(data, off, - (void *)iov->iov_addr, iov->iov_size); - else - return sockdriver_copyout(data, off, - (const void *)iov->iov_addr, iov->iov_size); - } - - assert(data != NULL); - assert(data->_sd_endpt != SELF); - assert(GRANT_VALID(data->_sd_grant)); - - for (i = 0; i < iovcnt; i++, iov++) { - if (copyin) { - vec[i].v_from = data->_sd_endpt; - vec[i].v_to = SELF; - } else { - vec[i].v_from = SELF; - vec[i].v_to = data->_sd_endpt; - } - vec[i].v_gid = data->_sd_grant; - vec[i].v_offset = off; - vec[i].v_addr = iov->iov_addr; - vec[i].v_bytes = iov->iov_size; - - off += iov->iov_size; - } - - assert(off <= data->_sd_len); - - return sys_vsafecopy(vec, iovcnt); -} - -/* - * Copy data from the caller into the local address space, using a vector of - * buffers. Return OK or a negative error code. - */ -int -sockdriver_vcopyin(const struct sockdriver_data * __restrict data, size_t off, - const iovec_t * __restrict iov, unsigned int iovcnt) -{ - - return sockdriver_vcopy(data, off, iov, iovcnt, TRUE /*copyin*/); -} - -/* - * Copy data from the local address space to the caller, using a vector of - * buffers. Return OK or a negative error code. - */ -int -sockdriver_vcopyout(const struct sockdriver_data * __restrict data, size_t off, - const iovec_t * __restrict iov, unsigned int iovcnt) -{ - - return sockdriver_vcopy(data, off, iov, iovcnt, FALSE /*copyin*/); -} - -/* - * Copy data from the caller into the local address space, using socket option - * semantics: fail the call with EINVAL if the given 'optlen' is not equal to - * the given 'len'. Return OK or a negative error code. - */ -int -sockdriver_copyin_opt(const struct sockdriver_data * __restrict data, - void * __restrict ptr, size_t len, socklen_t optlen) -{ - - if (len != optlen) - return EINVAL; - else - return sockdriver_copyin(data, 0, ptr, len); -} - -/* - * Copy data from the local address space to the caller, using socket option - * semantics: limit the size of the copied-out data to the size pointed to by - * 'optlen', and return the possibly truncated size in 'optlen' on success. - * Return OK or a negative error code. - */ -int -sockdriver_copyout_opt(const struct sockdriver_data * __restrict data, - const void * __restrict ptr, size_t len, socklen_t * __restrict optlen) -{ - int r; - - if (len > *optlen) - len = *optlen; - - if ((r = sockdriver_copyout(data, 0, ptr, len)) == OK) - *optlen = len; - - return r; -} - -/* - * Compress a sockdriver_data structure to a smaller variant that stores only - * the fields that are not already stored redundantly in/as the given 'call' - * and 'len' parameters. The typical use case here this call suspension. In - * that case, the caller will already store 'call' and 'len' as is, and can - * save memory by storing a packed version of 'data' rather than that structure - * itself. Return OK on success, with 'pack' containing a compressed version - * of 'data'. Return EINVAL if the given parameters do not match; this would - * typically be a sign that the calling application messed up badly. - */ -int -sockdriver_pack_data(struct sockdriver_packed_data * pack, - const struct sockdriver_call * call, - const struct sockdriver_data * data, size_t len) -{ - - if (data->_sd_endpt != call->sc_endpt) - return EINVAL; - if (data->_sd_len != len) - return EINVAL; - - pack->_spd_grant = data->_sd_grant; - return OK; -} - -/* - * Decompress a previously packed sockdriver data structure into a full - * sockdriver_data structure, with the help of the given 'call' and 'len' - * parameters. Return the unpacked version of 'pack' in 'data'. This function - * always succeeds. - */ -void -sockdriver_unpack_data(struct sockdriver_data * data, - const struct sockdriver_call * call, - const struct sockdriver_packed_data * pack, size_t len) -{ - - data->_sd_endpt = call->sc_endpt; - data->_sd_grant = pack->_spd_grant; - data->_sd_len = len; -} - -/* - * Send a reply to a request. - */ -static void -send_reply(endpoint_t endpt, int type, message * m_ptr) -{ - int r; - - m_ptr->m_type = type; - - if ((r = asynsend(endpt, m_ptr)) != OK) - printf("sockdriver: sending reply to %d failed (%d)\n", - endpt, r); -} - -/* - * Send a reply which takes only a result code and no additional reply fields. - */ -static void -send_generic_reply(endpoint_t endpt, sockreq_t req, int reply) -{ - message m; - - assert(reply != SUSPEND && reply != EDONTREPLY); - - memset(&m, 0, sizeof(m)); - m.m_lsockdriver_vfs_reply.req_id = req; - m.m_lsockdriver_vfs_reply.status = reply; - - send_reply(endpt, SDEV_REPLY, &m); -} - -/* - * Send a reply to an earlier suspended request which takes only a result code - * and no additional reply fields. - */ -void -sockdriver_reply_generic(const struct sockdriver_call * call, int reply) -{ - - send_generic_reply(call->sc_endpt, call->sc_req, reply); -} - -/* - * Send a reply to a socket or a socketpair request. Since these calls may not - * be suspended, this function is used internally only. - */ -static void -send_socket_reply(endpoint_t endpt, sockreq_t req, sockid_t reply, - sockid_t reply2) -{ - message m; - - assert(reply != SUSPEND && reply != EDONTREPLY); - - memset(&m, 0, sizeof(m)); - m.m_lsockdriver_vfs_socket_reply.req_id = req; - m.m_lsockdriver_vfs_socket_reply.sock_id = reply; - m.m_lsockdriver_vfs_socket_reply.sock_id2 = reply2; - - send_reply(endpt, SDEV_SOCKET_REPLY, &m); -} - -/* - * Send a reply to an earlier suspended accept request. The given reply is - * either a socket identifier (>= 0) or an error code (< 0). On success, an - * address must be given as 'addr', and its nonzero length must be given as - * 'addr_len'. - */ -void -sockdriver_reply_accept(const struct sockdriver_call * __restrict call, - sockid_t reply, struct sockaddr * __restrict addr, socklen_t addr_len) -{ - sockid_t id; - message m; - - assert(reply != SUSPEND && reply != EDONTREPLY); - - /* - * If the accept was successful, copy out the address, if requested. - * If the copy fails, send both a valid socket ID and an error to VFS. - * VFS will then close the newly created socket immediately, and return - * the error to the caller. - * - * While not particularly nice, the general behavior of closing the - * socket after accepting it seems to be common among other OSes for - * address copy errors. Most importantly, it frees the socket driver - * from having to deal with address copy errors itself. - * - * Letting VFS close the socket is also not all that great. However, - * it is the lesser evil compared to the two main alternatives: 1) - * immediately calling sdr_close() from here, which would seriously - * complicate writing socket drivers due to sockets disappearing from - * under it, so to speak, and 2) queuing a forged incoming SDEV_CLOSE - * request, for which we do not have the necessary infrastructure. - * Additionally, VFS may close the newly accepted socket when out of - * other required resources anyway, so logically this fits in well. - * The only real price to pay is a slightly uglier message protocol. - * - * Copying out the address *length* is not our responsibility at all; - * if VFS chooses to do this itself (as opposed to letting libc do it), - * it too will have to close the socket on failure, using a separate - * close call. This is always multithreading-safe because userland can - * not access the accepted socket yet anyway. - */ - if (reply >= 0) { - id = reply; - reply = OK; - } else - id = -1; - - if (reply == OK && GRANT_VALID(call->_sc_grant)) { - if (addr == NULL || addr_len == 0) - panic("libsockdriver: success but no address given"); - - if (addr_len > call->_sc_len) - addr_len = call->_sc_len; /* truncate addr and len */ - - if (addr_len > 0) { - reply = sys_safecopyto(call->sc_endpt, call->_sc_grant, - 0, (vir_bytes)addr, addr_len); - - /* Intentionally leave 'id' set on failure here. */ - } - } else - addr_len = 0; /* not needed, but cleaner */ - - memset(&m, 0, sizeof(m)); - m.m_lsockdriver_vfs_accept_reply.req_id = call->sc_req; - m.m_lsockdriver_vfs_accept_reply.sock_id = id; - m.m_lsockdriver_vfs_accept_reply.status = reply; - m.m_lsockdriver_vfs_accept_reply.len = addr_len; - - send_reply(call->sc_endpt, SDEV_ACCEPT_REPLY, &m); -} - -/* - * Send a reply to an earlier suspended receive call. The given reply code is - * the number of regular data bytes received (>= 0) or an error code (< 0). - * On success, for connectionless sockets, 'addr' must point to the source - * address and 'addr_len' must contain the address length; for connection- - * oriented sockets, 'addr_len' must be zero, in which case 'addr' is ignored. - */ -void -sockdriver_reply_recv(const struct sockdriver_call * __restrict call, - int reply, socklen_t ctl_len, struct sockaddr * __restrict addr, - socklen_t addr_len, int flags) -{ - message m; - int r; - - assert(reply != SUSPEND && reply != EDONTREPLY); - - /* - * If applicable, copy out the address. If this fails, the result is - * loss of the data received; in the case of AF_UNIX, this may include - * references to file descriptors already created in the receiving - * process. At least Linux and NetBSD behave this way as well, which - * is not an excuse to be lazy, but we need to change just about - * everything for the worse (including having additional grants just - * for storing lengths) in order to fully solve this corner case. - * - * TODO: a reasonable compromise might be to add a callback routine for - * closing file descriptors in any already-written control data. This - * would solve the worst aspect of the data loss, not the loss itself. - */ - if (reply >= 0 && addr_len > 0 && GRANT_VALID(call->_sc_grant)) { - if (addr == NULL) - panic("libsockdriver: success but no address given"); - - if (addr_len > call->_sc_len) - addr_len = call->_sc_len; /* truncate addr and len */ - - if (addr_len > 0 && (r = sys_safecopyto(call->sc_endpt, - call->_sc_grant, 0, (vir_bytes)addr, addr_len)) != OK) - reply = r; - } else - addr_len = 0; - - memset(&m, 0, sizeof(m)); - m.m_lsockdriver_vfs_recv_reply.req_id = call->sc_req; - m.m_lsockdriver_vfs_recv_reply.status = reply; - m.m_lsockdriver_vfs_recv_reply.ctl_len = ctl_len; - m.m_lsockdriver_vfs_recv_reply.addr_len = addr_len; - m.m_lsockdriver_vfs_recv_reply.flags = flags; - - send_reply(call->sc_endpt, SDEV_RECV_REPLY, &m); -} - -/* - * Send a reply to a select request. - */ -static void -send_select_reply(const struct sockdriver_select * sel, int type, sockid_t id, - int ops) -{ - message m; - - assert(ops != SUSPEND && ops != EDONTREPLY); - - memset(&m, 0, sizeof(m)); - m.m_lsockdriver_vfs_select_reply.sock_id = id; - m.m_lsockdriver_vfs_select_reply.status = ops; - - send_reply(sel->ss_endpt, type, &m); -} - -/* - * Send a reply to an earlier select call that requested notifications. - */ -void -sockdriver_reply_select(const struct sockdriver_select * sel, sockid_t id, - int ops) -{ - - send_select_reply(sel, SDEV_SELECT2_REPLY, id, ops); -} - -/* - * Create a new socket. This call may not be suspended. - */ -static void -do_socket(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - sockid_t r; - - if (sdp->sdr_socket != NULL) - r = sdp->sdr_socket(m_ptr->m_vfs_lsockdriver_socket.domain, - m_ptr->m_vfs_lsockdriver_socket.type, - m_ptr->m_vfs_lsockdriver_socket.protocol, - m_ptr->m_vfs_lsockdriver_socket.user_endpt); - else - r = EOPNOTSUPP; - - send_socket_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_socket.req_id, r, -1); -} - -/* - * Create a pair of connected sockets. Relevant for UNIX domain sockets only. - * This call may not be suspended. - */ -static void -do_socketpair(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - sockid_t sockid[2]; - int r; - - if (sdp->sdr_socketpair != NULL) - r = sdp->sdr_socketpair(m_ptr->m_vfs_lsockdriver_socket.domain, - m_ptr->m_vfs_lsockdriver_socket.type, - m_ptr->m_vfs_lsockdriver_socket.protocol, - m_ptr->m_vfs_lsockdriver_socket.user_endpt, sockid); - else - r = EOPNOTSUPP; - - if (r != OK) { - sockid[0] = r; - sockid[1] = -1; - } - - send_socket_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_socket.req_id, sockid[0], sockid[1]); -} - -/* - * Bind a socket to a local address, or connect a socket to a remote address. - * In both cases, this call may be suspended by the socket driver, in which - * case sockdriver_reply_generic() must be used to reply later. - * - * For bind(2), POSIX is not entirely consistent regarding call suspension: the - * bind(2) call may return EINPROGRESS for nonblocking sockets, but this also - * suggests that blocking bind(2) calls may be interrupted by signals (as on - * MINIX3 they can be), yet EINTR is not defined as a valid return code for it. - */ -static void -do_bind_connect(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - int (*proc)(sockid_t, const struct sockaddr * __restrict, socklen_t, - endpoint_t, const struct sockdriver_call * __restrict); - struct sockdriver_call call; - char buf[SOCKADDR_MAX]; - sockid_t id; - cp_grant_id_t grant; - socklen_t len; - endpoint_t user_endpt; - int r, sflags; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_addr.req_id; - - id = m_ptr->m_vfs_lsockdriver_addr.sock_id; - grant = m_ptr->m_vfs_lsockdriver_addr.grant; - len = m_ptr->m_vfs_lsockdriver_addr.len; - user_endpt = m_ptr->m_vfs_lsockdriver_addr.user_endpt; - sflags = m_ptr->m_vfs_lsockdriver_addr.sflags; - - switch (m_ptr->m_type) { - case SDEV_BIND: proc = sdp->sdr_bind; break; - case SDEV_CONNECT: proc = sdp->sdr_connect; break; - default: panic("expected bind or connect"); - } - - r = OK; - if (!GRANT_VALID(grant) || len == 0 || len > sizeof(buf)) - r = EINVAL; - else - r = sys_safecopyfrom(m_ptr->m_source, grant, 0, (vir_bytes)buf, - len); - - if (r == OK) { - if (proc != NULL) - r = proc(id, (struct sockaddr *)buf, len, user_endpt, - (sflags & SDEV_NONBLOCK) ? NULL : &call); - else - r = EOPNOTSUPP; - } - - assert(!(sflags & SDEV_NONBLOCK) || (r != SUSPEND && r != EDONTREPLY)); - - if (r != SUSPEND && r != EDONTREPLY) - sockdriver_reply_generic(&call, r); -} - -/* - * Put a socket in listening mode. This call may not be suspended. - */ -static void -do_listen(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - int r; - - if (sdp->sdr_listen != NULL) - r = sdp->sdr_listen(m_ptr->m_vfs_lsockdriver_simple.sock_id, - m_ptr->m_vfs_lsockdriver_simple.param /*backlog*/); - else - r = EOPNOTSUPP; - - send_generic_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_simple.req_id, r); -} - -/* - * Accept a connection on a listening socket, creating a new socket. - * This call may be suspended by the socket driver, in which case - * sockdriver_reply_accept() must be used to reply later. - */ -static void -do_accept(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_call call; - char buf[SOCKADDR_MAX]; - struct sockaddr *addr; - socklen_t len; - endpoint_t user_endpt; - int sflags; - sockid_t r; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_addr.req_id; - call._sc_grant = m_ptr->m_vfs_lsockdriver_addr.grant; - call._sc_len = m_ptr->m_vfs_lsockdriver_addr.len; - - addr = (struct sockaddr *)buf; - len = 0; - user_endpt = m_ptr->m_vfs_lsockdriver_addr.user_endpt; - sflags = m_ptr->m_vfs_lsockdriver_addr.sflags; - - if (sdp->sdr_accept != NULL) - r = sdp->sdr_accept(m_ptr->m_vfs_lsockdriver_addr.sock_id, - addr, &len, user_endpt, - (sflags & SDEV_NONBLOCK) ? NULL : &call); - else - r = EOPNOTSUPP; - - assert(!(sflags & SDEV_NONBLOCK) || (r != SUSPEND && r != EDONTREPLY)); - - if (r != SUSPEND && r != EDONTREPLY) - sockdriver_reply_accept(&call, r, addr, len); -} - -/* - * Send regular and/or control data. This call may be suspended by the socket - * driver, in which case sockdriver_reply_generic() must be used to reply - * later. - */ -static void -do_send(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_call call; - struct sockdriver_data data, ctl_data; - char buf[SOCKADDR_MAX]; - struct sockaddr *addr; - cp_grant_id_t addr_grant; - socklen_t addr_len; - endpoint_t user_endpt; - sockid_t id; - int r, flags; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_sendrecv.req_id; - - data._sd_grant = m_ptr->m_vfs_lsockdriver_sendrecv.data_grant; - data._sd_endpt = m_ptr->m_source; - data._sd_len = m_ptr->m_vfs_lsockdriver_sendrecv.data_len; - - /* The returned size must fit in an 'int'; truncate accordingly. */ - if (data._sd_len > INT_MAX) - data._sd_len = INT_MAX; - - ctl_data._sd_endpt = m_ptr->m_source; - ctl_data._sd_grant = m_ptr->m_vfs_lsockdriver_sendrecv.ctl_grant; - ctl_data._sd_len = m_ptr->m_vfs_lsockdriver_sendrecv.ctl_len; - - id = m_ptr->m_vfs_lsockdriver_sendrecv.sock_id; - addr_grant = m_ptr->m_vfs_lsockdriver_sendrecv.addr_grant; - addr_len = m_ptr->m_vfs_lsockdriver_sendrecv.addr_len; - user_endpt = m_ptr->m_vfs_lsockdriver_sendrecv.user_endpt; - flags = m_ptr->m_vfs_lsockdriver_sendrecv.flags; - - r = OK; - if (GRANT_VALID(addr_grant)) { - if (addr_len == 0 || addr_len > sizeof(buf)) - r = EINVAL; - else - r = sys_safecopyfrom(m_ptr->m_source, addr_grant, 0, - (vir_bytes)buf, addr_len); - addr = (struct sockaddr *)buf; - } else { - addr = NULL; - addr_len = 0; - } - - if (r == OK) { - if (sdp->sdr_send != NULL) - r = sdp->sdr_send(id, &data, data._sd_len, &ctl_data, - ctl_data._sd_len, addr, addr_len, user_endpt, - flags, (flags & MSG_DONTWAIT) ? NULL : &call); - else - r = EOPNOTSUPP; - } - - assert(!(flags & MSG_DONTWAIT) || (r != SUSPEND && r != EDONTREPLY)); - - if (r != SUSPEND && r != EDONTREPLY) - sockdriver_reply_generic(&call, r); -} - -/* - * Receive regular and/or control data. This call may be suspended by the - * socket driver, in which case sockdriver_reply_recv() must be used to reply - * later. - */ -static void -do_recv(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_call call; - struct sockdriver_data data, ctl_data; - char buf[SOCKADDR_MAX]; - struct sockaddr *addr; - sockid_t id; - socklen_t ctl_len, addr_len; - endpoint_t user_endpt; - int r, flags; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_sendrecv.req_id; - call._sc_grant = m_ptr->m_vfs_lsockdriver_sendrecv.addr_grant; - call._sc_len = m_ptr->m_vfs_lsockdriver_sendrecv.addr_len; - - data._sd_endpt = m_ptr->m_source; - data._sd_grant = m_ptr->m_vfs_lsockdriver_sendrecv.data_grant; - data._sd_len = m_ptr->m_vfs_lsockdriver_sendrecv.data_len; - - /* The returned size must fit in an 'int'; truncate accordingly. */ - if (data._sd_len > INT_MAX) - data._sd_len = INT_MAX; - - ctl_data._sd_endpt = m_ptr->m_source; - ctl_data._sd_grant = m_ptr->m_vfs_lsockdriver_sendrecv.ctl_grant; - ctl_data._sd_len = m_ptr->m_vfs_lsockdriver_sendrecv.ctl_len; - - id = m_ptr->m_vfs_lsockdriver_sendrecv.sock_id; - ctl_len = ctl_data._sd_len; - addr = (struct sockaddr *)buf; - addr_len = 0; /* the default: no source address */ - user_endpt = m_ptr->m_vfs_lsockdriver_sendrecv.user_endpt; - flags = m_ptr->m_vfs_lsockdriver_sendrecv.flags; - - if (sdp->sdr_recv != NULL) - r = sdp->sdr_recv(id, &data, data._sd_len, &ctl_data, &ctl_len, - addr, &addr_len, user_endpt, &flags, - (flags & MSG_DONTWAIT) ? NULL : &call); - else - r = EOPNOTSUPP; - - assert(!(flags & MSG_DONTWAIT) || (r != SUSPEND && r != EDONTREPLY)); - - if (r != SUSPEND && r != EDONTREPLY) - sockdriver_reply_recv(&call, r, ctl_len, addr, addr_len, - flags); -} - -/* - * Process an I/O control call. This call may be suspended by the socket - * driver, in which case sockdriver_reply_generic() must be used to reply - * later. - */ -static void -do_ioctl(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_call call; - struct sockdriver_data data; - sockid_t id; - unsigned long request; - endpoint_t user_endpt; - int r, sflags; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_ioctl.req_id; - - id = m_ptr->m_vfs_lsockdriver_ioctl.sock_id; - request = m_ptr->m_vfs_lsockdriver_ioctl.request; - user_endpt = m_ptr->m_vfs_lsockdriver_ioctl.user_endpt; - sflags = m_ptr->m_vfs_lsockdriver_ioctl.sflags; - - data._sd_endpt = m_ptr->m_source; - data._sd_grant = m_ptr->m_vfs_lsockdriver_ioctl.grant; - if (_MINIX_IOCTL_BIG(request)) - data._sd_len = _MINIX_IOCTL_SIZE_BIG(request); - else - data._sd_len = _MINIX_IOCTL_SIZE(request); - - if (sdp->sdr_ioctl != NULL) - r = sdp->sdr_ioctl(id, request, &data, user_endpt, - (sflags & SDEV_NONBLOCK) ? NULL : &call); - else - r = EOPNOTSUPP; - - assert(!(sflags & SDEV_NONBLOCK) || (r != SUSPEND && r != EDONTREPLY)); - - if (r != SUSPEND && r != EDONTREPLY) - sockdriver_reply_generic(&call, r); -} - -/* - * Set socket options. This call may not be suspended. - */ -static void -do_setsockopt(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_data data; - int r; - - data._sd_endpt = m_ptr->m_source; - data._sd_grant = m_ptr->m_vfs_lsockdriver_getset.grant; - data._sd_len = m_ptr->m_vfs_lsockdriver_getset.len; - - if (sdp->sdr_setsockopt != NULL) - r = sdp->sdr_setsockopt( - m_ptr->m_vfs_lsockdriver_getset.sock_id, - m_ptr->m_vfs_lsockdriver_getset.level, - m_ptr->m_vfs_lsockdriver_getset.name, &data, data._sd_len); - else - r = EOPNOTSUPP; - - send_generic_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_getset.req_id, r); -} - -/* - * Retrieve socket options. This call may not be suspended. - */ -static void -do_getsockopt(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_data data; - socklen_t len; - int r; - - data._sd_endpt = m_ptr->m_source; - data._sd_grant = m_ptr->m_vfs_lsockdriver_getset.grant; - data._sd_len = m_ptr->m_vfs_lsockdriver_getset.len; - - len = data._sd_len; - - if (sdp->sdr_setsockopt != NULL) - r = sdp->sdr_getsockopt( - m_ptr->m_vfs_lsockdriver_getset.sock_id, - m_ptr->m_vfs_lsockdriver_getset.level, - m_ptr->m_vfs_lsockdriver_getset.name, &data, &len); - else - r = EOPNOTSUPP; - - /* - * For these requests, the main reply code is used to return the - * resulting data length on success. The length will never large - * enough to overflow, and we save on API calls and messages this way. - */ - if (r == OK) { - assert(len <= INT_MAX); - - r = (int)len; - } else if (r > 0) - panic("libsockdriver: invalid reply"); - - send_generic_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_getset.req_id, r); -} - -/* - * Get local or remote address. This call may not be suspended. - */ -static void -do_getname(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - int (*proc)(sockid_t, struct sockaddr * __restrict, - socklen_t * __restrict); - char buf[SOCKADDR_MAX]; - socklen_t addr_len, len; - int r; - - switch (m_ptr->m_type) { - case SDEV_GETSOCKNAME: proc = sdp->sdr_getsockname; break; - case SDEV_GETPEERNAME: proc = sdp->sdr_getpeername; break; - default: panic("expected getsockname or getpeername"); - } - - /* The 'name' and 'level' message fields are unused for these calls. */ - - addr_len = m_ptr->m_vfs_lsockdriver_getset.len; - len = 0; - - if (proc != NULL) - r = proc(m_ptr->m_vfs_lsockdriver_getset.sock_id, - (struct sockaddr *)buf, &len); - else - r = EOPNOTSUPP; - - if (r == OK) { - if (len == 0) - panic("libsockdriver: success but no address given"); - - if (addr_len > len) - addr_len = len; - - /* As above, use the reply code for the resulting length. */ - if (addr_len > 0 && (r = sys_safecopyto(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_getset.grant, 0, (vir_bytes)buf, - addr_len)) == OK) { - assert(addr_len <= INT_MAX); - - /* - * The Open Group wording has changed recently, now - * suggesting that when truncating the "stored address" - * the resulting length should be truncated as well. - */ - r = addr_len; - } - } else if (r > 0) - panic("libsockdriver: invalid reply"); - - send_generic_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_getset.req_id, r); -} - -/* - * Shut down socket send and receive operations. This call may not be - * suspended. - */ -static void -do_shutdown(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - int r; - - if (sdp->sdr_shutdown != NULL) - r = sdp->sdr_shutdown( - m_ptr->m_vfs_lsockdriver_simple.sock_id, - m_ptr->m_vfs_lsockdriver_simple.param /*how*/); - else - r = EOPNOTSUPP; - - send_generic_reply(m_ptr->m_source, - m_ptr->m_vfs_lsockdriver_simple.req_id, r); -} - -/* - * Close a socket. This call may be suspended by the socket driver, in which - * case sockdriver_reply_generic() must be used to reply later. Note that VFS - * currently does not support blocking close operations, and will mark all - * close operations as nonblocking. This will be changed in the future. - */ -static void -do_close(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_call call; - int r, sflags; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_simple.req_id; - - sflags = m_ptr->m_vfs_lsockdriver_simple.param; - - if (sdp->sdr_close != NULL) - r = sdp->sdr_close(m_ptr->m_vfs_lsockdriver_simple.sock_id, - (sflags & SDEV_NONBLOCK) ? NULL : &call); - else - r = OK; /* exception: this must never fail */ - - assert(!(sflags & SDEV_NONBLOCK) || (r != SUSPEND && r != EDONTREPLY)); - - if (r != SUSPEND && r != EDONTREPLY) - sockdriver_reply_generic(&call, r); -} - -/* - * Cancel a previous operation which may currently be suspended. The cancel - * operation itself does not have a reply. Instead, if the provided operation - * was found to be currently suspended, that operation must be aborted and a - * reply (typically EINTR) must be sent for it. If no matching operation was - * found, no reply must be sent at all. - */ -static void -do_cancel(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_call call; - - call.sc_endpt = m_ptr->m_source; - call.sc_req = m_ptr->m_vfs_lsockdriver_simple.req_id; - - /* The 'param' message field is unused by this request. */ - - if (sdp->sdr_cancel != NULL) - sdp->sdr_cancel(m_ptr->m_vfs_lsockdriver_simple.sock_id, - &call); -} - -/* - * Process a select request. Select requests have their own rules with respect - * to suspension and later notification. The basic idea is: an immediate reply - * is always sent with the subset of requested operations that are ready. If - * SDEV_NOTIFY is given, the remaining operations are to be combined with any - * previous operations requested (with SDEV_NOTIFY) by the calling endpoint. - * If any of the pending previous operations become ready, a late reply is sent - * and only those ready operations are forgotten, leaving any other non-ready - * operations for other late replies. - */ -static void -do_select(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr) -{ - struct sockdriver_select sel; - sockid_t id; - int r, ops; - - sel.ss_endpt = m_ptr->m_source; - id = m_ptr->m_vfs_lsockdriver_select.sock_id; - ops = m_ptr->m_vfs_lsockdriver_select.ops; - - if (sdp->sdr_select != NULL) - r = sdp->sdr_select(id, ops, - (ops & SDEV_NOTIFY) ? &sel : NULL); - else - r = EOPNOTSUPP; - - send_select_reply(&sel, SDEV_SELECT1_REPLY, id, r); -} - -/* - * Return TRUE if the given endpoint may initiate socket requests. - */ -static int -may_request(endpoint_t endpt) -{ - - /* - * For now, we allow only VFS to initiate socket calls. In the future, - * we may allow networked file systems to call into the network stack - * directly. The sockdriver API has already been designed to allow for - * that, but this check will then need to change. Ideally it would be - * using some sort of ACL system. For now, this check prevents that - * network drivers themselves create and use sockets. - */ - return (endpt == VFS_PROC_NR); -} - -/* - * Process an incoming message, and (typically) send a reply. - */ -void -sockdriver_process(const struct sockdriver * __restrict sdp, - const message * __restrict m_ptr, int ipc_status) -{ - - /* Handle notifications separately. */ - if (is_ipc_notify(ipc_status)) { - switch (m_ptr->m_source) { - case CLOCK: - if (sdp->sdr_alarm != NULL) - sdp->sdr_alarm(m_ptr->m_notify.timestamp); - break; - default: - if (sdp->sdr_other != NULL) - sdp->sdr_other(m_ptr, ipc_status); - } - - return; /* do not send a reply */ - } - - /* Is this a socket request from an acceptable party? */ - if (!IS_SDEV_RQ(m_ptr->m_type) || !may_request(m_ptr->m_source)) { - if (sdp->sdr_other != NULL) - sdp->sdr_other(m_ptr, ipc_status); - - return; /* do not send a reply */ - } - - /* - * Process the request. If the request is not recognized, we cannot - * send a reply either, because we do not know the reply message - * format. Passing the request message to the sdr_other hook serves no - * practical purpose either: if the request is legitimate, this library - * should know about it. - */ - switch (m_ptr->m_type) { - case SDEV_SOCKET: do_socket(sdp, m_ptr); break; - case SDEV_SOCKETPAIR: do_socketpair(sdp, m_ptr); break; - case SDEV_BIND: do_bind_connect(sdp, m_ptr); break; - case SDEV_CONNECT: do_bind_connect(sdp, m_ptr); break; - case SDEV_LISTEN: do_listen(sdp, m_ptr); break; - case SDEV_ACCEPT: do_accept(sdp, m_ptr); break; - case SDEV_SEND: do_send(sdp, m_ptr); break; - case SDEV_RECV: do_recv(sdp, m_ptr); break; - case SDEV_IOCTL: do_ioctl(sdp, m_ptr); break; - case SDEV_SETSOCKOPT: do_setsockopt(sdp, m_ptr); break; - case SDEV_GETSOCKOPT: do_getsockopt(sdp, m_ptr); break; - case SDEV_GETSOCKNAME: do_getname(sdp, m_ptr); break; - case SDEV_GETPEERNAME: do_getname(sdp, m_ptr); break; - case SDEV_SHUTDOWN: do_shutdown(sdp, m_ptr); break; - case SDEV_CLOSE: do_close(sdp, m_ptr); break; - case SDEV_CANCEL: do_cancel(sdp, m_ptr); break; - case SDEV_SELECT: do_select(sdp, m_ptr); break; - } -} - -/* - * Break out of the main loop after finishing the current request. - */ -void -sockdriver_terminate(void) -{ - - running = FALSE; - - sef_cancel(); -} - -/* - * Main program of any socket driver. - */ -void -sockdriver_task(const struct sockdriver * sdp) -{ - message m; - int r, ipc_status; - - /* The main message loop. */ - running = TRUE; - - while (running) { - if ((r = sef_receive_status(ANY, &m, &ipc_status)) != OK) { - if (r == EINTR) - continue; /* sef_cancel() was called */ - - panic("sockdriver: sef_receive_status failed: %d", r); - } - - sockdriver_process(sdp, &m, ipc_status); - } -} diff --git a/minix/lib/libsockevent/Makefile b/minix/lib/libsockevent/Makefile deleted file mode 100644 index 713cd13ca..000000000 --- a/minix/lib/libsockevent/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile for libsockevent - -CPPFLAGS+= -D_MINIX_SYSTEM -I${NETBSDSRCDIR}/minix/lib/libcharevent - -LIB= sockevent - -SRCS= sockevent.c sockevent_proc.c - -.include diff --git a/minix/servers/ipc/inc.h b/minix/servers/ipc/inc.h deleted file mode 100644 index 01c1d710a..000000000 --- a/minix/servers/ipc/inc.h +++ /dev/null @@ -1,66 +0,0 @@ -#define _SYSTEM 1 /* get OK and negative error codes */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * On NetBSD, these macros are only defined when _KERNEL is set. However, - * since ipcs(1) uses IXSEQ_TO_IPCID, NetBSD cannot change these macros without - * breaking the userland API. Thus, having a copy of them here is not risky. - */ -#define IPCID_TO_IX(id) ((id) & 0xffff) -#define IPCID_TO_SEQ(id) (((id) >> 16) & 0xffff) - -/* main.c */ -void update_sem_sub(int); - -/* shm.c */ -int do_shmget(message *); -int do_shmat(message *); -int do_shmdt(message *); -int do_shmctl(message *); -int get_shm_mib_info(struct rmib_oldp *); -int is_shm_nil(void); -void update_refcount_and_destroy(void); - -/* sem.c */ -int do_semget(message *); -int do_semctl(message *); -int do_semop(message *); -int get_sem_mib_info(struct rmib_oldp *); -int is_sem_nil(void); -void sem_process_event(endpoint_t, int); - -/* utility.c */ -int check_perm(struct ipc_perm *, endpoint_t, int); -void prepare_mib_perm(struct ipc_perm_sysctl *, const struct ipc_perm *); diff --git a/minix/servers/ipc/main.c b/minix/servers/ipc/main.c deleted file mode 100644 index 02c62c427..000000000 --- a/minix/servers/ipc/main.c +++ /dev/null @@ -1,284 +0,0 @@ -#include "inc.h" - -#define SEM_EVENTS 0x01 /* semaphore code wants process events */ -static unsigned int event_mask = 0; - -static int verbose = 0; - -/* - * The call table for this service. - */ -#define CALL(n) [((n) - IPC_BASE)] -static int (* const call_vec[])(message *) = { - CALL(IPC_SHMGET) = do_shmget, - CALL(IPC_SHMAT) = do_shmat, - CALL(IPC_SHMDT) = do_shmdt, - CALL(IPC_SHMCTL) = do_shmctl, - CALL(IPC_SEMGET) = do_semget, - CALL(IPC_SEMCTL) = do_semctl, - CALL(IPC_SEMOP) = do_semop, -}; - -/* - * Remote MIB implementation of CTL_KERN KERN_SYSVIPC KERN_SYSVIPC_INFO. This - * function handles all queries on the "kern.ipc.sysvipc_info" sysctl(2) node. - */ -static ssize_t -kern_ipc_info(struct rmib_call * call, struct rmib_node * node __unused, - struct rmib_oldp * oldp, struct rmib_newp * newp __unused) -{ - - if (call->call_namelen != 1) - return EINVAL; - - /* - * Let each IPC submodule provide information through it own function. - * An important security note: unlike IPC_STAT and the like, access to - * the sysvipc_info node does not require root privileges. That is: on - * NetBSD, any user can get a full listing of all IPC objects in the - * system. We therefore do not perform any security check here. - */ - switch (call->call_name[0]) { - case KERN_SYSVIPC_SEM_INFO: - return get_sem_mib_info(oldp); - - case KERN_SYSVIPC_SHM_INFO: - return get_shm_mib_info(oldp); - - default: - return EOPNOTSUPP; - } -} - -/* The CTL_KERN KERN_SYSVIPC subtree. */ -static struct rmib_node kern_ipc_table[] = { -/* 1*/ [KERN_SYSVIPC_INFO] = RMIB_FUNC(RMIB_RO | CTLTYPE_NODE, 0, - kern_ipc_info, "sysvipc_info", - "System V style IPC information"), -/* 2*/ [KERN_SYSVIPC_MSG] = RMIB_INT(RMIB_RO, 0, "sysvmsg", "System V " - "style message support available"), -/* 3*/ [KERN_SYSVIPC_SEM] = RMIB_INT(RMIB_RO, 1, "sysvsem", "System V " - "style semaphore support available"), -/* 4*/ [KERN_SYSVIPC_SHM] = RMIB_INT(RMIB_RO, 1, "sysvshm", "System V " - "style shared memory support available"), -/* 5*/ /* KERN_SYSVIPC_SHMMAX: not yet supported */ -/* 6*/ /* KERN_SYSVIPC_SHMMNI: not yet supported */ -/* 7*/ /* KERN_SYSVIPC_SHMSEG: not yet supported */ -/* 8*/ /* KERN_SYSVIPC_SHMMAXPGS: not yet supported */ -/* 9*/ /* KERN_SYSVIPC_SHMUSEPHYS: not yet supported */ - /* In addition, NetBSD has a number of dynamic nodes here. */ -}; - -/* The CTL_KERN KERN_SYSVIPC node. */ -static struct rmib_node kern_ipc_node = - RMIB_NODE(RMIB_RO, kern_ipc_table, "ipc", "SysV IPC options"); - -/* - * Initialize the IPC server. - */ -static int -sef_cb_init_fresh(int type __unused, sef_init_info_t * info __unused) -{ - const int mib[] = { CTL_KERN, KERN_SYSVIPC }; - int r; - - /* - * Register our own "kern.ipc" subtree with the MIB service. - * - * This call only returns local failures. Remote failures (in the MIB - * service) are silently ignored. So, we can safely panic on failure. - */ - if ((r = rmib_register(mib, __arraycount(mib), &kern_ipc_node)) != OK) - panic("unable to register remote MIB tree: %d", r); - - return OK; -} - -/* - * The service has received a signal. - */ -static void -sef_cb_signal_handler(int signo) -{ - - /* Only check for termination signal, ignore anything else. */ - if (signo != SIGTERM) return; - - /* - * Check if there are still IPC keys around. If not, we can safely - * exit immediately. Otherwise, warn the system administrator. - */ - if (is_sem_nil() && is_shm_nil()) { - rmib_deregister(&kern_ipc_node); - - sef_exit(0); - } - - printf("IPC: exit with unclean state\n"); -} - -/* - * Perform SEF initialization. - */ -static void -sef_local_startup(void) -{ - - /* Register init callbacks. */ - sef_setcb_init_fresh(sef_cb_init_fresh); - sef_setcb_init_restart(sef_cb_init_fresh); - - /* Register signal callbacks. */ - sef_setcb_signal_handler(sef_cb_signal_handler); - - /* Let SEF perform startup. */ - sef_startup(); -} - -/* - * Update the process event subscription mask if necessary, after one of the - * modules has changed its subscription needs. This code is set up so that - * support for SysV IPC message queues can be added easily later. - */ -static void -update_sub(unsigned int new_mask) -{ - - /* If the old and new mask are not both zero or nonzero, update. */ - if (!event_mask != !new_mask) { - /* - * Subscribe to PM process events, or unsubscribe. While it - * might be tempting to implement a system that subscribes to - * events only from processes that are actually blocked (or - * using the SysV IPC facilities at all), this would result in - * race conditions where subscription could happen "too late" - * for an ongoing signal delivery, causing the affected process - * to deadlock. Subscribing to events from any other call is - * safe however, and we exploit that to limit the kernel-level - * message passing overhead in the common case (which is that - * the IPC servier is not being used at all). After we have - * unsubscribed, we may still get a few leftover events for the - * previous subscription, and we must properly reply to those. - */ - if (new_mask) - proceventmask(PROC_EVENT_EXIT | PROC_EVENT_SIGNAL); - else - proceventmask(0); - } - - event_mask = new_mask; -} - -/* - * Update the process event subscription mask for the semaphore code. - */ -void -update_sem_sub(int want_events) -{ - unsigned int new_mask; - - new_mask = event_mask & ~SEM_EVENTS; - if (want_events) - new_mask |= SEM_EVENTS; - - update_sub(new_mask); -} - -/* - * PM sent us a process event message. Handle it, and reply. - */ -static void -got_proc_event(message * m) -{ - endpoint_t endpt; - int r, has_exited; - - endpt = m->m_pm_lsys_proc_event.endpt; - has_exited = (m->m_pm_lsys_proc_event.event == PROC_EVENT_EXIT); - - /* - * Currently, only semaphore handling needs to know about processes - * being signaled and exiting. - */ - if (event_mask & SEM_EVENTS) - sem_process_event(endpt, has_exited); - - /* Echo the request as a reply back to PM. */ - m->m_type = PROC_EVENT_REPLY; - if ((r = asynsend3(m->m_source, m, AMF_NOREPLY)) != OK) - printf("IPC: replying to PM process event failed (%d)\n", r); -} - -/* - * The System V IPC server. - */ -int -main(int argc, char ** argv) -{ - message m; - unsigned int call_index; - int r, ipc_status; - - /* SEF local startup. */ - env_setargs(argc, argv); - sef_local_startup(); - - /* The main message loop. */ - for (;;) { - if ((r = sef_receive_status(ANY, &m, &ipc_status)) != OK) - panic("IPC: sef_receive_status failed: %d", r); - - if (verbose) - printf("IPC: got %d from %d\n", m.m_type, m.m_source); - - if (is_ipc_notify(ipc_status)) { - printf("IPC: ignoring notification from %d\n", - m.m_source); - continue; - } - - /* Process event messages from PM are handled separately. */ - if (m.m_source == PM_PROC_NR && m.m_type == PROC_EVENT) { - got_proc_event(&m); - - continue; - } - - /* Remote MIB messages from MIB are handled separately too. */ - if (m.m_source == MIB_PROC_NR) { - rmib_process(&m, ipc_status); - - continue; - } - - /* Dispatch the request. */ - call_index = (unsigned int)(m.m_type - IPC_BASE); - - if (call_index < __arraycount(call_vec) && - call_vec[call_index] != NULL) { - r = call_vec[call_index](&m); - } else - r = ENOSYS; - - /* Send a reply, if needed. */ - if (r != SUSPEND) { - if (verbose) - printf("IPC: call result %d\n", r); - - m.m_type = r; - /* - * Other fields may have been set by the handler - * function already. - */ - - if ((r = ipc_sendnb(m.m_source, &m)) != OK) - printf("IPC: send error %d\n", r); - } - - /* XXX there must be a better way to do this! */ - update_refcount_and_destroy(); - } - - /* NOTREACHED */ - return 0; -} diff --git a/minix/servers/ipc/sem.c b/minix/servers/ipc/sem.c deleted file mode 100644 index e1bcfda13..000000000 --- a/minix/servers/ipc/sem.c +++ /dev/null @@ -1,888 +0,0 @@ -#include "inc.h" - -struct sem_struct; - -/* IPC-server process table, currently used for semaphores only. */ -struct iproc { - struct sem_struct *ip_sem; /* affected semaphore set, or NULL */ - struct sembuf *ip_sops; /* pending operations (malloc'ed) */ - unsigned int ip_nsops; /* number of pending operations */ - struct sembuf *ip_blkop; /* pointer to operation that blocked */ - endpoint_t ip_endpt; /* process endpoint */ - pid_t ip_pid; /* process PID */ - TAILQ_ENTRY(iproc) ip_next; /* next waiting process */ -} iproc[NR_PROCS]; - -struct semaphore { - unsigned short semval; /* semaphore value */ - unsigned short semzcnt; /* # waiting for zero */ - unsigned short semncnt; /* # waiting for increase */ - pid_t sempid; /* process that did last op */ -}; - -/* - * For the list of waiting processes, we use a doubly linked tail queue. In - * order to maintain a basic degree of fairness, we keep the pending processes - * in FCFS (well, at least first tested) order, which means we need to be able - * to add new processes at the end of the list. In order to remove waiting - * processes O(1) instead of O(n) we need a doubly linked list; in the common - * case we do have the element's predecessor, but STAILQ_REMOVE is O(n) anyway - * and NetBSD has no STAILQ_REMOVE_AFTER yet. - * - * We use one list per semaphore set: semop(2) affects only one semaphore set, - * but it may involve operations on multiple semaphores within the set. While - * it is possible to recheck only semaphores that were affected by a particular - * operation, and associate waiting lists to individual semaphores, the number - * of expected waiting processes is currently not high enough to justify the - * extra complexity of such an implementation. - */ -struct sem_struct { - struct semid_ds semid_ds; - struct semaphore sems[SEMMSL]; - TAILQ_HEAD(waiters, iproc) waiters; -}; - -static struct sem_struct sem_list[SEMMNI]; -static unsigned int sem_list_nr = 0; /* highest in-use slot number plus one */ - -/* - * Find a semaphore set by key. The given key must not be IPC_PRIVATE. Return - * a pointer to the semaphore set if found, or NULL otherwise. - */ -static struct sem_struct * -sem_find_key(key_t key) -{ - unsigned int i; - - for (i = 0; i < sem_list_nr; i++) { - if (!(sem_list[i].semid_ds.sem_perm.mode & SEM_ALLOC)) - continue; - if (sem_list[i].semid_ds.sem_perm._key == key) - return &sem_list[i]; - } - - return NULL; -} - -/* - * Find a semaphore set by identifier. Return a pointer to the semaphore set - * if found, or NULL otherwise. - */ -static struct sem_struct * -sem_find_id(int id) -{ - struct sem_struct *sem; - unsigned int i; - - i = IPCID_TO_IX(id); - if (i >= sem_list_nr) - return NULL; - - sem = &sem_list[i]; - if (!(sem->semid_ds.sem_perm.mode & SEM_ALLOC)) - return NULL; - if (sem->semid_ds.sem_perm._seq != IPCID_TO_SEQ(id)) - return NULL; - return sem; -} - -/* - * Implementation of the semget(2) system call. - */ -int -do_semget(message * m) -{ - struct sem_struct *sem; - unsigned int i, seq; - key_t key; - int nsems, flag; - - key = m->m_lc_ipc_semget.key; - nsems = m->m_lc_ipc_semget.nr; - flag = m->m_lc_ipc_semget.flag; - - if (key != IPC_PRIVATE && (sem = sem_find_key(key)) != NULL) { - if ((flag & IPC_CREAT) && (flag & IPC_EXCL)) - return EEXIST; - if (!check_perm(&sem->semid_ds.sem_perm, m->m_source, flag)) - return EACCES; - if (nsems > sem->semid_ds.sem_nsems) - return EINVAL; - i = sem - sem_list; - } else { - if (key != IPC_PRIVATE && !(flag & IPC_CREAT)) - return ENOENT; - if (nsems <= 0 || nsems > SEMMSL) - return EINVAL; - - /* Find a free entry. */ - for (i = 0; i < __arraycount(sem_list); i++) - if (!(sem_list[i].semid_ds.sem_perm.mode & SEM_ALLOC)) - break; - if (i == __arraycount(sem_list)) - return ENOSPC; - - /* Initialize the entry. */ - sem = &sem_list[i]; - seq = sem->semid_ds.sem_perm._seq; - memset(sem, 0, sizeof(*sem)); - sem->semid_ds.sem_perm._key = key; - sem->semid_ds.sem_perm.cuid = - sem->semid_ds.sem_perm.uid = getnuid(m->m_source); - sem->semid_ds.sem_perm.cgid = - sem->semid_ds.sem_perm.gid = getngid(m->m_source); - sem->semid_ds.sem_perm.mode = SEM_ALLOC | (flag & ACCESSPERMS); - sem->semid_ds.sem_perm._seq = (seq + 1) & 0x7fff; - sem->semid_ds.sem_nsems = nsems; - sem->semid_ds.sem_otime = 0; - sem->semid_ds.sem_ctime = clock_time(NULL); - TAILQ_INIT(&sem->waiters); - - assert(i <= sem_list_nr); - if (i == sem_list_nr) { - /* - * If no semaphore sets were allocated before, - * subscribe to process events now. - */ - if (sem_list_nr == 0) - update_sem_sub(TRUE /*want_events*/); - - sem_list_nr++; - } - } - - m->m_lc_ipc_semget.retid = IXSEQ_TO_IPCID(i, sem->semid_ds.sem_perm); - return OK; -} - -/* - * Increase the proper suspension count (semncnt or semzcnt) of the semaphore - * on which the given process is blocked. - */ -static void -inc_susp_count(struct iproc * ip) -{ - struct sembuf *blkop; - struct semaphore *sp; - - blkop = ip->ip_blkop; - sp = &ip->ip_sem->sems[blkop->sem_num]; - - if (blkop->sem_op != 0) { - assert(sp->semncnt < USHRT_MAX); - sp->semncnt++; - } else { - assert(sp->semncnt < USHRT_MAX); - sp->semzcnt++; - } -} - -/* - * Decrease the proper suspension count (semncnt or semzcnt) of the semaphore - * on which the given process is blocked. - */ -static void -dec_susp_count(struct iproc * ip) -{ - struct sembuf *blkop; - struct semaphore *sp; - - blkop = ip->ip_blkop; - sp = &ip->ip_sem->sems[blkop->sem_num]; - - if (blkop->sem_op != 0) { - assert(sp->semncnt > 0); - sp->semncnt--; - } else { - assert(sp->semzcnt > 0); - sp->semzcnt--; - } -} - -/* - * Send a reply for a semop(2) call suspended earlier, thus waking up the - * process. - */ -static void -send_reply(endpoint_t who, int ret) -{ - message m; - - memset(&m, 0, sizeof(m)); - m.m_type = ret; - - ipc_sendnb(who, &m); -} - -/* - * Satisfy or cancel the semop(2) call on which the given process is blocked, - * and send the given reply code (OK or a negative error code) to wake it up, - * unless the given code is EDONTREPLY. - */ -static void -complete_semop(struct iproc * ip, int code) -{ - struct sem_struct *sem; - - sem = ip->ip_sem; - - assert(sem != NULL); - - TAILQ_REMOVE(&sem->waiters, ip, ip_next); - - dec_susp_count(ip); - - assert(ip->ip_sops != NULL); - free(ip->ip_sops); - - ip->ip_sops = NULL; - ip->ip_blkop = NULL; - ip->ip_sem = NULL; - - if (code != EDONTREPLY) - send_reply(ip->ip_endpt, code); -} - -/* - * Free up the given semaphore set. This includes cancelling any blocking - * semop(2) calls on any of its semaphores. - */ -static void -remove_set(struct sem_struct * sem) -{ - struct iproc *ip; - - /* - * Cancel all semop(2) operations on this semaphore set, with an EIDRM - * reply code. - */ - while (!TAILQ_EMPTY(&sem->waiters)) { - ip = TAILQ_FIRST(&sem->waiters); - - complete_semop(ip, EIDRM); - } - - /* Mark the entry as free. */ - sem->semid_ds.sem_perm.mode &= ~SEM_ALLOC; - - /* - * This may have been the last in-use slot in the list. Ensure that - * sem_list_nr again equals the highest in-use slot number plus one. - */ - while (sem_list_nr > 0 && - !(sem_list[sem_list_nr - 1].semid_ds.sem_perm.mode & SEM_ALLOC)) - sem_list_nr--; - - /* - * If this was our last semaphore set, unsubscribe from process events. - */ - if (sem_list_nr == 0) - update_sem_sub(FALSE /*want_events*/); -} - -/* - * Try to perform a set of semaphore operations, as given by semop(2), on a - * semaphore set. The entire action must be atomic, i.e., either succeed in - * its entirety or fail without making any changes. Return OK on success, in - * which case the PIDs of all affected semaphores will be updated to the given - * 'pid' value, and the semaphore set's sem_otime will be updated as well. - * Return SUSPEND if the call should be suspended, in which case 'blkop' will - * be set to a pointer to the operation causing the call to block. Return an - * error code if the call failed altogether. - */ -static int -try_semop(struct sem_struct *sem, struct sembuf *sops, unsigned int nsops, - pid_t pid, struct sembuf ** blkop) -{ - struct semaphore *sp; - struct sembuf *op; - unsigned int i; - int r; - - /* - * The operation must be processed atomically. However, it must also - * be processed "in array order," which we assume to mean that while - * processing one operation, the changes of the previous operations - * must be taken into account. This is relevant for cases where the - * same semaphore is referenced by more than one operation, for example - * to perform an atomic increase-if-zero action on a single semaphore. - * As a result, we must optimistically modify semaphore values and roll - * back on suspension or failure afterwards. - */ - r = OK; - op = NULL; - for (i = 0; i < nsops; i++) { - sp = &sem->sems[sops[i].sem_num]; - op = &sops[i]; - - if (op->sem_op > 0) { - if (SEMVMX - sp->semval < op->sem_op) { - r = ERANGE; - break; - } - sp->semval += op->sem_op; - } else if (op->sem_op < 0) { - /* - * No SEMVMX check; if the process wants to deadlock - * itself by supplying -SEMVMX it is free to do so.. - */ - if ((int)sp->semval < -(int)op->sem_op) { - r = (op->sem_flg & IPC_NOWAIT) ? EAGAIN : - SUSPEND; - break; - } - sp->semval += op->sem_op; - } else /* (op->sem_op == 0) */ { - if (sp->semval != 0) { - r = (op->sem_flg & IPC_NOWAIT) ? EAGAIN : - SUSPEND; - break; - } - } - } - - /* - * If we did not go through all the operations, then either an error - * occurred or the user process is to be suspended. In that case we - * must roll back any progress we have made so far, and return the - * operation that caused the call to block. - */ - if (i < nsops) { - assert(op != NULL); - *blkop = op; - - /* Roll back all changes made so far. */ - while (i-- > 0) - sem->sems[sops[i].sem_num].semval -= sops[i].sem_op; - - assert(r != OK); - return r; - } - - /* - * The operation has completed successfully. Also update all affected - * semaphores' PID values, and the semaphore set's last-semop time. - * The caller must do everything else. - */ - for (i = 0; i < nsops; i++) - sem->sems[sops[i].sem_num].sempid = pid; - - sem->semid_ds.sem_otime = clock_time(NULL); - - return OK; -} - -/* - * Check whether any blocked operations can now be satisfied on any of the - * semaphores in the given semaphore set. Do this repeatedly as necessary, as - * any unblocked operation may in turn allow other operations to be resumed. - */ -static void -check_set(struct sem_struct * sem) -{ - struct iproc *ip, *nextip; - struct sembuf *blkop; - int r, woken_up; - - /* - * Go through all the waiting processes in FIFO order, which is our - * best attempt at providing at least some fairness. Keep trying as - * long as we woke up at least one process, which means we made actual - * progress. - */ - do { - woken_up = FALSE; - - TAILQ_FOREACH_SAFE(ip, &sem->waiters, ip_next, nextip) { - /* Retry the entire semop(2) operation, atomically. */ - r = try_semop(ip->ip_sem, ip->ip_sops, ip->ip_nsops, - ip->ip_pid, &blkop); - - if (r != SUSPEND) { - /* Success or failure. */ - complete_semop(ip, r); - - /* No changes are made on failure. */ - if (r == OK) - woken_up = TRUE; - } else if (blkop != ip->ip_blkop) { - /* - * The process stays suspended, but it is now - * blocked on a different semaphore. As a - * result, we need to adjust the semaphores' - * suspension counts. - */ - dec_susp_count(ip); - - ip->ip_blkop = blkop; - - inc_susp_count(ip); - } - } - } while (woken_up); -} - -/* - * Fill a seminfo structure with actual information. The information returned - * depends on the given command, which may be either IPC_INFO or SEM_INFO. - */ -static void -fill_seminfo(struct seminfo * sinfo, int cmd) -{ - unsigned int i; - - assert(cmd == IPC_INFO || cmd == SEM_INFO); - - memset(sinfo, 0, sizeof(*sinfo)); - - sinfo->semmap = SEMMNI; - sinfo->semmni = SEMMNI; - sinfo->semmns = SEMMNI * SEMMSL; - sinfo->semmnu = 0; /* TODO: support for SEM_UNDO */ - sinfo->semmsl = SEMMSL; - sinfo->semopm = SEMOPM; - sinfo->semume = 0; /* TODO: support for SEM_UNDO */ - if (cmd == SEM_INFO) { - /* - * For SEM_INFO the semusz field is expected to contain the - * number of semaphore sets currently in use. - */ - sinfo->semusz = sem_list_nr; - } else - sinfo->semusz = 0; /* TODO: support for SEM_UNDO */ - sinfo->semvmx = SEMVMX; - if (cmd == SEM_INFO) { - /* - * For SEM_INFO the semaem field is expected to contain - * the total number of allocated semaphores. - */ - for (i = 0; i < sem_list_nr; i++) - sinfo->semaem += sem_list[i].semid_ds.sem_nsems; - } else - sinfo->semaem = 0; /* TODO: support for SEM_UNDO */ -} - -/* - * Implementation of the semctl(2) system call. - */ -int -do_semctl(message * m) -{ - static unsigned short valbuf[SEMMSL]; - unsigned int i; - vir_bytes opt; - uid_t uid; - int r, id, num, cmd, val; - struct semid_ds tmp_ds; - struct sem_struct *sem; - struct seminfo sinfo; - - id = m->m_lc_ipc_semctl.id; - num = m->m_lc_ipc_semctl.num; - cmd = m->m_lc_ipc_semctl.cmd; - opt = m->m_lc_ipc_semctl.opt; - - /* - * Look up the target semaphore set. The IPC_INFO and SEM_INFO - * commands have no associated semaphore set. The SEM_STAT command - * takes an array index into the semaphore set table. For all other - * commands, look up the semaphore set by its given identifier. - * */ - switch (cmd) { - case IPC_INFO: - case SEM_INFO: - sem = NULL; - break; - case SEM_STAT: - if (id < 0 || (unsigned int)id >= sem_list_nr) - return EINVAL; - sem = &sem_list[id]; - if (!(sem->semid_ds.sem_perm.mode & SEM_ALLOC)) - return EINVAL; - break; - default: - if ((sem = sem_find_id(id)) == NULL) - return EINVAL; - break; - } - - /* - * Check if the caller has the appropriate permissions on the target - * semaphore set. SETVAL and SETALL require write permission. IPC_SET - * and IPC_RMID require ownership permission, and return EPERM instead - * of EACCES on failure. IPC_INFO and SEM_INFO are free for general - * use. All other calls require read permission. - */ - switch (cmd) { - case SETVAL: - case SETALL: - assert(sem != NULL); - if (!check_perm(&sem->semid_ds.sem_perm, m->m_source, IPC_W)) - return EACCES; - break; - case IPC_SET: - case IPC_RMID: - assert(sem != NULL); - uid = getnuid(m->m_source); - if (uid != sem->semid_ds.sem_perm.cuid && - uid != sem->semid_ds.sem_perm.uid && uid != 0) - return EPERM; - break; - case IPC_INFO: - case SEM_INFO: - break; - default: - assert(sem != NULL); - if (!check_perm(&sem->semid_ds.sem_perm, m->m_source, IPC_R)) - return EACCES; - } - - switch (cmd) { - case IPC_STAT: - case SEM_STAT: - if ((r = sys_datacopy(SELF, (vir_bytes)&sem->semid_ds, - m->m_source, opt, sizeof(sem->semid_ds))) != OK) - return r; - if (cmd == SEM_STAT) - m->m_lc_ipc_semctl.ret = - IXSEQ_TO_IPCID(id, sem->semid_ds.sem_perm); - break; - case IPC_SET: - if ((r = sys_datacopy(m->m_source, opt, SELF, - (vir_bytes)&tmp_ds, sizeof(tmp_ds))) != OK) - return r; - sem->semid_ds.sem_perm.uid = tmp_ds.sem_perm.uid; - sem->semid_ds.sem_perm.gid = tmp_ds.sem_perm.gid; - sem->semid_ds.sem_perm.mode &= ~ACCESSPERMS; - sem->semid_ds.sem_perm.mode |= - tmp_ds.sem_perm.mode & ACCESSPERMS; - sem->semid_ds.sem_ctime = clock_time(NULL); - break; - case IPC_RMID: - /* - * Awaken all processes blocked in semop(2) on any semaphore in - * this set, and remove the semaphore set itself. - */ - remove_set(sem); - break; - case IPC_INFO: - case SEM_INFO: - fill_seminfo(&sinfo, cmd); - - if ((r = sys_datacopy(SELF, (vir_bytes)&sinfo, m->m_source, - opt, sizeof(sinfo))) != OK) - return r; - /* Return the highest in-use slot number if any, or zero. */ - if (sem_list_nr > 0) - m->m_lc_ipc_semctl.ret = sem_list_nr - 1; - else - m->m_lc_ipc_semctl.ret = 0; - break; - case GETALL: - assert(sem->semid_ds.sem_nsems <= __arraycount(valbuf)); - for (i = 0; i < sem->semid_ds.sem_nsems; i++) - valbuf[i] = sem->sems[i].semval; - r = sys_datacopy(SELF, (vir_bytes)valbuf, m->m_source, - opt, sizeof(unsigned short) * sem->semid_ds.sem_nsems); - if (r != OK) - return r; - break; - case GETNCNT: - if (num < 0 || num >= sem->semid_ds.sem_nsems) - return EINVAL; - m->m_lc_ipc_semctl.ret = sem->sems[num].semncnt; - break; - case GETPID: - if (num < 0 || num >= sem->semid_ds.sem_nsems) - return EINVAL; - m->m_lc_ipc_semctl.ret = sem->sems[num].sempid; - break; - case GETVAL: - if (num < 0 || num >= sem->semid_ds.sem_nsems) - return EINVAL; - m->m_lc_ipc_semctl.ret = sem->sems[num].semval; - break; - case GETZCNT: - if (num < 0 || num >= sem->semid_ds.sem_nsems) - return EINVAL; - m->m_lc_ipc_semctl.ret = sem->sems[num].semzcnt; - break; - case SETALL: - assert(sem->semid_ds.sem_nsems <= __arraycount(valbuf)); - r = sys_datacopy(m->m_source, opt, SELF, (vir_bytes)valbuf, - sizeof(unsigned short) * sem->semid_ds.sem_nsems); - if (r != OK) - return r; - for (i = 0; i < sem->semid_ds.sem_nsems; i++) - if (valbuf[i] > SEMVMX) - return ERANGE; -#ifdef DEBUG_SEM - for (i = 0; i < sem->semid_ds.sem_nsems; i++) - printf("SEMCTL: SETALL val: [%d] %d\n", i, valbuf[i]); -#endif - for (i = 0; i < sem->semid_ds.sem_nsems; i++) - sem->sems[i].semval = valbuf[i]; - sem->semid_ds.sem_ctime = clock_time(NULL); - /* Awaken any waiting parties if now possible. */ - check_set(sem); - break; - case SETVAL: - val = (int)opt; - if (num < 0 || num >= sem->semid_ds.sem_nsems) - return EINVAL; - if (val < 0 || val > SEMVMX) - return ERANGE; - sem->sems[num].semval = val; -#ifdef DEBUG_SEM - printf("SEMCTL: SETVAL: %d %d\n", num, val); -#endif - sem->semid_ds.sem_ctime = clock_time(NULL); - /* Awaken any waiting parties if now possible. */ - check_set(sem); - break; - default: - return EINVAL; - } - - return OK; -} - -/* - * Implementation of the semop(2) system call. - */ -int -do_semop(message * m) -{ - unsigned int i, mask, slot; - int id, r; - struct sembuf *sops, *blkop; - unsigned int nsops; - struct sem_struct *sem; - struct iproc *ip; - pid_t pid; - - id = m->m_lc_ipc_semop.id; - nsops = m->m_lc_ipc_semop.size; - - if ((sem = sem_find_id(id)) == NULL) - return EINVAL; - - if (nsops == 0) - return OK; /* nothing to do */ - if (nsops > SEMOPM) - return E2BIG; - - /* Get the array from the user process. */ - sops = malloc(sizeof(sops[0]) * nsops); - if (sops == NULL) - return ENOMEM; - r = sys_datacopy(m->m_source, (vir_bytes)m->m_lc_ipc_semop.ops, SELF, - (vir_bytes)sops, sizeof(sops[0]) * nsops); - if (r != OK) - goto out_free; - -#ifdef DEBUG_SEM - for (i = 0; i < nsops; i++) - printf("SEMOP: num:%d op:%d flg:%d\n", - sops[i].sem_num, sops[i].sem_op, sops[i].sem_flg); -#endif - /* - * Check for permissions. We do this only once, even though the call - * might suspend and the semaphore set's permissions might be changed - * before the call resumes. The specification is not clear on this. - * Either way, perform the permission check before checking on the - * validity of semaphore numbers, since obtaining the semaphore set - * size itself requires read permission (except through sysctl(2)..). - */ - mask = 0; - for (i = 0; i < nsops; i++) { - if (sops[i].sem_op != 0) - mask |= IPC_W; /* check for write permission */ - else - mask |= IPC_R; /* check for read permission */ - } - r = EACCES; - if (!check_perm(&sem->semid_ds.sem_perm, m->m_source, mask)) - goto out_free; - - /* Check that all given semaphore numbers are within range. */ - r = EFBIG; - for (i = 0; i < nsops; i++) - if (sops[i].sem_num >= sem->semid_ds.sem_nsems) - goto out_free; - - /* - * Do not check if the same semaphore is referenced more than once - * (there was such a check here originally), because that is actually - * a valid case. The result is however that it is possible to - * construct a semop(2) request that will never complete, and thus, - * care must be taken that such requests do not create potential - * deadlock situations etc. - */ - - pid = getnpid(m->m_source); - - /* - * We do not yet support SEM_UNDO at all, so we better not give the - * caller the impression that we do. For now, print a warning so that - * we know when an application actually fails for that reason. - */ - for (i = 0; i < nsops; i++) { - if (sops[i].sem_flg & SEM_UNDO) { - /* Print a warning only if this isn't the test set.. */ - if (sops[i].sem_flg != SHRT_MAX) - printf("IPC: pid %d tried to use SEM_UNDO\n", - pid); - r = EINVAL; - goto out_free; - } - } - - /* Try to perform the operation now. */ - r = try_semop(sem, sops, nsops, pid, &blkop); - - if (r == SUSPEND) { - /* - * The operation ended up blocking on a particular semaphore - * operation. Save all details in the slot for the user - * process, and add it to the list of processes waiting for - * this semaphore set. - */ - slot = _ENDPOINT_P(m->m_source); - assert(slot < __arraycount(iproc)); - - ip = &iproc[slot]; - assert(ip->ip_sem == NULL); /* can't already be in use */ - - ip->ip_endpt = m->m_source; - ip->ip_pid = pid; - ip->ip_sem = sem; - ip->ip_sops = sops; - ip->ip_nsops = nsops; - ip->ip_blkop = blkop; - - TAILQ_INSERT_TAIL(&sem->waiters, ip, ip_next); - - inc_susp_count(ip); - - return r; - } - -out_free: - free(sops); - - /* Awaken any other waiting parties if now possible. */ - if (r == OK) - check_set(sem); - - return r; -} - -/* - * Return semaphore information for a remote MIB call on the sysvipc_info node - * in the kern.ipc subtree. The particular semantics of this call are tightly - * coupled to the implementation of the ipcs(1) userland utility. - */ -ssize_t -get_sem_mib_info(struct rmib_oldp * oldp) -{ - struct sem_sysctl_info semsi; - struct semid_ds *semds; - unsigned int i; - ssize_t r, off; - - off = 0; - - fill_seminfo(&semsi.seminfo, IPC_INFO); - - /* - * As a hackish exception, the requested size may imply that just - * general information is to be returned, without throwing an ENOMEM - * error because there is no space for full output. - */ - if (rmib_getoldlen(oldp) == sizeof(semsi.seminfo)) - return rmib_copyout(oldp, 0, &semsi.seminfo, - sizeof(semsi.seminfo)); - - /* - * ipcs(1) blindly expects the returned array to be of size - * seminfo.semmni, using the SEM_ALLOC mode flag to see whether each - * entry is valid. If we return a smaller size, ipcs(1) will access - * arbitrary memory. - */ - assert(semsi.seminfo.semmni > 0); - - if (oldp == NULL) - return sizeof(semsi) + sizeof(semsi.semids[0]) * - (semsi.seminfo.semmni - 1); - - /* - * Copy out entries one by one. For the first entry, copy out the - * entire "semsi" structure. For subsequent entries, reuse the single - * embedded 'semids' element of "semsi" and copy out only that element. - */ - for (i = 0; i < (unsigned int)semsi.seminfo.semmni; i++) { - semds = &sem_list[i].semid_ds; - - memset(&semsi.semids[0], 0, sizeof(semsi.semids[0])); - if (i < sem_list_nr && (semds->sem_perm.mode & SEM_ALLOC)) { - prepare_mib_perm(&semsi.semids[0].sem_perm, - &semds->sem_perm); - semsi.semids[0].sem_nsems = semds->sem_nsems; - semsi.semids[0].sem_otime = semds->sem_otime; - semsi.semids[0].sem_ctime = semds->sem_ctime; - } - - if (off == 0) - r = rmib_copyout(oldp, off, &semsi, sizeof(semsi)); - else - r = rmib_copyout(oldp, off, &semsi.semids[0], - sizeof(semsi.semids[0])); - - if (r < 0) - return r; - off += r; - } - - return off; -} - -/* - * Return TRUE iff no semaphore sets are allocated. - */ -int -is_sem_nil(void) -{ - - return (sem_list_nr == 0); -} - -/* - * Check if the given endpoint is blocked on a semop(2) call. If so, cancel - * the call, because either it is interrupted by a signal or the process was - * killed. In the former case, unblock the process by replying with EINTR. - */ -void -sem_process_event(endpoint_t endpt, int has_exited) -{ - unsigned int slot; - struct iproc *ip; - - slot = _ENDPOINT_P(endpt); - assert(slot < __arraycount(iproc)); - - ip = &iproc[slot]; - - /* Was the process blocked on a semop(2) call at all? */ - if (ip->ip_sem == NULL) - return; - - assert(ip->ip_endpt == endpt); - - /* - * It was; cancel the semop(2) call. If the process is being removed - * because its call was interrupted by a signal, then we must wake it - * up with EINTR. - */ - complete_semop(ip, has_exited ? EDONTREPLY : EINTR); -} diff --git a/minix/servers/ipc/shm.c b/minix/servers/ipc/shm.c deleted file mode 100644 index 11b489765..000000000 --- a/minix/servers/ipc/shm.c +++ /dev/null @@ -1,469 +0,0 @@ -#include "inc.h" - -/* Private shm_perm.mode flags, synchronized with NetBSD kernel values */ -#define SHM_ALLOC 0x0800 /* slot is in use (SHMSEG_ALLOCATED) */ - -struct shm_struct { - struct shmid_ds shmid_ds; - vir_bytes page; - phys_bytes vm_id; -}; -static struct shm_struct shm_list[SHMMNI]; -static unsigned int shm_list_nr = 0; /* highest in-use slot number plus one */ - -static struct shm_struct * -shm_find_key(key_t key) -{ - unsigned int i; - - if (key == IPC_PRIVATE) - return NULL; - - for (i = 0; i < shm_list_nr; i++) { - if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) - continue; - if (shm_list[i].shmid_ds.shm_perm._key == key) - return &shm_list[i]; - } - - return NULL; -} - -static struct shm_struct * -shm_find_id(int id) -{ - struct shm_struct *shm; - unsigned int i; - - i = IPCID_TO_IX(id); - if (i >= shm_list_nr) - return NULL; - - shm = &shm_list[i]; - if (!(shm->shmid_ds.shm_perm.mode & SHM_ALLOC)) - return NULL; - if (shm->shmid_ds.shm_perm._seq != IPCID_TO_SEQ(id)) - return NULL; - return shm; -} - -int -do_shmget(message * m) -{ - struct shm_struct *shm; - unsigned int i, seq; - key_t key; - size_t size, old_size; - int flag; - void *page; - - key = m->m_lc_ipc_shmget.key; - old_size = size = m->m_lc_ipc_shmget.size; - flag = m->m_lc_ipc_shmget.flag; - - if ((shm = shm_find_key(key)) != NULL) { - if (!check_perm(&shm->shmid_ds.shm_perm, m->m_source, flag)) - return EACCES; - if ((flag & IPC_CREAT) && (flag & IPC_EXCL)) - return EEXIST; - if (size && shm->shmid_ds.shm_segsz < size) - return EINVAL; - i = shm - shm_list; - } else { /* no key found */ - if (!(flag & IPC_CREAT)) - return ENOENT; - if (size <= 0) - return EINVAL; - size = roundup(size, PAGE_SIZE); - if (size <= 0) - return EINVAL; - - /* Find a free entry. */ - for (i = 0; i < __arraycount(shm_list); i++) - if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) - break; - if (i == __arraycount(shm_list)) - return ENOSPC; - - /* - * Allocate memory to share. For now, we store the page - * reference as a numerical value so as to avoid issues with - * live update. TODO: a proper solution. - */ - page = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); - if (page == MAP_FAILED) - return ENOMEM; - memset(page, 0, size); - - /* Initialize the entry. */ - shm = &shm_list[i]; - seq = shm->shmid_ds.shm_perm._seq; - memset(shm, 0, sizeof(*shm)); - - shm->shmid_ds.shm_perm._key = key; - shm->shmid_ds.shm_perm.cuid = - shm->shmid_ds.shm_perm.uid = getnuid(m->m_source); - shm->shmid_ds.shm_perm.cgid = - shm->shmid_ds.shm_perm.gid = getngid(m->m_source); - shm->shmid_ds.shm_perm.mode = SHM_ALLOC | (flag & ACCESSPERMS); - shm->shmid_ds.shm_perm._seq = (seq + 1) & 0x7fff; - shm->shmid_ds.shm_segsz = old_size; - shm->shmid_ds.shm_atime = 0; - shm->shmid_ds.shm_dtime = 0; - shm->shmid_ds.shm_ctime = clock_time(NULL); - shm->shmid_ds.shm_cpid = getnpid(m->m_source); - shm->shmid_ds.shm_lpid = 0; - shm->shmid_ds.shm_nattch = 0; - shm->page = (vir_bytes)page; - shm->vm_id = vm_getphys(sef_self(), page); - - assert(i <= shm_list_nr); - if (i == shm_list_nr) - shm_list_nr++; - } - - m->m_lc_ipc_shmget.retid = IXSEQ_TO_IPCID(i, shm->shmid_ds.shm_perm); - return OK; -} - -int -do_shmat(message * m) -{ - int id, flag, mask; - vir_bytes addr; - void *ret; - struct shm_struct *shm; - - id = m->m_lc_ipc_shmat.id; - addr = (vir_bytes)m->m_lc_ipc_shmat.addr; - flag = m->m_lc_ipc_shmat.flag; - - if (addr % PAGE_SIZE) { - if (flag & SHM_RND) - addr -= addr % PAGE_SIZE; - else - return EINVAL; - } - - if ((shm = shm_find_id(id)) == NULL) - return EINVAL; - - mask = 0; - if (flag & SHM_RDONLY) - mask = IPC_R; - else - mask = IPC_R | IPC_W; - if (!check_perm(&shm->shmid_ds.shm_perm, m->m_source, mask)) - return EACCES; - - ret = vm_remap(m->m_source, sef_self(), (void *)addr, - (void *)shm->page, shm->shmid_ds.shm_segsz); - if (ret == MAP_FAILED) - return ENOMEM; - - shm->shmid_ds.shm_atime = clock_time(NULL); - shm->shmid_ds.shm_lpid = getnpid(m->m_source); - /* nattch is updated lazily */ - - m->m_lc_ipc_shmat.retaddr = ret; - return OK; -} - -void -update_refcount_and_destroy(void) -{ - u8_t rc; - unsigned int i; - - for (i = 0; i < shm_list_nr; i++) { - if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) - continue; - - rc = vm_getrefcount(sef_self(), (void *)shm_list[i].page); - if (rc == (u8_t)-1) { - printf("IPC: can't find physical region.\n"); - continue; - } - shm_list[i].shmid_ds.shm_nattch = rc - 1; - - if (shm_list[i].shmid_ds.shm_nattch == 0 && - (shm_list[i].shmid_ds.shm_perm.mode & SHM_DEST)) { - munmap((void *)shm_list[i].page, - roundup(shm_list[i].shmid_ds.shm_segsz, - PAGE_SIZE)); - /* Mark the entry as free. */ - shm_list[i].shmid_ds.shm_perm.mode &= ~SHM_ALLOC; - } - } - - /* - * Now that we may have removed an arbitrary set of slots, ensure that - * shm_list_nr again equals the highest in-use slot number plus one. - */ - while (shm_list_nr > 0 && - !(shm_list[shm_list_nr - 1].shmid_ds.shm_perm.mode & SHM_ALLOC)) - shm_list_nr--; -} - -int -do_shmdt(message * m) -{ - struct shm_struct *shm; - vir_bytes addr; - phys_bytes vm_id; - unsigned int i; - - addr = (vir_bytes)m->m_lc_ipc_shmdt.addr; - - if ((vm_id = vm_getphys(m->m_source, (void *)addr)) == 0) - return EINVAL; - - for (i = 0; i < shm_list_nr; i++) { - shm = &shm_list[i]; - - if (!(shm->shmid_ds.shm_perm.mode & SHM_ALLOC)) - continue; - - if (shm->vm_id == vm_id) { - shm->shmid_ds.shm_atime = clock_time(NULL); - shm->shmid_ds.shm_lpid = getnpid(m->m_source); - /* nattch is updated lazily */ - - vm_unmap(m->m_source, (void *)addr); - break; - } - } - if (i == shm_list_nr) - printf("IPC: do_shmdt: ID %lu not found\n", vm_id); - - update_refcount_and_destroy(); - - return OK; -} - -/* - * Fill a shminfo structure with actual information. - */ -static void -fill_shminfo(struct shminfo * sinfo) -{ - - memset(sinfo, 0, sizeof(*sinfo)); - - sinfo->shmmax = (unsigned long)-1; - sinfo->shmmin = 1; - sinfo->shmmni = __arraycount(shm_list); - sinfo->shmseg = (unsigned long)-1; - sinfo->shmall = (unsigned long)-1; -} - -int -do_shmctl(message * m) -{ - struct shmid_ds tmp_ds; - struct shm_struct *shm; - struct shminfo sinfo; - struct shm_info s_info; - vir_bytes buf; - unsigned int i; - uid_t uid; - int r, id, cmd; - - id = m->m_lc_ipc_shmctl.id; - cmd = m->m_lc_ipc_shmctl.cmd; - buf = (vir_bytes)m->m_lc_ipc_shmctl.buf; - - /* - * For stat calls, sure that all information is up-to-date. Since this - * may free the slot, do this before mapping from ID to slot below. - */ - if (cmd == IPC_STAT || cmd == SHM_STAT) - update_refcount_and_destroy(); - - switch (cmd) { - case IPC_INFO: - case SHM_INFO: - shm = NULL; - break; - case SHM_STAT: - if (id < 0 || (unsigned int)id >= shm_list_nr) - return EINVAL; - shm = &shm_list[id]; - if (!(shm->shmid_ds.shm_perm.mode & SHM_ALLOC)) - return EINVAL; - break; - default: - if ((shm = shm_find_id(id)) == NULL) - return EINVAL; - break; - } - - switch (cmd) { - case IPC_STAT: - case SHM_STAT: - /* Check whether the caller has read permission. */ - if (!check_perm(&shm->shmid_ds.shm_perm, m->m_source, IPC_R)) - return EACCES; - if ((r = sys_datacopy(SELF, (vir_bytes)&shm->shmid_ds, - m->m_source, buf, sizeof(shm->shmid_ds))) != OK) - return r; - if (cmd == SHM_STAT) - m->m_lc_ipc_shmctl.ret = - IXSEQ_TO_IPCID(id, shm->shmid_ds.shm_perm); - break; - case IPC_SET: - uid = getnuid(m->m_source); - if (uid != shm->shmid_ds.shm_perm.cuid && - uid != shm->shmid_ds.shm_perm.uid && uid != 0) - return EPERM; - if ((r = sys_datacopy(m->m_source, buf, SELF, - (vir_bytes)&tmp_ds, sizeof(tmp_ds))) != OK) - return r; - shm->shmid_ds.shm_perm.uid = tmp_ds.shm_perm.uid; - shm->shmid_ds.shm_perm.gid = tmp_ds.shm_perm.gid; - shm->shmid_ds.shm_perm.mode &= ~ACCESSPERMS; - shm->shmid_ds.shm_perm.mode |= - tmp_ds.shm_perm.mode & ACCESSPERMS; - shm->shmid_ds.shm_ctime = clock_time(NULL); - break; - case IPC_RMID: - uid = getnuid(m->m_source); - if (uid != shm->shmid_ds.shm_perm.cuid && - uid != shm->shmid_ds.shm_perm.uid && uid != 0) - return EPERM; - shm->shmid_ds.shm_perm.mode |= SHM_DEST; - /* Destroy if possible. */ - update_refcount_and_destroy(); - break; - case IPC_INFO: - fill_shminfo(&sinfo); - if ((r = sys_datacopy(SELF, (vir_bytes)&sinfo, m->m_source, - buf, sizeof(sinfo))) != OK) - return r; - if (shm_list_nr > 0) - m->m_lc_ipc_shmctl.ret = shm_list_nr - 1; - else - m->m_lc_ipc_shmctl.ret = 0; - break; - case SHM_INFO: - memset(&s_info, 0, sizeof(s_info)); - s_info.used_ids = shm_list_nr; - s_info.shm_tot = 0; - for (i = 0; i < shm_list_nr; i++) - s_info.shm_tot += - shm_list[i].shmid_ds.shm_segsz / PAGE_SIZE; - s_info.shm_rss = s_info.shm_tot; - s_info.shm_swp = 0; - s_info.swap_attempts = 0; - s_info.swap_successes = 0; - if ((r = sys_datacopy(SELF, (vir_bytes)&s_info, m->m_source, - buf, sizeof(s_info))) != OK) - return r; - if (shm_list_nr > 0) - m->m_lc_ipc_shmctl.ret = shm_list_nr - 1; - else - m->m_lc_ipc_shmctl.ret = 0; - break; - default: - return EINVAL; - } - return OK; -} - -/* - * Return shared memory information for a remote MIB call on the sysvipc_info - * node in the kern.ipc subtree. The particular semantics of this call are - * tightly coupled to the implementation of the ipcs(1) userland utility. - */ -ssize_t -get_shm_mib_info(struct rmib_oldp * oldp) -{ - struct shm_sysctl_info shmsi; - struct shmid_ds *shmds; - unsigned int i; - ssize_t r, off; - - off = 0; - - fill_shminfo(&shmsi.shminfo); - - /* - * As a hackish exception, the requested size may imply that just - * general information is to be returned, without throwing an ENOMEM - * error because there is no space for full output. - */ - if (rmib_getoldlen(oldp) == sizeof(shmsi.shminfo)) - return rmib_copyout(oldp, 0, &shmsi.shminfo, - sizeof(shmsi.shminfo)); - - /* - * ipcs(1) blindly expects the returned array to be of size - * shminfo.shmmni, using the SHMSEG_ALLOCATED (aka SHM_ALLOC) mode flag - * to see whether each entry is valid. If we return a smaller size, - * ipcs(1) will access arbitrary memory. - */ - assert(shmsi.shminfo.shmmni > 0); - - if (oldp == NULL) - return sizeof(shmsi) + sizeof(shmsi.shmids[0]) * - (shmsi.shminfo.shmmni - 1); - - /* - * Copy out entries one by one. For the first entry, copy out the - * entire "shmsi" structure. For subsequent entries, reuse the single - * embedded 'shmids' element of "shmsi" and copy out only that element. - */ - for (i = 0; i < shmsi.shminfo.shmmni; i++) { - shmds = &shm_list[i].shmid_ds; - - memset(&shmsi.shmids[0], 0, sizeof(shmsi.shmids[0])); - if (i < shm_list_nr && (shmds->shm_perm.mode & SHM_ALLOC)) { - prepare_mib_perm(&shmsi.shmids[0].shm_perm, - &shmds->shm_perm); - shmsi.shmids[0].shm_segsz = shmds->shm_segsz; - shmsi.shmids[0].shm_lpid = shmds->shm_lpid; - shmsi.shmids[0].shm_cpid = shmds->shm_cpid; - shmsi.shmids[0].shm_atime = shmds->shm_atime; - shmsi.shmids[0].shm_dtime = shmds->shm_dtime; - shmsi.shmids[0].shm_ctime = shmds->shm_ctime; - shmsi.shmids[0].shm_nattch = shmds->shm_nattch; - } - - if (off == 0) - r = rmib_copyout(oldp, off, &shmsi, sizeof(shmsi)); - else - r = rmib_copyout(oldp, off, &shmsi.shmids[0], - sizeof(shmsi.shmids[0])); - - if (r < 0) - return r; - off += r; - } - - return off; -} - -#if 0 -static void -list_shm_ds(void) -{ - unsigned int i; - - printf("key\tid\tpage\n"); - for (i = 0; i < shm_list_nr; i++) { - if (!(shm_list[i].shmid_ds.shm_perm.mode & SHM_ALLOC)) - continue; - printf("%ld\t%d\t%lx\n", - shm_list[i].shmid_ds.shm_perm._key, - IXSEQ_TO_IPCID(i, shm_list[i].shmid_ds.shm_perm), - shm_list[i].page); - } -} -#endif - -int -is_shm_nil(void) -{ - - return (shm_list_nr == 0); -} diff --git a/minix/servers/is/Makefile b/minix/servers/is/Makefile deleted file mode 100644 index 38644bf2d..000000000 --- a/minix/servers/is/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile for Information Server (IS) -.include - -PROG= is -SRCS= main.c dmp.c dmp_kernel.c dmp_pm.c dmp_fs.c dmp_rs.c dmp_ds.c dmp_vm.c - -DPADD+= ${LIBSYS} -LDADD+= -lsys - -CPPFLAGS.dmp_fs.c+= -I${NETBSDSRCDIR}/minix/servers \ - -I${NETBSDSRCDIR}/minix/fs -CPPFLAGS.dmp_kernel.c+= -I${NETBSDSRCDIR}/minix -CPPFLAGS.dmp_rs.c+= -I${NETBSDSRCDIR}/minix -CPPFLAGS.dmp_vm.c+= -I${NETBSDSRCDIR}/minix - -# This setting must match the kernel's, as it affects the IRQ hooks table size. -.if ${USE_APIC} != "no" -CFLAGS+= -DUSE_APIC -.endif - -.include diff --git a/minix/servers/mib/Makefile b/minix/servers/mib/Makefile deleted file mode 100644 index 6b482b5da..000000000 --- a/minix/servers/mib/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile for the Management Information Base (MIB) server - -.include - -.if !empty(DBG:M-Og) || !empty(CFLAGS:M-Og) || \ - !empty(DBG:M-g) || !empty(CFLAGS:M-g) -#LSC: -Wno-maybe-uninitialized while compiling with -DNDEBUG -Og -CWARNFLAGS.gcc+= -Wno-maybe-uninitialized -.endif - -PROG= mib -SRCS= main.c tree.c remote.c kern.c vm.c hw.c proc.c minix.c - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -DPADD+= ${LIBSYS} -LDADD+= -lsys - -WARNS?= 5 - -.include diff --git a/minix/servers/mib/kern.c b/minix/servers/mib/kern.c deleted file mode 100644 index 465a7ab39..000000000 --- a/minix/servers/mib/kern.c +++ /dev/null @@ -1,508 +0,0 @@ -/* MIB service - kern.c - implementation of the CTL_KERN subtree */ - -#include "mib.h" - -#include -#include -#include - -#include "servers/vfs/const.h" -#include "servers/vfs/dmap.h" - -static char hostname[MAXHOSTNAMELEN], domainname[MAXHOSTNAMELEN]; - -/* - * Verification for CTL_KERN KERN_SECURELVL. - */ -static int -mib_kern_securelvl(struct mib_call * call __unused, struct mib_node * node, - void * ptr, size_t size __unused) -{ - int v; - - memcpy(&v, ptr, sizeof(v)); - - /* - * Only ever allow the security level to be increased. This is a mock - * implementation. TODO: implement actual support for security levels. - */ - return (v >= node->node_int); -} - -/* - * Implementation of CTL_KERN KERN_CLOCKRATE. - */ -static ssize_t -mib_kern_clockrate(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - struct clockinfo clockinfo; - - memset(&clockinfo, 0, sizeof(clockinfo)); - - clockinfo.hz = sys_hz(); - clockinfo.tick = 1000000 / clockinfo.hz; - clockinfo.profhz = clockinfo.hz; - clockinfo.stathz = clockinfo.hz; - - /* - * Number of microseconds that can be corrected per clock tick through - * adjtime(2). The kernel allows correction of one clock tick per - * clock tick, which means it should be the same as .tick.. I think. - * TODO: get this from the kernel itself. - */ - clockinfo.tickadj = clockinfo.tick; - - return mib_copyout(oldp, 0, &clockinfo, sizeof(clockinfo)); -} - -/* - * Implementation of CTL_KERN KERN_PROFILING. - */ -static ssize_t -mib_kern_profiling(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp __unused, - struct mib_newp * newp __unused) -{ - - /* As per sysctl(7). We have a different profiling API. */ - return EOPNOTSUPP; -} - -/* - * Implementation of CTL_KERN KERN_HARDCLOCK_TICKS. - */ -static ssize_t -mib_kern_hardclock_ticks(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - int uptime; - - /* - * The number of hardclock (hardware clock driver) ticks is what we - * call the number of monotonic clock ticks AKA the uptime clock ticks. - */ - uptime = (int)getticks(); - - return mib_copyout(oldp, 0, &uptime, sizeof(uptime)); -} - -/* - * Implementation of CTL_KERN KERN_ROOT_DEVICE. - */ -static ssize_t -mib_kern_root_device(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - char name[PATH_MAX]; - struct sysgetenv sysgetenv; - - sysgetenv.key = __UNCONST("rootdevname"); - sysgetenv.keylen = strlen(sysgetenv.key) + 1; - sysgetenv.val = name; - sysgetenv.vallen = sizeof(name); - - if (svrctl(PMGETPARAM, &sysgetenv) != 0) - return EINVAL; - - name[MIN(sysgetenv.vallen, sizeof(name) - 1)] = '\0'; - - return mib_copyout(oldp, 0, name, strlen(name) + 1); -} - -/* - * Implementation of CTL_KERN KERN_CCPU. - */ -static ssize_t -mib_kern_ccpu(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - int ccpu; - - ccpu = (int)cpuavg_getccpu(); - - return mib_copyout(oldp, 0, &ccpu, sizeof(ccpu)); -} - -/* - * Implementation of CTL_KERN KERN_CP_TIME. - */ -static ssize_t -mib_kern_cp_time(struct mib_call * call, struct mib_node * node __unused, - struct mib_oldp * oldp, struct mib_newp * newp __unused) -{ - uint64_t ticks[MINIX_CPUSTATES], sum[MINIX_CPUSTATES]; - unsigned int cpu; - int i, r, do_sum; - - /* - * If a subnode is provided, it identifies the CPU number for which to - * return information. If no subnode is provided, but a size is given - * that allows returning information for all CPUs, return information - * for all of them in an array. If no such size is given either, - * return a summation of all CPU statistics. Both we and the kernel - * are considering the number of configured CPUs (hw.ncpu). - */ - if (call->call_namelen > 1) - return EINVAL; - - if (call->call_namelen == 1) { - /* Do not bother saving on this call if oldp is NULL. */ - if ((r = sys_getcputicks(ticks, call->call_name[0])) != OK) - return r; - - return mib_copyout(oldp, 0, ticks, sizeof(ticks)); - } - - if (oldp == NULL) - return sizeof(ticks); /* implying a summation request */ - - do_sum = (mib_getoldlen(oldp) == sizeof(ticks)); - - if (do_sum) - memset(&sum, 0, sizeof(sum)); - - for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) { - if ((r = sys_getcputicks(ticks, cpu)) != OK) - return r; - - if (do_sum) { - for (i = 0; i < MINIX_CPUSTATES; i++) - sum[i] += ticks[i]; - } else { - if ((r = mib_copyout(oldp, cpu * sizeof(ticks), ticks, - sizeof(ticks))) < 0) - return r; - } - } - - if (do_sum) - return mib_copyout(oldp, 0, sum, sizeof(sum)); - else - return cpu * sizeof(ticks); -} - -/* - * Implementation of CTL_KERN KERN_CONSDEV. - */ -static ssize_t -mib_kern_consdev(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - dev_t dev; - - dev = makedev(TTY_MAJOR, CONS_MINOR); - - /* No support for legacy 32-bit requests. */ - return mib_copyout(oldp, 0, &dev, sizeof(dev)); -} - -/* - * Verification for CTL_KERN KERN_FORKFSLEEP. - */ -static int -mib_kern_forkfsleep(struct mib_call * call __unused, - struct mib_node * node __unused, void * ptr, size_t size __unused) -{ - int v; - - memcpy(&v, ptr, sizeof(v)); - - return (v >= 0 && v <= MAXSLP * 1000); /* rules from NetBSD */ -} - -/* - * Implementation of CTL_KERN KERN_DRIVERS. - */ -static ssize_t -mib_kern_drivers(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - struct dmap dmap_tab[NR_DEVICES]; - struct kinfo_drivers drivers[NR_DEVICES + 1]; - unsigned int count; - devmajor_t maj; - - /* - * On MINIX3, we list only drivers that are actually running. - */ - - if (getsysinfo(VFS_PROC_NR, SI_DMAP_TAB, dmap_tab, - sizeof(dmap_tab)) != OK) - return EINVAL; - - count = 0; - - /* - * Compatibility hack. NetBSD userland expects that the name of the - * PTY driver is "pts". Add an extra entry for this purpose if needed. - */ - if (dmap_tab[PTY_MAJOR].dmap_driver != NONE && - strcmp(dmap_tab[PTY_MAJOR].dmap_label, "pts")) { - if (mib_inrange(oldp, 0)) { - memset(&drivers[0], 0, sizeof(drivers[0])); - strlcpy(drivers[count].d_name, "pts", - sizeof(drivers[0].d_name)); - drivers[count].d_bmajor = -1; - drivers[count].d_cmajor = PTY_MAJOR; - } - count++; - } - - for (maj = 0; maj < NR_DEVICES; maj++) { - if (dmap_tab[maj].dmap_driver == NONE) - continue; - - if (mib_inrange(oldp, sizeof(drivers[0]) * count)) { - memset(&drivers[count], 0, sizeof(drivers[0])); - - strlcpy(drivers[count].d_name, - dmap_tab[maj].dmap_label, - sizeof(drivers[0].d_name)); - - /* - * We do not know whether the device is a block device, - * character device, or both. In any case, a driver - * has only one major number. - */ - drivers[count].d_bmajor = maj; - drivers[count].d_cmajor = maj; - } - count++; - } - - return mib_copyout(oldp, 0, drivers, count * sizeof(drivers[0])); -} - -/* - * Implementation of CTL_KERN KERN_BOOTTIME. - */ -static ssize_t -mib_kern_boottime(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - struct timeval tv; - - memset(&tv, 0, sizeof(tv)); - - if (getuptime(NULL, NULL, &tv.tv_sec) != OK) - return EINVAL; - - return mib_copyout(oldp, 0, &tv, sizeof(tv)); -} - -/* - * Mock implementation of CTL_KERN KERN_SYSVIPC KERN_SYSVIPC_INFO. Normally, - * the IPC service overrides the entire "kern.ipc" subtree. Therefore, this - * function will only ever be called when the IPC service is *not* running. - */ -static ssize_t -mib_kern_ipc_info(struct mib_call * call, struct mib_node * node __unused, - struct mib_oldp * oldp __unused, struct mib_newp * newp __unused) -{ - - /* The caller must always specify the resouce type (sem/shm/msg). */ - if (call->call_namelen != 1) - return EINVAL; - - return EOPNOTSUPP; -} - -/* The CTL_KERN KERN_SYSVIPC nodes, when not overridden by the IPC service. */ -static struct mib_node mib_kern_ipc_table[] = { -/* 1*/ [KERN_SYSVIPC_INFO] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0, - mib_kern_ipc_info, "sysvipc_info", - "System V style IPC information"), -/* 2*/ [KERN_SYSVIPC_MSG] = MIB_INT(_P | _RO, 0, "sysvmsg", "System V " - "style message support available"), -/* 3*/ [KERN_SYSVIPC_SEM] = MIB_INT(_P | _RO, 0, "sysvsem", "System V " - "style semaphore support available"), -/* 4*/ [KERN_SYSVIPC_SHM] = MIB_INT(_P | _RO, 0, "sysvshm", "System V " - "style shared memory support available"), -}; - -/* The CTL_KERN nodes. */ -static struct mib_node mib_kern_table[] = { -/* 1*/ [KERN_OSTYPE] = MIB_STRING(_P | _RO, OS_NAME, "ostype", - "Operating system type"), -/* 2*/ [KERN_OSRELEASE] = MIB_STRING(_P | _RO, OS_RELEASE, "osrelease", - "Operating system release"), -/* 3*/ [KERN_OSREV] = MIB_INT(_P | _RO , OS_REV, "osrevision", - "Operating system revision"), -/* 4*/ [KERN_VERSION] = MIB_STRING(_P | _RO, OS_VERSION, "version", - "Kernel version"), -/* 5*/ [KERN_MAXVNODES] = MIB_INT(_P | _RO, NR_VNODES, "maxvnodes", - "Maximum number of vnodes"), -/* 6*/ [KERN_MAXPROC] = MIB_INT(_P | _RO, NR_PROCS, "maxproc", - "Maximum number of simultaneous " - "processes"), -/* 7*/ [KERN_MAXFILES] = MIB_INT(_P | _RO, NR_VNODES, "maxfiles", - "Maximum number of open files"), -/* 8*/ [KERN_ARGMAX] = MIB_INT(_P | _RO, ARG_MAX, "argmax", - "Maximum number of bytes of arguments to " - "execve(2)"), -/* 9*/ [KERN_SECURELVL] = MIB_INTV(_P | _RW, -1, mib_kern_securelvl, - "securelevel", "System security level"), -/*10*/ [KERN_HOSTNAME] = MIB_STRING(_P | _RW, hostname, "hostname", - "System hostname"), -/*11*/ [KERN_HOSTID] = MIB_INT(_P | _RW | CTLFLAG_HEX, 0, "hostid", - "System host ID number"), -/*12*/ [KERN_CLOCKRATE] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, - sizeof(struct clockinfo), - mib_kern_clockrate, "clockrate", - "Kernel clock rates"), -/*13*/ /* KERN_VNODE: not yet implemented */ -/*14*/ /* KERN_PROC: not yet implemented */ -/*15*/ /* KERN_FILE: not yet implemented */ -/*16*/ [KERN_PROF] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0, - mib_kern_profiling, "profiling", - "Profiling information (not available)"), -/*17*/ [KERN_POSIX1] = MIB_INT(_P | _RO, _POSIX_VERSION, - "posix1version", "Version of ISO/IEC 9945 " - "(POSIX 1003.1) with which the operating " - "system attempts to comply"), -/*18*/ [KERN_NGROUPS] = MIB_INT(_P | _RO, NGROUPS_MAX, "ngroups", - "Maximum number of supplemental groups"), -/*19*/ [KERN_JOB_CONTROL] = MIB_INT(_P | _RO, 0, "job_control", - "Whether job control is available"), -/*20*/ [KERN_SAVED_IDS] = MIB_INT(_P | _RO, 0, "saved_ids", - "Whether POSIX saved set-group/user ID is " - "available"), -/*21*/ /* KERN_OBOOTTIME: obsolete */ -/*22*/ [KERN_DOMAINNAME] = MIB_STRING(_P | _RW, domainname, - "domainname", "YP domain name"), -/*23*/ [KERN_MAXPARTITIONS] = MIB_INT(_P | _RO, NR_PARTITIONS, - "maxpartitions", "Maximum number of " - "partitions allowed per disk"), -/*24*/ /* KERN_RAWPARTITION: incompatible with our device node scheme */ -/*25*/ /* KERN_NTPTIME: not yet supported */ -/*26*/ /* KERN_TIMEX: not yet supported */ -/*27*/ /* KERN_AUTONICETIME: not yet supported */ -/*28*/ /* KERN_AUTONICEVAL: not yet supported */ -/*29*/ [KERN_RTC_OFFSET] = MIB_INT(_P | _RW, 0, "rtc_offset", "Offset " - "of real time clock from UTC in minutes"), -/*30*/ [KERN_ROOT_DEVICE] = MIB_FUNC(_P | _RO | CTLTYPE_STRING, 0, - mib_kern_root_device, "root_device", - "Name of the root device"), -/*31*/ [KERN_MSGBUFSIZE] = MIB_INT(_P | _RO, DIAG_BUFSIZE, "msgbufsize", - "Size of the kernel message buffer"), -/*32*/ [KERN_FSYNC] = MIB_INT(_P | _RO, 1, "fsync", "Whether the " - "POSIX 1003.1b File Synchronization Option" - " is available on this system"), -/*33*/ /* KERN_OLDSYSVMSG: obsolete */ -/*34*/ /* KERN_OLDSYSVSEM: obsolete */ -/*35*/ /* KERN_OLDSYSVSHM: obsolete */ -/*36*/ /* KERN_OLDSHORTCORENAME: obsolete */ -/*37*/ [KERN_SYNCHRONIZED_IO] = MIB_INT(_P | _RO, 0, "synchronized_io", - "Whether the POSIX 1003.1b Synchronized " - "I/O Option is available on this system"), -/*38*/ [KERN_IOV_MAX] = MIB_INT(_P | _RO, IOV_MAX, "iov_max", - "Maximum number of iovec structures per " - "process"), -/*39*/ /* KERN_MBUF: not yet supported */ -/*40*/ [KERN_MAPPED_FILES] = MIB_INT(_P | _RO, 1, "mapped_files", - "Whether the POSIX 1003.1b Memory Mapped " - "Files Option is available on this " - "system"), -/*41*/ [KERN_MEMLOCK] = MIB_INT(_P | _RO, 0, "memlock", "Whether " - "the POSIX 1003.1b Process Memory Locking " - "Option is available on this system"), -/*42*/ [KERN_MEMLOCK_RANGE] = MIB_INT(_P | _RO, 0, "memlock_range", - "Whether the POSIX 1003.1b Range Memory " - "Locking Option is available on this " - "system"), -/*43*/ [KERN_MEMORY_PROTECTION]= MIB_INT(_P | _RO, 0, "memory_protection", - "Whether the POSIX 1003.1b Memory " - "Protection Option is available on this " - "system"), -/*44*/ /* KERN_LOGIN_NAME_MAX: not yet supported */ -/*45*/ /* KERN_DEFCORENAME: obsolete */ -/*46*/ /* KERN_LOGSIGEXIT: not yet supported */ -/*47*/ [KERN_PROC2] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0, - mib_kern_proc2, "proc2", - "Machine-independent process information"), -/*48*/ [KERN_PROC_ARGS] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0, - mib_kern_proc_args, "proc_args", - "Process argument information"), -/*49*/ [KERN_FSCALE] = MIB_INT(_P | _RO, FSCALE, "fscale", - "Kernel fixed-point scale factor"), -/*50*/ [KERN_CCPU] = MIB_FUNC(_P | _RO | CTLTYPE_INT, sizeof(int), - mib_kern_ccpu, "ccpu", - "Scheduler exponential decay value"), -/*51*/ [KERN_CP_TIME] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0, - mib_kern_cp_time, "cp_time", "Clock ticks " - "spent in different CPU states"), -/*52*/ /* KERN_OLDSYSVIPC_INFO: obsolete */ -/*53*/ /* KERN_MSGBUF: not yet supported */ -/*54*/ [KERN_CONSDEV] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, - sizeof(dev_t), mib_kern_consdev, "consdev", - "Console device"), -/*55*/ [KERN_MAXPTYS] = MIB_INT(_P | _RO, NR_PTYS, "maxptys", - "Maximum number of pseudo-ttys"), -/*56*/ /* KERN_PIPE: not yet supported */ -/*57*/ [KERN_MAXPHYS] = MIB_INT(_P | _RO, 4*1024*1024, "maxphys", - "Maximum raw I/O transfer size"), - /* 4MB is the upper limit for AHCI */ -/*58*/ /* KERN_SBMAX: not yet supported */ -/*59*/ /* KERN_TKSTAT: not yet supported */ -/*60*/ [KERN_MONOTONIC_CLOCK] = MIB_INT(_P | _RO, _POSIX_MONOTONIC_CLOCK, - "monotonic_clock", - "Implementation version of the POSIX " - "1003.1b Monotonic Clock Option"), -/*61*/ /* KERN_URND: not yet supported */ -/*62*/ /* KERN_LABELSECTOR: not yet supported */ -/*63*/ /* KERN_LABELOFFSET: not yet supported */ -/*64*/ [KERN_LWP] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0, - mib_kern_lwp, "lwp", - "System-wide LWP information"), -/*65*/ [KERN_FORKFSLEEP] = MIB_INTV(_P | _RW, 0, mib_kern_forkfsleep, - "forkfsleep", "Milliseconds to sleep on " - "fork failure due to process limits"), -/*66*/ /* KERN_POSIX_THREADS: not yet supported */ -/*67*/ /* KERN_POSIX_SEMAPHORES: not yet supported */ -/*68*/ /* KERN_POSIX_BARRIERS: not yet supported */ -/*69*/ /* KERN_POSIX_TIMERS: not yet supported */ -/*70*/ /* KERN_POSIX_SPIN_LOCKS: not yet supported */ -/*71*/ /* KERN_POSIX_READER_WRITER_LOCKS: not yet supported */ -/*72*/ [KERN_DUMP_ON_PANIC] = MIB_INT(_P | _RO, 0, "dump_on_panic", - "Perform a crash dump on system panic"), -/*73*/ /* KERN_SOMAXKVA: not yet supported */ -/*74*/ /* KERN_ROOT_PARTITION: incompatible with our device node scheme */ -/*75*/ [KERN_DRIVERS] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, 0, - mib_kern_drivers, "drivers", - "List of all drivers with block and " - "character device numbers"), -/*76*/ /* KERN_BUF: not yet supported */ -/*77*/ /* KERN_FILE2: not yet supported */ -/*78*/ /* KERN_VERIEXEC: not yet supported */ -/*79*/ /* KERN_CP_ID: not yet supported */ -/*80*/ [KERN_HARDCLOCK_TICKS] = MIB_FUNC(_P | _RO | CTLFLAG_UNSIGNED | - CTLTYPE_INT, sizeof(int), - mib_kern_hardclock_ticks, - "hardclock_ticks", - "Number of hardclock ticks"), -/*81*/ /* KERN_ARND: not yet supported */ -/*82*/ [KERN_SYSVIPC] = MIB_NODE(_P | _RO, mib_kern_ipc_table, "ipc", - "SysV IPC options"), -/*83*/ [KERN_BOOTTIME] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, - sizeof(struct timeval), mib_kern_boottime, - "boottime", "System boot time"), -/*84*/ /* KERN_EVCNT: not yet supported */ -}; - -/* - * Initialize the CTL_KERN subtree. - */ -void -mib_kern_init(struct mib_node * node) -{ - - MIB_INIT_ENODE(node, mib_kern_table); -} diff --git a/minix/servers/mib/main.c b/minix/servers/mib/main.c deleted file mode 100644 index 51d7492e9..000000000 --- a/minix/servers/mib/main.c +++ /dev/null @@ -1,492 +0,0 @@ -/* MIB service - main.c - request abstraction and first-level tree */ -/* - * This is the Management Information Base (MIB) service. Its one and only - * task is to implement the sysctl(2) system call, which plays a fairly - * important role in parts of *BSD userland. - * - * The sysctl(2) interface is used to access a variety of information. In - * order to obtain that information, and possibly modify it, the MIB service - * calls into many other services. The MIB service must therefore not be - * called directly from other services, with the exception of ProcFS. In fact, - * ProcFS is currently the only service that is modeled as logically higher in - * the MINIX3 service stack than MIB, something that itself is possible only - * due to the nonblocking nature of VFS. MIB may issue blocking calls to VFS. - * - * The MIB service is in the boot image because even init(8) makes use of - * sysctl(2) during its own startup, so launching the MIB service at any later - * time would make a proper implementation of sysctl(2) impossible. Also, the - * service needs superuser privileges because it may need to issue privileged - * calls and obtain privileged information from other services. - * - * While most of the sysctl tree is maintained locally, the MIB service also - * allows other services to register "remote" subtrees which are then handled - * entirely by those services. This feature, which works much like file system - * mounting, allows 1) sysctl handling code to stay local to its corresponding - * service, and 2) parts of the sysctl tree to adapt and expand dynamically as - * optional services are started and stopped. Compared to the MIB service's - * local handling, remotely handled subtrees are subject to several additional - * practical restrictions, hoever. In the current implementation, the MIB - * service makes blocking calls to remote services as needed; in the future, - * these interactions could be made (more) asynchronous. - * - * The MIB service was created by David van Moolenbroek . - */ - -#include "mib.h" - -/* - * Most of these initially empty nodes are filled in by their corresponding - * modules' _init calls; see mib_init below. However, some subtrees are not - * populated by the MIB service itself. CTL_NET is expected to be populated - * through registration of remote subtrees. The libc sysctl(3) wrapper code - * takes care of the CTL_USER subtree. It must have an entry here though, or - * sysctl(8) will not list it. CTL_VENDOR is also empty, but writable, so that - * it may be used by third parties. - */ -static struct mib_node mib_table[] = { -/* 1*/ [CTL_KERN] = MIB_ENODE(_P | _RO, "kern", "High kernel"), -/* 2*/ [CTL_VM] = MIB_ENODE(_P | _RO, "vm", "Virtual memory"), -/* 4*/ [CTL_NET] = MIB_ENODE(_P | _RO, "net", "Networking"), -/* 6*/ [CTL_HW] = MIB_ENODE(_P | _RO, "hw", "Generic CPU, I/O"), -/* 8*/ [CTL_USER] = MIB_ENODE(_P | _RO, "user", "User-level"), -/*11*/ [CTL_VENDOR] = MIB_ENODE(_P | _RW, "vendor", "Vendor specific"), -/*32*/ [CTL_MINIX] = MIB_ENODE(_P | _RO, "minix", "MINIX3 specific"), -}; - -/* - * The root node of the tree. The root node is used internally only--it is - * impossible to access the root node itself from userland in any way. The - * node is writable by default, so that programs such as init(8) may create - * their own top-level entries. - */ -struct mib_node mib_root = MIB_NODE(_RW, mib_table, "", ""); - -/* - * Structures describing old and new data as provided by userland. The primary - * advantage of these opaque structures is that we could in principle use them - * to implement storage of small data results in the sysctl reply message, so - * as to avoid the kernel copy, without changing any of the handler code. - */ -struct mib_oldp { - endpoint_t oldp_endpt; - vir_bytes oldp_addr; - size_t oldp_len; -}; -/* - * Same structure, different type: prevent accidental mixups, and avoid the - * need to use __restrict everywhere. - */ -struct mib_newp { - endpoint_t newp_endpt; - vir_bytes newp_addr; - size_t newp_len; -}; - -/* - * Return TRUE or FALSE indicating whether the given offset is within the range - * of data that is to be copied out. This call can be used to test whether - * certain bits of data need to be prepared for copying at all. - */ -int -mib_inrange(struct mib_oldp * oldp, size_t off) -{ - - if (oldp == NULL) - return FALSE; - - return (off < oldp->oldp_len); -} - -/* - * Return the total length of the requested data. This should not be used - * directly except in highly unusual cases, such as particular node requests - * where the request semantics blatantly violate overall sysctl(2) semantics. - */ -size_t -mib_getoldlen(struct mib_oldp * oldp) -{ - - if (oldp == NULL) - return 0; - - return oldp->oldp_len; -} - -/* - * Copy out (partial) data to the user. The copy is automatically limited to - * the range of data requested by the user. Return the requested length on - * success (for the caller's convenience) or an error code on failure. - */ -ssize_t -mib_copyout(struct mib_oldp * __restrict oldp, size_t off, - const void * __restrict buf, size_t size) -{ - size_t len; - int r; - - len = size; - assert(len <= SSIZE_MAX); - - if (oldp == NULL || off >= oldp->oldp_len) - return size; /* nothing to do */ - - if (len > oldp->oldp_len - off) - len = oldp->oldp_len - off; - - if ((r = sys_datacopy(SELF, (vir_bytes)buf, oldp->oldp_endpt, - oldp->oldp_addr + off, len)) != OK) - return r; - - return size; -} - -/* - * Override the oldlen value returned from the call, in situations where an - * error is thrown as well. - */ -void -mib_setoldlen(struct mib_call * call, size_t oldlen) -{ - - call->call_reslen = oldlen; -} - -/* - * Return the new data length as provided by the user, or 0 if the user did not - * supply new data. - */ -size_t -mib_getnewlen(struct mib_newp * newp) -{ - - if (newp == NULL) - return 0; - - return newp->newp_len; -} - -/* - * Copy in data from the user. The given length must match exactly the length - * given by the user. Return OK or an error code. - */ -int -mib_copyin(struct mib_newp * __restrict newp, void * __restrict buf, - size_t len) -{ - - if (newp == NULL || len != newp->newp_len) - return EINVAL; - - if (len == 0) - return OK; - - return sys_datacopy(newp->newp_endpt, newp->newp_addr, SELF, - (vir_bytes)buf, len); -} - -/* - * Copy in auxiliary data from the user, based on a user pointer obtained from - * data copied in earlier through mib_copyin(). - */ -int -mib_copyin_aux(struct mib_newp * __restrict newp, vir_bytes addr, - void * __restrict buf, size_t len) -{ - - assert(newp != NULL); - - if (len == 0) - return OK; - - return sys_datacopy(newp->newp_endpt, addr, SELF, (vir_bytes)buf, len); -} - -/* - * Create a grant for a call's old data region, if not NULL, for the given - * endpoint. On success, store the grant (or GRANT_INVALID) in grantp and the - * length in lenp, and return OK. On error, return an error code that must not - * be ENOMEM. - */ -int -mib_relay_oldp(endpoint_t endpt, struct mib_oldp * __restrict oldp, - cp_grant_id_t * grantp, size_t * __restrict lenp) -{ - - if (oldp != NULL) { - *grantp = cpf_grant_magic(endpt, oldp->oldp_endpt, - oldp->oldp_addr, oldp->oldp_len, CPF_WRITE); - if (!GRANT_VALID(*grantp)) - return EINVAL; - *lenp = oldp->oldp_len; - } else { - *grantp = GRANT_INVALID; - *lenp = 0; - } - - return OK; -} - -/* - * Create a grant for a call's new data region, if not NULL, for the given - * endpoint. On success, store the grant (or GRANT_INVALID) in grantp and the - * length in lenp, and return OK. On error, return an error code that must not - * be ENOMEM. - */ -int -mib_relay_newp(endpoint_t endpt, struct mib_newp * __restrict newp, - cp_grant_id_t * grantp, size_t * __restrict lenp) -{ - - if (newp != NULL) { - *grantp = cpf_grant_magic(endpt, newp->newp_endpt, - newp->newp_addr, newp->newp_len, CPF_READ); - if (!GRANT_VALID(*grantp)) - return EINVAL; - *lenp = newp->newp_len; - } else { - *grantp = GRANT_INVALID; - *lenp = 0; - } - - return OK; -} - -/* - * Check whether the user is allowed to perform privileged operations. The - * function returns a nonzero value if this is the case, and zero otherwise. - * Authorization is performed only once per call. - */ -int -mib_authed(struct mib_call * call) -{ - - if ((call->call_flags & (MIB_FLAG_AUTH | MIB_FLAG_NOAUTH)) == 0) { - /* Ask PM if this endpoint has superuser privileges. */ - if (getnuid(call->call_endpt) == SUPER_USER) - call->call_flags |= MIB_FLAG_AUTH; - else - call->call_flags |= MIB_FLAG_NOAUTH; - } - - return (call->call_flags & MIB_FLAG_AUTH); -} - -/* - * Implement the sysctl(2) system call. - */ -static int -mib_sysctl(message * __restrict m_in, int ipc_status, - message * __restrict m_out) -{ - vir_bytes oldaddr, newaddr; - size_t oldlen, newlen; - unsigned int namelen; - int s, name[CTL_MAXNAME]; - endpoint_t endpt; - struct mib_oldp oldp, *oldpp; - struct mib_newp newp, *newpp; - struct mib_call call; - ssize_t r; - - /* Only handle blocking calls. Ignore everything else. */ - if (IPC_STATUS_CALL(ipc_status) != SENDREC) - return EDONTREPLY; - - endpt = m_in->m_source; - oldaddr = m_in->m_lc_mib_sysctl.oldp; - oldlen = m_in->m_lc_mib_sysctl.oldlen; - newaddr = m_in->m_lc_mib_sysctl.newp; - newlen = m_in->m_lc_mib_sysctl.newlen; - namelen = m_in->m_lc_mib_sysctl.namelen; - - if (namelen == 0 || namelen > CTL_MAXNAME) - return EINVAL; - - /* - * In most cases, the entire name fits in the request message, so we - * can avoid a kernel copy. - */ - if (namelen > CTL_SHORTNAME) { - if ((s = sys_datacopy(endpt, m_in->m_lc_mib_sysctl.namep, SELF, - (vir_bytes)&name, sizeof(name[0]) * namelen)) != OK) - return s; - } else - memcpy(name, m_in->m_lc_mib_sysctl.name, - sizeof(name[0]) * namelen); - - /* - * Set up a structure for the old data, if any. When no old address is - * given, be forgiving if oldlen is not zero, as the user may simply - * not have initialized the variable before passing a pointer to it. - */ - if (oldaddr != 0) { - oldp.oldp_endpt = endpt; - oldp.oldp_addr = oldaddr; - oldp.oldp_len = oldlen; - oldpp = &oldp; - } else - oldpp = NULL; - - /* - * Set up a structure for the new data, if any. If one of newaddr and - * newlen is zero but not the other, we (like NetBSD) disregard both. - */ - if (newaddr != 0 && newlen != 0) { - newp.newp_endpt = endpt; - newp.newp_addr = newaddr; - newp.newp_len = newlen; - newpp = &newp; - } else - newpp = NULL; - - /* - * Set up a structure for other call parameters. Most of these should - * be used rarely, and we may want to add more later, so do not pass - * all of them around as actual function parameters all the time. - */ - call.call_endpt = endpt; - call.call_name = name; - call.call_namelen = namelen; - call.call_flags = 0; - call.call_reslen = 0; - - r = mib_dispatch(&call, oldpp, newpp); - - /* - * From NetBSD: we copy out as much as we can from the old data, while - * at the same time computing the full data length. Then, here at the - * end, if the entire result did not fit in the destination buffer, we - * return ENOMEM instead of success, thus also returning a partial - * result and the full data length. - * - * It is also possible that data are copied out along with a "real" - * error. In that case, we must report a nonzero resulting length - * along with that error code. This is currently the case when node - * creation resulted in a collision, in which case the error code is - * EEXIST while the existing node is copied out as well. - */ - if (r >= 0) { - m_out->m_mib_lc_sysctl.oldlen = (size_t)r; - - if (oldaddr != 0 && oldlen < (size_t)r) - r = ENOMEM; - else - r = OK; - } else - m_out->m_mib_lc_sysctl.oldlen = call.call_reslen; - - return r; -} - -/* - * Initialize the service. - */ -static int -mib_init(int type __unused, sef_init_info_t * info __unused) -{ - - /* - * Initialize pointers and sizes of subtrees in different modules. - * This is needed because we cannot use sizeof on external arrays. - * We do initialize the node entry (including any other fields) - * statically through MIB_ENODE because that forces the array to be - * large enough to store the entry. - */ - mib_kern_init(&mib_table[CTL_KERN]); - mib_vm_init(&mib_table[CTL_VM]); - mib_hw_init(&mib_table[CTL_HW]); - mib_minix_init(&mib_table[CTL_MINIX]); - - /* - * Now that the static tree is complete, go through the entire tree, - * initializing miscellaneous fields. - */ - mib_tree_init(); - - /* Prepare for requests to mount remote subtrees. */ - mib_remote_init(); - - return OK; -} - -/* - * Perform SEF startup. - */ -static void -mib_startup(void) -{ - - sef_setcb_init_fresh(mib_init); - /* - * If we restart we lose all dynamic state, which means we lose all - * nodes that have been created at run time. However, running with - * only the static node tree is still better than not running at all. - */ - sef_setcb_init_restart(mib_init); - - sef_startup(); -} - -/* - * The Management Information Base (MIB) service. - */ -int -main(void) -{ - message m_in, m_out; - int r, ipc_status; - - /* Perform initialization. */ - mib_startup(); - - /* The main message loop. */ - for (;;) { - /* Receive a request. */ - if ((r = sef_receive_status(ANY, &m_in, &ipc_status)) != OK) - panic("sef_receive failed: %d", r); - - /* Process the request. */ - if (is_ipc_notify(ipc_status)) { - /* We are not expecting any notifications. */ - printf("MIB: notification from %d\n", m_in.m_source); - - continue; - } - - memset(&m_out, 0, sizeof(m_out)); - - switch (m_in.m_type) { - case MIB_SYSCTL: - r = mib_sysctl(&m_in, ipc_status, &m_out); - - break; - - case MIB_REGISTER: - r = mib_register(&m_in, ipc_status); - - break; - - case MIB_DEREGISTER: - r = mib_deregister(&m_in, ipc_status); - - break; - - default: - if (IPC_STATUS_CALL(ipc_status) == SENDREC) - r = ENOSYS; - else - r = EDONTREPLY; - } - - /* Send a reply, if applicable. */ - if (r != EDONTREPLY) { - m_out.m_type = r; - - if ((r = ipc_sendnb(m_in.m_source, &m_out)) != OK) - printf("MIB: ipc_sendnb failed (%d)\n", r); - } - } - - /* NOTREACHED */ - return 0; -} diff --git a/minix/servers/mib/mib.h b/minix/servers/mib/mib.h deleted file mode 100644 index 413a109cc..000000000 --- a/minix/servers/mib/mib.h +++ /dev/null @@ -1,390 +0,0 @@ -#ifndef _MINIX_MIB_MIB_H -#define _MINIX_MIB_MIB_H - -#include -#include -#include -#include - -#if defined(__i386__) -#include "kernel/arch/i386/include/archconst.h" -#endif - -#ifndef CONFIG_MAX_CPUS -#define CONFIG_MAX_CPUS 1 -#endif - -/* - * The following setting toggles the existence of the minix.test subtree. For - * production environments, it should probably be disabled, although it should - * do no harm either. For development platforms, it should be enabled, or - * test87 will fail. - */ -#define MINIX_TEST_SUBTREE 1 /* include the minix.test subtree? */ - -/* - * By default, mount request failures will be silently discarded, because the - * requests themselves are one-way. For service authors, a bit more output may - * be helpful. Set the following defininition to "printf s" in order to - * include more information about mount requests and failures. - */ -#define MIB_DEBUG_MOUNT(s) /* printf s */ - -struct mib_oldp; -struct mib_newp; - -/* - * This structure contains a number of less heavily used parameters for handler - * functions, mainly to provide extensibility while limiting argument clutter. - */ -struct mib_call { - endpoint_t call_endpt; /* endpoint of the user process */ - const int *call_name; /* remaining part of the name */ - unsigned int call_namelen; /* length of the remaining name part */ - unsigned int call_flags; /* internal call processing flags */ - size_t call_reslen; /* resulting oldlen value on error */ -}; - -/* Call flags. */ -#define MIB_FLAG_AUTH 0x01 /* user verified to be superuser */ -#define MIB_FLAG_NOAUTH 0x02 /* user verified to be regular user */ - -/* - * We reassign new meaning to three NetBSD node flags, because we do not use - * the flags in the way NetBSD does: - * - * - On NetBSD, CTLFLAG_ROOT is used to mark the root of the sysctl tree. The - * entire root node is not exposed to userland, and thus, neither is this - * flag. We do not need the flag as we do not have parent pointers. - * - On NetBSD, CTLFLAG_ALIAS is used to mark one node as an alias of another - * node, presumably to avoid having to duplicate entire subtrees. We can - * simply have two nodes point to the same subtree instead, and thus, we do - * not need to support this functionality at all. - * - On NetBSD, CTLFLAG_MMAP is defined for future support for memory-mapping - * node data with CTL_MMAP. It is not yet clear where or why this feature - * would be used in practice. For as long as NetBSD does not actually use - * this flag *for node-type nodes*, we can reuse it for our own purposes. - * - * The meaning of our replacement flags is explained further below. We ensure - * that none of these flags are ever exposed to userland. As such, our own - * definitions can be changed as necessary without breaking anything. - */ -#define CTLFLAG_PARENT CTLFLAG_ROOT /* node is a real parent node */ -#define CTLFLAG_VERIFY CTLFLAG_ALIAS /* node has verification function */ -#define CTLFLAG_REMOTE CTLFLAG_MMAP /* node is root of remote subtree */ - -/* - * The following node structure definition aims to meet several goals at once: - * - * 1) it can be used for static and dynamic nodes; - * 2) it can be used to point to both static and dynamic child arrays at once; - * 3) it allows for embedded, pointed-to, and function-generated data; - * 4) it allows both temporary and obscuring mount points for remote subtrees; - * 5) its unions are compatible with magic instrumentation; - * 6) it is optimized for size, assuming many static and few dynamic nodes. - * - * All nodes have flags, a size, a version, a parent (except the root node), a - * name, and optionally a description. The use of the rest of the fields - * depends on the type of the node, which is defined as part of the node's - * flags field. - * - * Data nodes, that is, nodes of type CTLTYPE_{BOOL,INT,QUAD,STRING,STRUCT}, - * have associated data. For types CTLTYPE_{BOOL,INT,QUAD}, the node may have - * immediate data (CTLFLAG_IMMEDIATE), in which case the value of the node is - * stored in the node structure itself (node_bool, node_int, node_quad). These - * node types may instead also have a pointer to data. This is always the case - * for types CTLTYPE_STRING and CTLTYPE_STRUCT. In that case, node_data is a - * valid pointer, and CTLFLAG_IMMEDIATE is not set. Either way, node_size is - * the size of the data, which for strings is the maximum string size; for - * other types, it defines the exact field size. In addition, data nodes may - * have the CTLFLAG_VERIFY flag set, which indicates that node_valid points - * to a callback function that verifies whether a newly written value is valid - * for the node. If this flag is not set, data nodes may have an associated - * function, in which case node_func is not NULL, which will be called to read - * and write data instead. The function may optionally use the node's regular - * (size, immediate and/or pointer) data fields as it sees fit. - * - * Node-type nodes, of type CTLTYPE_NODE, behave differently. Such nodes may - * have static and dynamic child nodes, or have an associated function, or be - * a mount point for a subtree handled by a remote process. The exact case is - * defined by the combination of the CTLFLAG_PARENT and CTLFLAG_REMOTE flags, - * yielding four possible cases: - * - * CTLFLAG_PARENT CTLFLAG_REMOTE Meaning - * not set not set The node has an associated function which - * handles all access to the entire subtree. - * set not set The node is the root of a real, local - * subtree with static and/or dynamic children. - * not set set The node is a temporarily created mount - * point for a remote tree. A remote service - * handles all access to the entire subtree. - * Unmounting the node also destroys the node. - * set set The node is a mount point that obscures a - * real, local subtree. A remote service - * handles all access to the entire subtree. - * Unmounting makes the original node visible. - * - * If the CTLFLAG_PARENT flag is set, the node is the root of a real sutree. - * For such nodes, node_size is the number (not size!) of the array of static - * child nodes, which is pointed to by node_scptr and indexed by child - * identifier. Within the static array, child nodes with zeroed flags fields - * are not in use. The node_dcptr field points to a linked list of dynamic - * child nodes. The node_csize field is set to the size of the static array - * plus the number of dynamic nodes; node_clen is set to the number of valid - * entries in the static array plus the number of dynamic nodes. - * - * If a function is set, and thus neither CTLFLAG_PARENT and CTLFLAG_REMOTE are - * set, none of the aforementioned fields are used, and the node_size field is - * typically (but not necessarily) set to zero. - * - * A remote service can mount its own subtree into the central MIB tree. The - * MIB service will then relay any requests for that subtree to the remote - * service. Both the mountpoint and the root of the remote subtree must be of - * type CTLTYPE_NODE; thus, no individual leaf nodes may be mounted. The mount - * point may either be created temporarily for the purpose of mounting (e.g., - * net.inet), or it may override a preexisting node (e.g., kern.ipc). In the - * first case, the parent node must exist and be a node type (net). In the - * second case, the preexisting target node (the MIB service's kern.ipc) may - * not have an associated function and may only have static children. While - * being used as a mountpoint (i.e., have CTLFLAG_REMOTE set), the local node's - * node_csize and node_clen fields must not be used. Instead, the same space - * in the node structure is used to store information about the remote node: - * node_rid, node_tid, and the smaller node_rcsize and node_rclen which contain - * information about the root of the remote subtree. Remote nodes are also - * part of a linked list for administration purposes, using the node_next - * field. When a preexisting (CTLFLAG_PARENT) node is unmounted, its original - * node_csize and node_clen fields are recomputed. - * - * The structure uses unions for either only pointers or only non-pointers, to - * simplify live update support. However, this does not mean the structure is - * not fully used: real node-type nodes use node_{flags,size,ver,parent,csize, - * clen,scptr,dcptr,name,desc}, which together add up to the full structure - * size. - */ -struct mib_node; -struct mib_dynode; - -typedef ssize_t (*mib_func_ptr)(struct mib_call *, struct mib_node *, - struct mib_oldp *, struct mib_newp *); -typedef int (*mib_verify_ptr)(struct mib_call *, struct mib_node *, void *, - size_t); - -/* - * To save space for the maintenance of remote nodes, we split up one uint32_t - * field into three subfields: - * - node_eid ("endpoint ID"), which is an index into the table of endpoints; - * - node_rcsize ("child size"), the number of child slots of the remote root; - * - node_rclen ("child length"), the number of children of the remote root. - * These fields impose limits on the number of endpoints known in the MIB - * service, and the maximum size of the remote subtree root. - */ -#define MIB_EID_BITS 5 /* up to 32 services can set remote subtrees */ -#define MIB_RC_BITS 12 /* remote root may have up to 4096 children */ - -#if MIB_EID_BITS + 2 * MIB_RC_BITS > 32 -#error "Sum of remote ID and remote children bit fields exceeds uint32_t size" -#endif - -struct mib_node { - uint32_t node_flags; /* CTLTYPE_ type and CTLFLAG_ flags */ - size_t node_size; /* size of associated data (bytes) */ - uint32_t node_ver; /* node version */ - struct mib_node *node_parent; /* pointer to parent node */ - union ixfer_node_val_u { - struct { - uint32_t nvuc_csize; /* number of child slots */ - uint32_t nvuc_clen; /* number of actual children */ - } nvu_child; - struct { - uint32_t nvur_eid:MIB_EID_BITS; /* endpoint index */ - uint32_t nvur_csize:MIB_RC_BITS;/* remote ch. slots */ - uint32_t nvur_clen:MIB_RC_BITS; /* remote children */ - uint32_t nvur_rid; /* opaque ID of remote root */ - } nvu_remote; - bool nvu_bool; /* immediate boolean */ - int nvu_int; /* immediate integer */ - u_quad_t nvu_quad; /* immediate quad */ - } node_val_u; - union pxfer_node_ptr_u { - void *npu_data; /* struct or string data pointer */ - struct mib_node *npu_scptr; /* static child node array */ - } node_ptr_u; - union pxfer_node_aux_u { - struct mib_dynode *nau_dcptr; /* dynamic child node list */ - mib_func_ptr nau_func; /* handler function */ - mib_verify_ptr nau_verify; /* verification function */ - struct mib_node *nau_next; /* next remote node in list */ - } node_aux_u; - const char *node_name; /* node name string */ - const char *node_desc; /* node description (may be NULL) */ -}; -#define node_csize node_val_u.nvu_child.nvuc_csize -#define node_clen node_val_u.nvu_child.nvuc_clen -#define node_eid node_val_u.nvu_remote.nvur_eid -#define node_rcsize node_val_u.nvu_remote.nvur_csize -#define node_rclen node_val_u.nvu_remote.nvur_clen -#define node_rid node_val_u.nvu_remote.nvur_rid -#define node_bool node_val_u.nvu_bool -#define node_int node_val_u.nvu_int -#define node_quad node_val_u.nvu_quad -#define node_data node_ptr_u.npu_data -#define node_scptr node_ptr_u.npu_scptr -#define node_dcptr node_aux_u.nau_dcptr -#define node_func node_aux_u.nau_func -#define node_verify node_aux_u.nau_verify -#define node_next node_aux_u.nau_next - -/* - * This structure is used for dynamically allocated nodes, that is, nodes - * created by userland at run time. It contains not only the fields below, but - * also the full name and, for leaf nodes with non-immediate data, the actual - * data area, or, for temporary mount points for remote subtrees, the node's - * description. - */ -struct mib_dynode { - struct mib_dynode *dynode_next; /* next in linked dynamic node list */ - int dynode_id; /* identifier of this node */ - struct mib_node dynode_node; /* actual node */ - char dynode_name[1]; /* node name data (variable size) */ -}; - -/* Static node initialization macros. */ -#define MIB_NODE(f,t,n,d) { \ - .node_flags = CTLTYPE_NODE | CTLFLAG_PARENT | f, \ - .node_size = __arraycount(t), \ - .node_scptr = t, \ - .node_name = n, \ - .node_desc = d \ -} -#define MIB_ENODE(f,n,d) { /* "E"mpty or "E"xternal */ \ - .node_flags = CTLTYPE_NODE | CTLFLAG_PARENT | f, \ - .node_name = n, \ - .node_desc = d \ -} -#define MIB_BOOL(f,b,n,d) { \ - .node_flags = CTLTYPE_BOOL | CTLFLAG_IMMEDIATE | f, \ - .node_size = sizeof(bool), \ - .node_bool = b, \ - .node_name = n, \ - .node_desc = d \ -} -#define MIB_INT(f,i,n,d) { \ - .node_flags = CTLTYPE_INT | CTLFLAG_IMMEDIATE | f, \ - .node_size = sizeof(int), \ - .node_int = i, \ - .node_name = n, \ - .node_desc = d \ -} -#define MIB_QUAD(f,q,n,d) { \ - .node_flags = CTLTYPE_QUAD | CTLFLAG_IMMEDIATE | f, \ - .node_size = sizeof(u_quad_t), \ - .node_quad = q, \ - .node_name = n, \ - .node_desc = d \ -} -#define _MIB_DATA(f,s,p,n,d) { \ - .node_flags = f, \ - .node_size = s, \ - .node_data = __UNCONST(p), \ - .node_name = n, \ - .node_desc = d \ -} -#define MIB_BOOLPTR(f,p,n,d) _MIB_DATA(CTLTYPE_BOOL | f, sizeof(*p), p, n, d) -#define MIB_INTPTR(f,p,n,d) _MIB_DATA(CTLTYPE_INT | f, sizeof(*p), p, n, d) -#define MIB_QUADTR(f,p,n,d) _MIB_DATA(CTLTYPE_QUAD | f, sizeof(*p), p, n, d) -#define MIB_STRING(f,p,n,d) _MIB_DATA(CTLTYPE_STRING | f, sizeof(p), p, n, d) -#define MIB_STRUCT(f,s,p,n,d) _MIB_DATA(CTLTYPE_STRUCT | f, s, p, n, d) -#define MIB_FUNC(f,s,fp,n,d) { \ - .node_flags = f, \ - .node_size = s, \ - .node_func = fp, \ - .node_name = n, \ - .node_desc = d \ -} -#define MIB_INTV(f,i,vp,n,d) { \ - .node_flags = CTLTYPE_INT | CTLFLAG_IMMEDIATE | \ - CTLFLAG_VERIFY | f, \ - .node_size = sizeof(int), \ - .node_int = i, \ - .node_verify = vp, \ - .node_name = n, \ - .node_desc = d \ -} - -/* Finalize a node initialized with MIB_ENODE. */ -#define MIB_INIT_ENODE(n,t) \ -do { \ - (n)->node_size = __arraycount(t); \ - (n)->node_scptr = t; \ -} while (0) - -/* Some convenient shortcuts for highly common flags. */ -#define _RO CTLFLAG_READONLY -#define _RW CTLFLAG_READWRITE -#define _P CTLFLAG_PERMANENT - -/* - * If this check fails, all uses of "struct sysctlnode" and "struct sysctldesc" - * need to be revised, and translation between different versions of those - * structures may have to be added for backward compatibility. - */ -#if SYSCTL_VERSION != SYSCTL_VERS_1 -#error "NetBSD sysctl headers are ahead of our implementation" -#endif - -/* main.c */ -int mib_inrange(struct mib_oldp *, size_t); -size_t mib_getoldlen(struct mib_oldp *); -ssize_t mib_copyout(struct mib_oldp *, size_t, const void * __restrict, - size_t); -void mib_setoldlen(struct mib_call *, size_t); -size_t mib_getnewlen(struct mib_newp *); -int mib_copyin(struct mib_newp * __restrict, void * __restrict, size_t); -int mib_copyin_aux(struct mib_newp * __restrict, vir_bytes, - void * __restrict, size_t); -int mib_relay_oldp(endpoint_t, struct mib_oldp * __restrict, cp_grant_id_t *, - size_t * __restrict); -int mib_relay_newp(endpoint_t, struct mib_newp * __restrict, cp_grant_id_t *, - size_t * __restrict); -int mib_authed(struct mib_call *); -extern struct mib_node mib_root; - -/* tree.c */ -ssize_t mib_readwrite(struct mib_call *, struct mib_node *, struct mib_oldp *, - struct mib_newp *, mib_verify_ptr); -ssize_t mib_dispatch(struct mib_call *, struct mib_oldp *, struct mib_newp *); -void mib_tree_init(void); -int mib_mount(const int *, unsigned int, unsigned int, uint32_t, uint32_t, - unsigned int, unsigned int, struct mib_node **); -void mib_unmount(struct mib_node *); -extern unsigned int mib_nodes; -extern unsigned int mib_objects; -extern unsigned int mib_remotes; - -/* remote.c */ -void mib_remote_init(void); -int mib_register(const message *, int); -int mib_deregister(const message *, int); -int mib_remote_info(unsigned int, uint32_t, char *, size_t, char *, size_t); -ssize_t mib_remote_call(struct mib_call *, struct mib_node *, - struct mib_oldp *, struct mib_newp *); - -/* proc.c */ -ssize_t mib_kern_lwp(struct mib_call *, struct mib_node *, struct mib_oldp *, - struct mib_newp *); -ssize_t mib_kern_proc2(struct mib_call *, struct mib_node *, struct mib_oldp *, - struct mib_newp *); -ssize_t mib_kern_proc_args(struct mib_call *, struct mib_node *, - struct mib_oldp *, struct mib_newp *); -ssize_t mib_minix_proc_list(struct mib_call *, struct mib_node *, - struct mib_oldp *, struct mib_newp *); -ssize_t mib_minix_proc_data(struct mib_call *, struct mib_node *, - struct mib_oldp *, struct mib_newp *); - -/* subtree modules */ -void mib_kern_init(struct mib_node *); -void mib_vm_init(struct mib_node *); -void mib_hw_init(struct mib_node *); -void mib_minix_init(struct mib_node *); - -#endif /* !_MINIX_MIB_MIB_H */ diff --git a/minix/servers/mib/proc.c b/minix/servers/mib/proc.c deleted file mode 100644 index 4a35536f2..000000000 --- a/minix/servers/mib/proc.c +++ /dev/null @@ -1,1288 +0,0 @@ -/* MIB service - proc.c - functionality based on service process tables */ -/* Eventually, the CTL_PROC subtree might end up here as well. */ - -#include "mib.h" - -#include -#include - -#include -#include "kernel/proc.h" -#include "servers/pm/mproc.h" -#include "servers/vfs/const.h" -#include "servers/vfs/fproc.h" - -typedef struct proc ixfer_proc_t; -typedef struct mproc ixfer_mproc_t; - -static ixfer_proc_t proc_tab[NR_TASKS + NR_PROCS]; -static ixfer_mproc_t mproc_tab[NR_PROCS]; -static struct fproc_light fproc_tab[NR_PROCS]; - -/* - * The number of processes added to the current number of processes when doing - * a size estimation, so that the actual data retrieval does not end up with - * too little space if new processes have forked between the two calls. We do - * a process table update only once per clock tick, which means that typically - * no update will take place between the user process's size estimation request - * and its subsequent data retrieval request. On the other hand, if we do - * update process tables in between, quite a bit might have changed. - */ -#define EXTRA_PROCS 8 - -#define HASH_SLOTS (NR_PROCS / 4) /* expected nr. of processes in use */ -#define NO_SLOT (-1) -static int hash_tab[HASH_SLOTS]; /* hash table mapping from PID.. */ -static int hnext_tab[NR_PROCS]; /* ..to PM process slot */ - -static clock_t tabs_updated = 0; /* when the tables were last updated */ -static int tabs_valid = TRUE; /* FALSE if obtaining tables failed */ - -/* - * Update the process tables by pulling in new copies from the kernel, PM, and - * VFS, but only every so often and only if it has not failed before. Return - * TRUE iff the tables are now valid. - */ -static int -update_tables(void) -{ - clock_t now; - pid_t pid; - int r, kslot, mslot, hslot; - - /* - * If retrieving the tables failed at some point, do not keep trying - * all the time. Such a failure is very unlikely to be transient. - */ - if (tabs_valid == FALSE) - return FALSE; - - /* - * Update the tables once per clock tick at most. The update operation - * is rather heavy, transferring several hundreds of kilobytes between - * servers. Userland should be able to live with information that is - * outdated by at most one clock tick. - */ - now = getticks(); - - if (tabs_updated != 0 && tabs_updated == now) - return TRUE; - - /* Perform an actual update now. */ - tabs_valid = FALSE; - - /* Retrieve and check the kernel process table. */ - if ((r = sys_getproctab(proc_tab)) != OK) { - printf("MIB: unable to obtain kernel process table (%d)\n", r); - - return FALSE; - } - - for (kslot = 0; kslot < NR_TASKS + NR_PROCS; kslot++) { - if (proc_tab[kslot].p_magic != PMAGIC) { - printf("MIB: kernel process table mismatch\n"); - - return FALSE; - } - } - - /* Retrieve and check the PM process table. */ - r = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc_tab, sizeof(mproc_tab)); - if (r != OK) { - printf("MIB: unable to obtain PM process table (%d)\n", r); - - return FALSE; - } - - for (mslot = 0; mslot < NR_PROCS; mslot++) { - if (mproc_tab[mslot].mp_magic != MP_MAGIC) { - printf("MIB: PM process table mismatch\n"); - - return FALSE; - } - } - - /* Retrieve an extract of the VFS process table. */ - r = getsysinfo(VFS_PROC_NR, SI_PROCLIGHT_TAB, fproc_tab, - sizeof(fproc_tab)); - if (r != OK) { - printf("MIB: unable to obtain VFS process table (%d)\n", r); - - return FALSE; - } - - tabs_valid = TRUE; - tabs_updated = now; - - /* - * Build a hash table mapping from process IDs to slot numbers, for - * fast access. TODO: decide if this is better done on demand only. - */ - for (hslot = 0; hslot < HASH_SLOTS; hslot++) - hash_tab[hslot] = NO_SLOT; - - for (mslot = 0; mslot < NR_PROCS; mslot++) { - if (mproc_tab[mslot].mp_flags & IN_USE) { - if ((pid = mproc_tab[mslot].mp_pid) <= 0) - continue; - - hslot = mproc_tab[mslot].mp_pid % HASH_SLOTS; - - hnext_tab[mslot] = hash_tab[hslot]; - hash_tab[hslot] = mslot; - } - } - - return TRUE; -} - -/* - * Return the PM slot number for the given PID, or NO_SLOT if the PID is not in - * use by a process. - */ -static int -get_mslot(pid_t pid) -{ - int mslot; - - /* PID 0 identifies the kernel; checking this is up to the caller. */ - if (pid <= 0) - return NO_SLOT; - - for (mslot = hash_tab[pid % HASH_SLOTS]; mslot != NO_SLOT; - mslot = hnext_tab[mslot]) - if (mproc_tab[mslot].mp_pid == pid) - break; - - return mslot; -} - -/* - * Store the given number of clock ticks as a timeval structure. - */ -static void -ticks_to_timeval(struct timeval * tv, clock_t ticks) -{ - clock_t hz; - - hz = sys_hz(); - - tv->tv_sec = ticks / hz; - tv->tv_usec = (long)((ticks % hz) * 1000000ULL / hz); -} - -/* - * Generate a wchan message text for the cases that the process is blocked on - * IPC with another process, of which the endpoint is given as 'endpt' here. - * The name of the other process is to be stored in 'wmesg', which is a buffer - * of size 'wmsz'. The result should be null terminated. If 'ipc' is set, the - * process is blocked on a direct IPC call, in which case the name of the other - * process is enclosed in parentheses. If 'ipc' is not set, the call is made - * indirectly through VFS, and the name of the other process should not be - * enclosed in parentheses. If no name can be obtained, we use the endpoint of - * the other process instead. - */ -static void -fill_wmesg(char * wmesg, size_t wmsz, endpoint_t endpt, int ipc) -{ - const char *name; - int mslot; - - switch (endpt) { - case ANY: - name = "any"; - break; - case SELF: - name = "self"; - break; - case NONE: - name = "none"; - break; - default: - mslot = _ENDPOINT_P(endpt); - if (mslot >= -NR_TASKS && mslot < NR_PROCS && - (mslot < 0 || (mproc_tab[mslot].mp_flags & IN_USE))) - name = proc_tab[NR_TASKS + mslot].p_name; - else - name = NULL; - } - - if (name != NULL) - snprintf(wmesg, wmsz, "%s%s%s", - ipc ? "(" : "", name, ipc ? ")" : ""); - else - snprintf(wmesg, wmsz, "%s%d%s", - ipc ? "(" : "", endpt, ipc ? ")" : ""); -} - -/* - * Return the LWP status of a process, along with additional information in - * case the process is sleeping (LSSLEEP): a wchan value and text to indicate - * what the process is sleeping on, and possibly a flag field modification to - * indicate that the sleep is interruptible. - */ -static int -get_lwp_stat(int mslot, uint64_t * wcptr, char * wmptr, size_t wmsz, - int32_t * flag) -{ - struct mproc *mp; - struct fproc_light *fp; - struct proc *kp; - const char *wmesg; - uint64_t wchan; - endpoint_t endpt; - - mp = &mproc_tab[mslot]; - fp = &fproc_tab[mslot]; - kp = &proc_tab[NR_TASKS + mslot]; - - /* - * First cover all the cases that the process is not sleeping. In - * those cases, we need not return additional sleep information either. - */ - if (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)) - return LSZOMB; - - if (mp->mp_flags & EXITING) - return LSDEAD; - - if ((mp->mp_flags & TRACE_STOPPED) || RTS_ISSET(kp, RTS_P_STOP)) - return LSSTOP; - - if (proc_is_runnable(kp)) - return LSRUN; - - /* - * The process is sleeping. In that case, we must also figure out why, - * and return an appropriate wchan value and human-readable wmesg text. - * - * The process can be blocked on either a known sleep state in PM or - * VFS, or otherwise on IPC communication with another process, or - * otherwise on a kernel RTS flag. In each case, decide what to use as - * wchan value and wmesg text, and whether the sleep is interruptible. - * - * The wchan value should be unique for the sleep reason. We use its - * lower eight bits to indicate a class: - * 0x00 = kernel task - * 0x01 = kerel RTS block - * 0x02 = PM call - * 0x03 = VFS call - * 0x04 = MIB call - * 0xff = blocked on process - * The upper bits are used for class-specific information. The actual - * value does not really matter, as long as it is nonzero and there is - * no overlap between the different values. - */ - wchan = 0; - wmesg = NULL; - - /* - * First see if the process is marked as blocked in the tables of PM or - * VFS. Such a block reason is always an interruptible sleep. Note - * that we do not use the kernel table at all in this case: each of the - * three tables is consistent within itself, but not necessarily - * consistent with any of the other tables, so we avoid internal - * mismatches if we can. - */ - if (mp->mp_flags & WAITING) { - wchan = 0x102; - wmesg = "wait"; - } else if (mp->mp_flags & SIGSUSPENDED) { - wchan = 0x202; - wmesg = "pause"; - } else if (fp->fpl_blocked_on != FP_BLOCKED_ON_NONE) { - wchan = (fp->fpl_blocked_on << 8) | 0x03; - switch (fp->fpl_blocked_on) { - case FP_BLOCKED_ON_PIPE: - wmesg = "pipe"; - break; - case FP_BLOCKED_ON_FLOCK: - wmesg = "flock"; - break; - case FP_BLOCKED_ON_POPEN: - wmesg = "popen"; - break; - case FP_BLOCKED_ON_SELECT: - wmesg = "select"; - break; - case FP_BLOCKED_ON_CDEV: - case FP_BLOCKED_ON_SDEV: - /* - * Add the task (= character or socket driver) endpoint - * to the wchan value, and use the driver's process - * name, without parentheses, as wmesg text. - */ - wchan |= (uint64_t)fp->fpl_task << 16; - fill_wmesg(wmptr, wmsz, fp->fpl_task, FALSE /*ipc*/); - break; - default: - /* A newly added flag we don't yet know about? */ - wmesg = "???"; - break; - } - } - if (wchan != 0) { - *wcptr = wchan; - if (wmesg != NULL) /* NULL means "already set" here */ - strlcpy(wmptr, wmesg, wmsz); - *flag |= L_SINTR; - } - - /* - * See if the process is blocked on sending or receiving. If not, then - * use one of the kernel RTS flags as reason. - */ - endpt = P_BLOCKEDON(kp); - - switch (endpt) { - case MIB_PROC_NR: - /* This is really just aesthetics. */ - wchan = 0x04; - wmesg = "sysctl"; - break; - case NONE: - /* - * The process is not running, but also not blocked on IPC with - * another process. This means it must be stopped on a kernel - * RTS flag. - */ - wchan = ((uint64_t)kp->p_rts_flags << 8) | 0x01; - if (RTS_ISSET(kp, RTS_PROC_STOP)) - wmesg = "kstop"; - else if (RTS_ISSET(kp, RTS_SIGNALED) || - RTS_ISSET(kp, RTS_SIGNALED)) - wmesg = "ksignal"; - else if (RTS_ISSET(kp, RTS_NO_PRIV)) - wmesg = "knopriv"; - else if (RTS_ISSET(kp, RTS_PAGEFAULT) || - RTS_ISSET(kp, RTS_VMREQTARGET)) - wmesg = "fault"; - else if (RTS_ISSET(kp, RTS_NO_QUANTUM)) - wmesg = "sched"; - else - wmesg = "kflag"; - break; - case ANY: - /* - * If the process is blocked receiving from ANY, mark it as - * being in an interruptible sleep. This looks nicer, even - * though "interruptible" is not applicable to services at all. - */ - *flag |= L_SINTR; - break; - } - - /* - * If at this point wchan is still zero, the process is blocked sending - * or receiving. Use a wchan value based on the target endpoint, and - * use "(procname)" as wmesg text. - */ - if (wchan == 0) { - *wcptr = ((uint64_t)endpt << 8) | 0xff; - fill_wmesg(wmptr, wmsz, endpt, TRUE /*ipc*/); - } else { - *wcptr = wchan; - if (wmesg != NULL) /* NULL means "already set" here */ - strlcpy(wmptr, wmesg, wmsz); - } - - return LSSLEEP; -} - - -/* - * Fill the part of a LWP structure that is common between kernel tasks and - * user processes. Also return a CPU estimate in 'estcpu', because we generate - * the value as a side effect here, and the LWP structure has no estcpu field. - */ -static void -fill_lwp_common(struct kinfo_lwp * l, int kslot, uint32_t * estcpu) -{ - struct proc *kp; - struct timeval tv; - clock_t uptime; - uint32_t hz; - - kp = &proc_tab[kslot]; - - uptime = getticks(); - hz = sys_hz(); - - /* - * We use the process endpoint as the LWP ID. Not only does this allow - * users to obtain process endpoints with "ps -s" (thus replacing the - * MINIX3 ps(1)'s "ps -E"), but if we ever do implement kernel threads, - * this is probably still going to be accurate. - */ - l->l_lid = kp->p_endpoint; - - /* - * The time during which the process has not been swapped in or out is - * not applicable for us, and thus, we set it to the time the process - * has been running (in seconds). This value is relevant mostly for - * ps(1)'s CPU usage correction for processes that have just started. - */ - if (kslot >= NR_TASKS) - l->l_swtime = uptime - mproc_tab[kslot - NR_TASKS].mp_started; - else - l->l_swtime = uptime; - l->l_swtime /= hz; - - /* - * Sleep (dequeue) times are not maintained for kernel tasks, so - * pretend they are never asleep (which is pretty accurate). - */ - if (kslot < NR_TASKS) - l->l_slptime = 0; - else - l->l_slptime = (uptime - kp->p_dequeued) / hz; - - l->l_priority = kp->p_priority; - l->l_usrpri = kp->p_priority; - l->l_cpuid = kp->p_cpu; - ticks_to_timeval(&tv, kp->p_user_time + kp->p_sys_time); - l->l_rtime_sec = tv.tv_sec; - l->l_rtime_usec = tv.tv_usec; - - /* - * Obtain CPU usage percentages and estimates through library code - * shared between the kernel and this service; see its source for - * details. We note that the produced estcpu value is rather different - * from the one produced by NetBSD, but this should not be a problem. - */ - l->l_pctcpu = cpuavg_getstats(&kp->p_cpuavg, &l->l_cpticks, estcpu, - uptime, hz); -} - -/* - * Fill a LWP structure for a kernel task. Each kernel task has its own LWP, - * and all of them have negative PIDs. - */ -static void -fill_lwp_kern(struct kinfo_lwp * l, int kslot) -{ - uint32_t estcpu; - - memset(l, 0, sizeof(*l)); - - l->l_flag = L_INMEM | L_SINTR | L_SYSTEM; - l->l_stat = LSSLEEP; - l->l_pid = kslot - NR_TASKS; - - /* - * When showing LWP entries, ps(1) uses the process name rather than - * the LWP name. All kernel tasks are therefore shown as "[kernel]" - * anyway. We use the wmesg field to show the actual kernel task name. - */ - l->l_wchan = ((uint64_t)(l->l_pid) << 8) | 0x00; - strlcpy(l->l_wmesg, proc_tab[kslot].p_name, sizeof(l->l_wmesg)); - strlcpy(l->l_name, "kernel", sizeof(l->l_name)); - - fill_lwp_common(l, kslot, &estcpu); -} - -/* - * Fill a LWP structure for a user process. - */ -static void -fill_lwp_user(struct kinfo_lwp * l, int mslot) -{ - struct mproc *mp; - uint32_t estcpu; - - memset(l, 0, sizeof(*l)); - - mp = &mproc_tab[mslot]; - - l->l_flag = L_INMEM; - l->l_stat = get_lwp_stat(mslot, &l->l_wchan, l->l_wmesg, - sizeof(l->l_wmesg), &l->l_flag); - l->l_pid = mp->mp_pid; - strlcpy(l->l_name, mp->mp_name, sizeof(l->l_name)); - - fill_lwp_common(l, NR_TASKS + mslot, &estcpu); -} - -/* - * Implementation of CTL_KERN KERN_LWP. - */ -ssize_t -mib_kern_lwp(struct mib_call * call, struct mib_node * node __unused, - struct mib_oldp * oldp, struct mib_newp * newp __unused) -{ - struct kinfo_lwp lwp; - struct mproc *mp; - size_t copysz; - ssize_t off; - pid_t pid; - int r, elsz, elmax, kslot, mslot, last_mslot; - - if (call->call_namelen != 3) - return EINVAL; - - pid = (pid_t)call->call_name[0]; - elsz = call->call_name[1]; - elmax = call->call_name[2]; /* redundant with the given oldlen.. */ - - if (pid < -1 || elsz <= 0 || elmax < 0) - return EINVAL; - - if (!update_tables()) - return EINVAL; - - off = 0; - copysz = MIN((size_t)elsz, sizeof(lwp)); - - /* - * We model kernel tasks as LWP threads of the kernel (with PID 0). - * Modeling the kernel tasks as processes with negative PIDs, like - * ProcFS does, conflicts with the KERN_LWP API here: a PID of -1 - * indicates that the caller wants a full listing of LWPs. - */ - if (pid <= 0) { - for (kslot = 0; kslot < NR_TASKS; kslot++) { - if (mib_inrange(oldp, off) && elmax > 0) { - fill_lwp_kern(&lwp, kslot); - if ((r = mib_copyout(oldp, off, &lwp, - copysz)) < 0) - return r; - elmax--; - } - off += elsz; - } - - /* No need to add extra space here: NR_TASKS is static. */ - if (pid == 0) - return off; - } - - /* - * With PID 0 out of the way: the user requested the LWP for either a - * specific user process (pid > 0), or for all processes (pid < 0). - */ - if (pid > 0) { - if ((mslot = get_mslot(pid)) == NO_SLOT || - (mproc_tab[mslot].mp_flags & (TRACE_ZOMBIE | ZOMBIE))) - return ESRCH; - last_mslot = mslot; - } else { - mslot = 0; - last_mslot = NR_PROCS - 1; - } - - for (; mslot <= last_mslot; mslot++) { - mp = &mproc_tab[mslot]; - - if ((mp->mp_flags & (IN_USE | TRACE_ZOMBIE | ZOMBIE)) != - IN_USE) - continue; - - if (mib_inrange(oldp, off) && elmax > 0) { - fill_lwp_user(&lwp, mslot); - if ((r = mib_copyout(oldp, off, &lwp, copysz)) < 0) - return r; - elmax--; - } - off += elsz; - } - - if (oldp == NULL && pid < 0) - off += EXTRA_PROCS * elsz; - - return off; -} - - -/* - * Fill the part of a process structure that is common between kernel tasks and - * user processes. - */ -static void -fill_proc2_common(struct kinfo_proc2 * p, int kslot) -{ - struct vm_usage_info vui; - struct timeval tv; - struct proc *kp; - struct kinfo_lwp l; - - kp = &proc_tab[kslot]; - - /* - * Much of the information in the LWP structure also ends up in the - * process structure. In order to avoid duplication of some important - * code, first generate LWP values and then copy it them into the - * process structure. - */ - memset(&l, 0, sizeof(l)); - fill_lwp_common(&l, kslot, &p->p_estcpu); - - /* Obtain memory usage information from VM. Ignore failures. */ - memset(&vui, 0, sizeof(vui)); - (void)vm_info_usage(kp->p_endpoint, &vui); - - ticks_to_timeval(&tv, kp->p_user_time + kp->p_sys_time); - p->p_rtime_sec = l.l_rtime_sec; - p->p_rtime_usec = l.l_rtime_usec; - p->p_cpticks = l.l_cpticks; - p->p_pctcpu = l.l_pctcpu; - p->p_swtime = l.l_swtime; - p->p_slptime = l.l_slptime; - p->p_uticks = kp->p_user_time; - p->p_sticks = kp->p_sys_time; - /* TODO: p->p_iticks */ - ticks_to_timeval(&tv, kp->p_user_time); - p->p_uutime_sec = tv.tv_sec; - p->p_uutime_usec = tv.tv_usec; - ticks_to_timeval(&tv, kp->p_sys_time); - p->p_ustime_sec = tv.tv_sec; - p->p_ustime_usec = tv.tv_usec; - - p->p_priority = l.l_priority; - p->p_usrpri = l.l_usrpri; - - p->p_vm_rssize = howmany(vui.vui_total, PAGE_SIZE); - p->p_vm_vsize = howmany(vui.vui_virtual, PAGE_SIZE); - p->p_vm_msize = howmany(vui.vui_mvirtual, PAGE_SIZE); - - p->p_uru_maxrss = vui.vui_maxrss; - p->p_uru_minflt = vui.vui_minflt; - p->p_uru_majflt = vui.vui_majflt; - - p->p_cpuid = l.l_cpuid; -} - -/* - * Fill a process structure for the kernel pseudo-process (with PID 0). - */ -static void -fill_proc2_kern(struct kinfo_proc2 * p) -{ - - memset(p, 0, sizeof(*p)); - - p->p_flag = L_INMEM | L_SYSTEM | L_SINTR; - p->p_pid = 0; - p->p_stat = LSSLEEP; - p->p_nice = NZERO; - - /* Use the KERNEL task wchan, for consistency between ps and top. */ - p->p_wchan = ((uint64_t)KERNEL << 8) | 0x00; - strlcpy(p->p_wmesg, "kernel", sizeof(p->p_wmesg)); - - strlcpy(p->p_comm, "kernel", sizeof(p->p_comm)); - p->p_realflag = P_INMEM | P_SYSTEM | P_SINTR; - p->p_realstat = SACTIVE; - p->p_nlwps = NR_TASKS; - - /* - * By using the KERNEL slot here, the kernel process will get a proper - * CPU usage average. - */ - fill_proc2_common(p, KERNEL + NR_TASKS); -} - -/* - * Fill a process structure for a user process. - */ -static void -fill_proc2_user(struct kinfo_proc2 * p, int mslot) -{ - struct mproc *mp; - struct fproc_light *fp; - time_t boottime; - dev_t tty; - struct timeval tv; - int i, r, kslot, zombie; - - memset(p, 0, sizeof(*p)); - - if ((r = getuptime(NULL, NULL, &boottime)) != OK) - panic("getuptime failed: %d", r); - - kslot = NR_TASKS + mslot; - mp = &mproc_tab[mslot]; - fp = &fproc_tab[mslot]; - - zombie = (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)); - tty = (!zombie) ? fp->fpl_tty : NO_DEV; - - p->p_eflag = 0; - if (tty != NO_DEV) - p->p_eflag |= EPROC_CTTY; - if (mp->mp_pid == mp->mp_procgrp) /* TODO: job control support */ - p->p_eflag |= EPROC_SLEADER; - - p->p_exitsig = SIGCHLD; /* TODO */ - - p->p_flag = P_INMEM; - if (mp->mp_flags & TAINTED) - p->p_flag |= P_SUGID; - if (mp->mp_tracer != NO_TRACER) - p->p_flag |= P_TRACED; - if (tty != NO_DEV) - p->p_flag |= P_CONTROLT; - p->p_pid = mp->mp_pid; - if (mp->mp_parent >= 0 && mp->mp_parent < NR_PROCS) - p->p_ppid = mproc_tab[mp->mp_parent].mp_pid; - p->p_sid = mp->mp_procgrp; /* TODO: job control supported */ - p->p__pgid = mp->mp_procgrp; - p->p_tpgid = (tty != NO_DEV) ? mp->mp_procgrp : 0; - p->p_uid = mp->mp_effuid; - p->p_ruid = mp->mp_realuid; - p->p_gid = mp->mp_effgid; - p->p_rgid = mp->mp_realgid; - p->p_ngroups = MIN(mp->mp_ngroups, KI_NGROUPS); - for (i = 0; i < p->p_ngroups; i++) - p->p_groups[i] = mp->mp_sgroups[i]; - p->p_tdev = tty; - memcpy(&p->p_siglist, &mp->mp_sigpending, sizeof(p->p_siglist)); - memcpy(&p->p_sigmask, &mp->mp_sigmask, sizeof(p->p_sigmask)); - memcpy(&p->p_sigcatch, &mp->mp_catch, sizeof(p->p_sigcatch)); - memcpy(&p->p_sigignore, &mp->mp_ignore, sizeof(p->p_sigignore)); - p->p_nice = mp->mp_nice + NZERO; - strlcpy(p->p_comm, mp->mp_name, sizeof(p->p_comm)); - p->p_uvalid = 1; - ticks_to_timeval(&tv, mp->mp_started); - p->p_ustart_sec = boottime + tv.tv_sec; - p->p_ustart_usec = tv.tv_usec; - /* TODO: other rusage fields */ - ticks_to_timeval(&tv, mp->mp_child_utime + mp->mp_child_stime); - p->p_uctime_sec = tv.tv_sec; - p->p_uctime_usec = tv.tv_usec; - p->p_realflag = p->p_flag; - p->p_nlwps = (zombie) ? 0 : 1; - p->p_svuid = mp->mp_svuid; - p->p_svgid = mp->mp_svgid; - - p->p_stat = get_lwp_stat(mslot, &p->p_wchan, p->p_wmesg, - sizeof(p->p_wmesg), &p->p_flag); - - switch (p->p_stat) { - case LSRUN: - p->p_realstat = SACTIVE; - p->p_nrlwps = 1; - break; - case LSSLEEP: - p->p_realstat = SACTIVE; - if (p->p_flag & L_SINTR) - p->p_realflag |= P_SINTR; - break; - case LSSTOP: - p->p_realstat = SSTOP; - break; - case LSZOMB: - p->p_realstat = SZOMB; - break; - case LSDEAD: - p->p_stat = LSZOMB; /* ps(1) STAT does not know LSDEAD */ - p->p_realstat = SDEAD; - break; - default: - assert(0); - } - - if (!zombie) - fill_proc2_common(p, kslot); -} - -/* - * Implementation of CTL_KERN KERN_PROC2. - */ -ssize_t -mib_kern_proc2(struct mib_call * call, struct mib_node * node __unused, - struct mib_oldp * oldp, struct mib_newp * newp __unused) -{ - struct kinfo_proc2 proc2; - struct mproc *mp; - size_t copysz; - ssize_t off; - dev_t tty; - int r, req, arg, elsz, elmax, kmatch, zombie, mslot; - - if (call->call_namelen != 4) - return EINVAL; - - req = call->call_name[0]; - arg = call->call_name[1]; - elsz = call->call_name[2]; - elmax = call->call_name[3]; /* redundant with the given oldlen.. */ - - /* - * The kernel is special, in that it does not have a slot in the PM or - * VFS tables. As such, it is dealt with separately. While checking - * arguments, we might as well check whether the kernel is matched. - */ - switch (req) { - case KERN_PROC_ALL: - kmatch = TRUE; - break; - case KERN_PROC_PID: - case KERN_PROC_SESSION: - case KERN_PROC_PGRP: - case KERN_PROC_UID: - case KERN_PROC_RUID: - case KERN_PROC_GID: - case KERN_PROC_RGID: - kmatch = (arg == 0); - break; - case KERN_PROC_TTY: - kmatch = ((dev_t)arg == KERN_PROC_TTY_NODEV); - break; - default: - return EINVAL; - } - - if (elsz <= 0 || elmax < 0) - return EINVAL; - - if (!update_tables()) - return EINVAL; - - off = 0; - copysz = MIN((size_t)elsz, sizeof(proc2)); - - if (kmatch) { - if (mib_inrange(oldp, off) && elmax > 0) { - fill_proc2_kern(&proc2); - if ((r = mib_copyout(oldp, off, &proc2, copysz)) < 0) - return r; - elmax--; - } - off += elsz; - } - - for (mslot = 0; mslot < NR_PROCS; mslot++) { - mp = &mproc_tab[mslot]; - - if (!(mp->mp_flags & IN_USE)) - continue; - - switch (req) { - case KERN_PROC_PID: - if ((pid_t)arg != mp->mp_pid) - continue; - break; - case KERN_PROC_SESSION: /* TODO: job control support */ - case KERN_PROC_PGRP: - if ((pid_t)arg != mp->mp_procgrp) - continue; - break; - case KERN_PROC_TTY: - if ((dev_t)arg == KERN_PROC_TTY_REVOKE) - continue; /* TODO: revoke(2) support */ - /* Do not access the fproc_tab slot of zombies. */ - zombie = (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)); - tty = (zombie) ? fproc_tab[mslot].fpl_tty : NO_DEV; - if ((dev_t)arg == KERN_PROC_TTY_NODEV) { - if (tty != NO_DEV) - continue; - } else if ((dev_t)arg == NO_DEV || (dev_t)arg != tty) - continue; - break; - case KERN_PROC_UID: - if ((uid_t)arg != mp->mp_effuid) - continue; - break; - case KERN_PROC_RUID: - if ((uid_t)arg != mp->mp_realuid) - continue; - break; - case KERN_PROC_GID: - if ((gid_t)arg != mp->mp_effgid) - continue; - break; - case KERN_PROC_RGID: - if ((gid_t)arg != mp->mp_realgid) - continue; - break; - } - - if (mib_inrange(oldp, off) && elmax > 0) { - fill_proc2_user(&proc2, mslot); - if ((r = mib_copyout(oldp, off, &proc2, copysz)) < 0) - return r; - elmax--; - } - off += elsz; - } - - if (oldp == NULL && req != KERN_PROC_PID) - off += EXTRA_PROCS * elsz; - - return off; -} - -/* - * Implementation of CTL_KERN KERN_PROC_ARGS. - */ -ssize_t -mib_kern_proc_args(struct mib_call * call, struct mib_node * node __unused, - struct mib_oldp * oldp, struct mib_newp * newp __unused) -{ - char vbuf[PAGE_SIZE], sbuf[PAGE_SIZE], obuf[PAGE_SIZE]; - struct ps_strings pss; - struct mproc *mp; - char *buf, *p, *q, *pptr; - vir_bytes vaddr, vpage, spage, paddr, ppage; - size_t max, off, olen, oleft, oldlen, bytes, pleft; - unsigned int copybudget; - pid_t pid; - int req, mslot, count, aborted, ended; - ssize_t r; - - if (call->call_namelen != 2) - return EINVAL; - - pid = call->call_name[0]; - req = call->call_name[1]; - - switch (req) { - case KERN_PROC_ARGV: - case KERN_PROC_ENV: - case KERN_PROC_NARGV: - case KERN_PROC_NENV: - break; - default: - return EOPNOTSUPP; - } - - if (!update_tables()) - return EINVAL; - - if ((mslot = get_mslot(pid)) == NO_SLOT) - return ESRCH; - mp = &mproc_tab[mslot]; - if (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)) - return ESRCH; - - /* We can return the count field size without copying in any data. */ - if (oldp == NULL && (req == KERN_PROC_NARGV || req == KERN_PROC_NENV)) - return sizeof(count); - - if (sys_datacopy(mp->mp_endpoint, - mp->mp_frame_addr + mp->mp_frame_len - sizeof(pss), - SELF, (vir_bytes)&pss, sizeof(pss)) != OK) - return EINVAL; - - /* - * Determine the upper size limit of the requested data. Not only may - * the size never exceed ARG_MAX, it may also not exceed the frame - * length as given in its original exec call. In fact, the frame - * length should be substantially larger: all strings for both the - * arguments and the environment are in there, along with other stuff, - * and there must be no overlap between strings. It is possible that - * the application called setproctitle(3), in which case the ps_strings - * pointers refer to data outside the frame altogether. However, this - * data should not exceed 2048 bytes, and we cover this by rounding up - * the frame length to a multiple of the page size. Anyhow, NetBSD - * blindly returns ARG_MAX when asked for a size estimate, so with this - * maximum we are already quite a bit more accurate. - */ - max = roundup(MIN(mp->mp_frame_len, ARG_MAX), PAGE_SIZE); - - switch (req) { - case KERN_PROC_NARGV: - count = pss.ps_nargvstr; - return mib_copyout(oldp, 0, &count, sizeof(count)); - case KERN_PROC_NENV: - count = pss.ps_nenvstr; - return mib_copyout(oldp, 0, &count, sizeof(count)); - case KERN_PROC_ARGV: - if (oldp == NULL) - return max; - vaddr = (vir_bytes)pss.ps_argvstr; - count = pss.ps_nargvstr; - break; - case KERN_PROC_ENV: - if (oldp == NULL) - return max; - vaddr = (vir_bytes)pss.ps_envstr; - count = pss.ps_nenvstr; - break; - } - - /* - * Go through the strings. Copy in entire, machine-aligned pages at - * once, in the hope that all data is stored consecutively, which it - * should be: we expect that the vector is followed by the strings, and - * that the strings are stored in order of vector reference. We keep - * up to two pages with copied-in data: one for the vector, and - * optionally one for string data. In addition, we keep one page with - * data to be copied out, so that we do not cause a lot of copy - * overhead for short strings. - * - * We stop whenever any of the following conditions are met: - * - copying in data from the target process fails for any reason; - * - we have processed the last index ('count') into the vector; - * - the current vector element is a NULL pointer; - * - the requested number of output bytes ('oldlen') has been reached; - * - the maximum number of output bytes ('max') has been reached; - * - the number of page copy-ins exceeds an estimated threshold; - * - copying out data fails for any reason (we then return the error). - * - * We limit the number of page copy-ins because otherwise a rogue - * process could create an argument vector consisting of only two-byte - * strings that all span two pages, causing us to copy up to 1GB of - * data with the current ARG_MAX value of 256K. No reasonable vector - * should cause more than (ARG_MAX / PAGE_SIZE) page copies for - * strings; we are nice enough to allow twice that. Vector copies do - * not count, as they are linear anyway. - * - * Unlike every other sysctl(2) call, we are supposed to truncate the - * resulting size (the returned 'oldlen') to the requested size (the - * given 'oldlen') *and* return the resulting size, rather than ENOMEM - * and the real size. Unfortunately, libkvm actually relies on this. - * - * Generally speaking, upon failure we just return a truncated result. - * In case of truncation, the data we copy out need not be null - * terminated. It is up to userland to process the data correctly. - */ - if (trunc_page(vaddr) == 0 || vaddr % sizeof(char *) != 0) - return 0; - - off = 0; - olen = 0; - aborted = FALSE; - - oldlen = mib_getoldlen(oldp); - if (oldlen > max) - oldlen = max; - - copybudget = (ARG_MAX / PAGE_SIZE) * 2; - - vpage = 0; - spage = 0; - - while (count > 0 && off + olen < oldlen && !aborted) { - /* - * Start by fetching the page containing the current vector - * element, if needed. We could limit the fetch to the vector - * size, but our hope is that for the simple cases, the strings - * are on the remainder of the same page, so we save a copy - * call. TODO: since the strings should follow the vector, we - * could start the copy at the base of the vector. - */ - if (trunc_page(vaddr) != vpage) { - vpage = trunc_page(vaddr); - if (sys_datacopy(mp->mp_endpoint, vpage, SELF, - (vir_bytes)vbuf, PAGE_SIZE) != OK) - break; - } - - /* Get the current vector element, pointing to a string. */ - memcpy(&pptr, &vbuf[vaddr - vpage], sizeof(pptr)); - paddr = (vir_bytes)pptr; - ppage = trunc_page(paddr); - if (ppage == 0) - break; - - /* Fetch the string itself, one page at a time at most. */ - do { - /* - * See if the string pointer falls inside either the - * vector page or the previously fetched string page - * (if any). If not, fetch a string page. - */ - if (ppage == vpage) { - buf = vbuf; - } else if (ppage == spage) { - buf = sbuf; - } else { - if (--copybudget == 0) { - aborted = TRUE; - break; - } - spage = ppage; - if (sys_datacopy(mp->mp_endpoint, spage, SELF, - (vir_bytes)sbuf, PAGE_SIZE) != OK) { - aborted = TRUE; - break; - } - buf = sbuf; - } - - /* - * We now have a string fragment in a buffer. See if - * the string is null terminated. If not, all the data - * up to the buffer end is part of the string, and the - * string continues on the next page. - */ - p = &buf[paddr - ppage]; - pleft = PAGE_SIZE - (paddr - ppage); - assert(pleft > 0); - - if ((q = memchr(p, '\0', pleft)) != NULL) { - bytes = (size_t)(q - p + 1); - assert(bytes <= pleft); - ended = TRUE; - } else { - bytes = pleft; - ended = FALSE; - } - - /* Limit the result to the requested length. */ - if (off + olen + bytes > oldlen) - bytes = oldlen - off - olen; - - /* - * Add 'bytes' bytes from string pointer 'p' to the - * output buffer, copying out its contents to userland - * if it has filled up. - */ - if (olen + bytes > sizeof(obuf)) { - oleft = sizeof(obuf) - olen; - memcpy(&obuf[olen], p, oleft); - - if ((r = mib_copyout(oldp, off, obuf, - sizeof(obuf))) < 0) - return r; - off += sizeof(obuf); - olen = 0; - - p += oleft; - bytes -= oleft; - } - if (bytes > 0) { - memcpy(&obuf[olen], p, bytes); - olen += bytes; - } - - /* - * Continue as long as we have not yet found the string - * end, and we have not yet filled the output buffer. - */ - paddr += pleft; - assert(trunc_page(paddr) == paddr); - ppage = paddr; - } while (!ended && off + olen < oldlen); - - vaddr += sizeof(char *); - count--; - } - - /* Copy out any remainder of the output buffer. */ - if (olen > 0) { - if ((r = mib_copyout(oldp, off, obuf, olen)) < 0) - return r; - off += olen; - } - - assert(off <= oldlen); - return off; -} - -/* - * Implementation of CTL_MINIX MINIX_PROC PROC_LIST. - */ -ssize_t -mib_minix_proc_list(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - struct minix_proc_list mpl[NR_PROCS]; - struct minix_proc_list *mplp; - struct mproc *mp; - unsigned int mslot; - - if (oldp == NULL) - return sizeof(mpl); - - if (!update_tables()) - return EINVAL; - - memset(&mpl, 0, sizeof(mpl)); - - mplp = mpl; - mp = mproc_tab; - - for (mslot = 0; mslot < NR_PROCS; mslot++, mplp++, mp++) { - if (!(mp->mp_flags & IN_USE) || mp->mp_pid <= 0) - continue; - - mplp->mpl_flags = MPLF_IN_USE; - if (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE)) - mplp->mpl_flags |= MPLF_ZOMBIE; - mplp->mpl_pid = mp->mp_pid; - mplp->mpl_uid = mp->mp_effuid; - mplp->mpl_gid = mp->mp_effgid; - } - - return mib_copyout(oldp, 0, &mpl, sizeof(mpl)); -} - -/* - * Implementation of CTL_MINIX MINIX_PROC PROC_DATA. - */ -ssize_t -mib_minix_proc_data(struct mib_call * call, struct mib_node * node __unused, - struct mib_oldp * oldp, struct mib_newp * newp __unused) -{ - struct minix_proc_data mpd; - struct proc *kp; - int kslot, mslot = 0; - unsigned int mflags; - pid_t pid; - - /* - * It is currently only possible to retrieve the process data for a - * particular PID, which must be given as the last name component. - */ - if (call->call_namelen != 1) - return EINVAL; - - pid = (pid_t)call->call_name[0]; - - if (!update_tables()) - return EINVAL; - - /* - * Unlike the CTL_KERN nodes, we use the ProcFS semantics here: if the - * given PID is negative, it is a kernel task; otherwise, it identifies - * a user process. A request for PID 0 will result in ESRCH. - */ - if (pid < 0) { - if (pid < -NR_TASKS) - return ESRCH; - - kslot = pid + NR_TASKS; - assert(kslot < NR_TASKS); - } else { - if ((mslot = get_mslot(pid)) == NO_SLOT) - return ESRCH; - - kslot = NR_TASKS + mslot; - } - - if (oldp == NULL) - return sizeof(mpd); - - kp = &proc_tab[kslot]; - - mflags = (pid > 0) ? mproc_tab[mslot].mp_flags : 0; - - memset(&mpd, 0, sizeof(mpd)); - mpd.mpd_endpoint = kp->p_endpoint; - if (mflags & PRIV_PROC) - mpd.mpd_flags |= MPDF_SYSTEM; - if (mflags & (TRACE_ZOMBIE | ZOMBIE)) - mpd.mpd_flags |= MPDF_ZOMBIE; - else if ((mflags & TRACE_STOPPED) || RTS_ISSET(kp, RTS_P_STOP)) - mpd.mpd_flags |= MPDF_STOPPED; - else if (proc_is_runnable(kp)) - mpd.mpd_flags |= MPDF_RUNNABLE; - mpd.mpd_blocked_on = P_BLOCKEDON(kp); - mpd.mpd_priority = kp->p_priority; - mpd.mpd_user_time = kp->p_user_time; - mpd.mpd_sys_time = kp->p_sys_time; - mpd.mpd_cycles = kp->p_cycles; - mpd.mpd_kipc_cycles = kp->p_kipc_cycles; - mpd.mpd_kcall_cycles = kp->p_kcall_cycles; - if (kslot >= NR_TASKS) { - mpd.mpd_nice = mproc_tab[mslot].mp_nice; - strlcpy(mpd.mpd_name, mproc_tab[mslot].mp_name, - sizeof(mpd.mpd_name)); - } else - strlcpy(mpd.mpd_name, kp->p_name, sizeof(mpd.mpd_name)); - - return mib_copyout(oldp, 0, &mpd, sizeof(mpd)); -} diff --git a/minix/servers/mib/tree.c b/minix/servers/mib/tree.c deleted file mode 100644 index 9eba191b8..000000000 --- a/minix/servers/mib/tree.c +++ /dev/null @@ -1,1842 +0,0 @@ -/* MIB service - tree.c - tree access and management */ - -#include "mib.h" - -/* - * Does the given identifier fall within the range of static identifiers in the - * given parent? This check can be used to enumerate all static array entries - * in the given parent, starting from zero. The check does not guarantee that - * the entry is actually for a valid node, nor does it guarantee that there is - * not a dynamic node with this identifier. - */ -#define IS_STATIC_ID(parent, id) ((unsigned int)(id) < (parent)->node_size) - -/* - * Scratch buffer, used for various cases of temporary data storage. It must - * be large enough to fit a sysctldesc structure followed by the longest - * supported description. It must also be large enough to serve as temporary - * storage for data being written in the majority of cases. Finally, it must - * be large enough to contain an entire page, for mib_copyin_str(). - */ -#define MAXDESCLEN 1024 /* from NetBSD */ -#define SCRATCH_SIZE MAX(PAGE_SIZE, sizeof(struct sysctldesc) + MAXDESCLEN) -static char scratch[SCRATCH_SIZE] __aligned(sizeof(int32_t)); - -unsigned int mib_nodes; /* how many nodes are there in the tree? */ -unsigned int mib_objects; /* how many memory objects are allocated? */ -unsigned int mib_remotes; /* how many remote subtrees are there? */ - -/* - * Find a node through its parent node and identifier. Return the node if it - * was found, and optionally store a pointer to the pointer to its dynode - * superstructure (for removal). If no matching node was found, return NULL. - */ -static struct mib_node * -mib_find(struct mib_node * parent, int id, struct mib_dynode *** prevpp) -{ - struct mib_node *node; - struct mib_dynode **dynp; - - if (id < 0) - return NULL; - - /* - * Is there a static node with this identifier? The static nodes are - * all in a single array, so lookup is O(1) for these nodes. We use - * the node flags field to see whether the array entry is valid. - */ - if (IS_STATIC_ID(parent, id)) { - node = &parent->node_scptr[id]; - - if (node->node_flags != 0) { - /* Found a matching static node. */ - if (prevpp != NULL) - *prevpp = NULL; - return node; - } - } - - /* - * Is there a dynamic node with this identifier? The dynamic nodes - * form a linked list. This is predominantly because userland may pick - * the identifier number at creation time, so we cannot rely on all - * dynamically created nodes falling into a small identifier range. - * That eliminates the option of a dynamic array indexed by identifier, - * and a linked list is the simplest next option. Thus, dynamic node - * lookup is O(n). However, since the list is sorted by identifier, - * we may be able to stop the search early. - */ - for (dynp = &parent->node_dcptr; *dynp != NULL; - dynp = &((*dynp)->dynode_next)) { - if ((*dynp)->dynode_id == id) { - /* Found a matching dynamic node. */ - if (prevpp != NULL) - *prevpp = dynp; - return &(*dynp)->dynode_node; - } else if ((*dynp)->dynode_id > id) - break; /* no need to look further */ - } - - return NULL; -} - -/* - * Copy out a node to userland, using the exchange format for nodes (namely, - * a sysctlnode structure). Return the size of the object that is (or, if the - * node falls outside the requested data range, would be) copied out on - * success, or a negative error code on failure. The function may return 0 - * to indicate that nothing was copied out after all (this is unused here). - */ -static ssize_t -mib_copyout_node(struct mib_call * call, struct mib_oldp * oldp, size_t off, - int id, const struct mib_node * node) -{ - struct sysctlnode scn; - int visible; - - if (!mib_inrange(oldp, off)) - return sizeof(scn); /* nothing to do */ - - memset(&scn, 0, sizeof(scn)); - - /* - * We use CTLFLAG_PARENT, CTLFLAG_VERIFY, and CTLFLAG_REMOTE internally - * only. NetBSD uses the values of these flags for different purposes. - * Either way, do not expose them to userland. - */ - scn.sysctl_flags = SYSCTL_VERSION | (node->node_flags & - ~(CTLFLAG_PARENT | CTLFLAG_VERIFY | CTLFLAG_REMOTE)); - scn.sysctl_num = id; - strlcpy(scn.sysctl_name, node->node_name, sizeof(scn.sysctl_name)); - scn.sysctl_ver = node->node_ver; - scn.sysctl_size = node->node_size; - - /* Some information is only visible if the user can access the node. */ - visible = (!(node->node_flags & CTLFLAG_PRIVATE) || mib_authed(call)); - - /* - * For immediate types, store the immediate value in the resulting - * structure, unless the caller is not authorized to obtain the value. - */ - if ((node->node_flags & CTLFLAG_IMMEDIATE) && visible) { - switch (SYSCTL_TYPE(node->node_flags)) { - case CTLTYPE_BOOL: - scn.sysctl_bdata = node->node_bool; - break; - case CTLTYPE_INT: - scn.sysctl_idata = node->node_int; - break; - case CTLTYPE_QUAD: - scn.sysctl_qdata = node->node_quad; - } - } - - /* Special rules apply to parent nodes. */ - if (SYSCTL_TYPE(node->node_flags) == CTLTYPE_NODE) { - /* Report the node size the way NetBSD does, just in case. */ - scn.sysctl_size = sizeof(scn); - - /* - * If this is a remote node, use the values we have of the root - * of the remote subtree. If we did not have these values, we - * would have to call into the remote service here, which for - * reliability purposes is a bad idea. - * - * If this is a real parent node, report child information. In - * both these cases, expose child information only if the node - * itself is accessible by the caller. - * - * If this is a function-driven node, indicate this by setting - * a nonzero function address. This allows trace(1) to - * determine that it should not attempt to descend into this - * part of the tree as usual, because a) accessing subnodes may - * have side effects, and b) meta-identifiers may not work as - * expected in these parts of the tree. Do not return the real - * function pointer, as this would leak anti-ASR information. - */ - if (node->node_flags & CTLFLAG_REMOTE) { - if (visible) { - scn.sysctl_csize = node->node_rcsize; - scn.sysctl_clen = node->node_rclen; - } - } else if (node->node_flags & CTLFLAG_PARENT) { - if (visible) { - scn.sysctl_csize = node->node_csize; - scn.sysctl_clen = node->node_clen; - } - } else - scn.sysctl_func = SYSCTL_NODE_FN; - } - - /* Copy out the resulting node. */ - return mib_copyout(oldp, off, &scn, sizeof(scn)); -} - -/* - * Given a query on a non-leaf (parent) node, provide the user with an array of - * this node's children. - */ -static ssize_t -mib_query(struct mib_call * call, struct mib_node * parent, - struct mib_oldp * oldp, struct mib_newp * newp) -{ - struct sysctlnode scn; - struct mib_node *node; - struct mib_dynode *dynode; - size_t off; - int r, id; - - /* If the user passed in version numbers, check them. */ - if (newp != NULL) { - if ((r = mib_copyin(newp, &scn, sizeof(scn))) != OK) - return r; - - if (SYSCTL_VERS(scn.sysctl_flags) != SYSCTL_VERSION) - return EINVAL; - - /* - * If a node version number is given, it must match the version - * of the parent or the root. - */ - if (scn.sysctl_ver != 0 && - scn.sysctl_ver != mib_root.node_ver && - scn.sysctl_ver != parent->node_ver) - return EINVAL; - } - - /* - * We need not return the nodes strictly in ascending order of - * identifiers, as this is not expected by userland. For example, - * sysctlgetmibinfo(3) performs its own sorting after a query. - * Thus, we can go through the static and dynamic nodes separately. - */ - off = 0; - - /* First enumerate the static nodes. */ - for (id = 0; IS_STATIC_ID(parent, id); id++) { - node = &parent->node_scptr[id]; - - if (node->node_flags == 0) - continue; - - if ((r = mib_copyout_node(call, oldp, off, id, node)) < 0) - return r; - off += r; - } - - /* Then enumerate the dynamic nodes. */ - for (dynode = parent->node_dcptr; dynode != NULL; - dynode = dynode->dynode_next) { - node = &dynode->dynode_node; - - if ((r = mib_copyout_node(call, oldp, off, dynode->dynode_id, - node)) < 0) - return r; - off += r; - } - - return off; -} - -/* - * Check whether the given name buffer contains a valid node name string. If - * the name is nonempty, properly terminated, and contains only acceptable - * characters, return the length of the string excluding null terminator. - * Otherwise, return zero to indicate failure. - */ -static size_t -mib_check_name(const char * name, size_t namesize) -{ - size_t namelen; - char c; - - /* Names must be nonempty, null terminated, C symbol style strings. */ - for (namelen = 0; namelen < namesize; namelen++) { - if ((c = name[namelen]) == '\0') - break; - /* A-Z, a-z, 0-9, _ only, and no digit as first character. */ - if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - c == '_' || (c >= '0' && c <= '9' && namelen > 0))) - return 0; - } - if (namelen == 0 || namelen == namesize) - return 0; - - return namelen; -} - -/* - * Scan a parent node's children, as part of new node creation. Search for - * either a free node identifier (if given_id < 0) or collisions with the node - * identifier to use (if given_id >= 0). Also check for name collisions. Upon - * success, return OK, with the resulting node identifier stored in 'idp' and a - * pointer to the pointer for the new dynamic node stored in 'prevpp'. Upon - * failure, return an error code. If the failure is EEXIST, 'idp' will contain - * the ID of the conflicting node, and 'nodep' will point to the node. - */ -static int -mib_scan(struct mib_node * parent, int given_id, const char * name, int * idp, - struct mib_dynode *** prevpp, struct mib_node ** nodep) -{ - struct mib_dynode **prevp, **dynp; - struct mib_node *node; - int id; - - /* - * We must verify that no entry already exists with the given name. In - * addition, if a nonnegative identifier is given, we should use that - * identifier and make sure it does not already exist. Otherwise, we - * must find a free identifier. Finally, we sort the dynamic nodes in - * ascending identifier order, so we must find the right place at which - * to insert the new node. - * - * For finding a free identifier, choose an ID that falls (well) - * outside the static range, both to avoid accidental retrieval by an - * application that uses a static ID, and to simplify verifying that - * the ID is indeed free. The sorting of dynamic nodes by identifier - * ensures that searching for a free identifier is O(n). - * - * At this time, we do not support some NetBSD features. We do not - * force success if the new node is sufficiently like an existing one. - * Also, we do not use global autoincrement for dynamic identifiers, - * although that could easily be changed. - */ - - /* First check the static node array, just for collisions. */ - for (id = 0; IS_STATIC_ID(parent, id); id++) { - node = &parent->node_scptr[id]; - if (node->node_flags == 0) - continue; - if (id == given_id || !strcmp(name, node->node_name)) { - *idp = id; - *nodep = node; - return EEXIST; - } - } - - /* - * Then try to find the place to insert a new dynamic node. At the - * same time, check for both identifier and name collisions. - */ - if (given_id >= 0) - id = given_id; - else - id = MAX(CREATE_BASE, parent->node_size); - - for (prevp = &parent->node_dcptr; *prevp != NULL; - prevp = &((*prevp)->dynode_next)) { - if ((*prevp)->dynode_id > id) - break; - if ((*prevp)->dynode_id == id) { - if (given_id >= 0) { - *idp = id; - *nodep = &(*prevp)->dynode_node; - return EEXIST; - } else - id++; - } - if (!strcmp(name, (*prevp)->dynode_node.node_name)) { - *idp = (*prevp)->dynode_id; - *nodep = &(*prevp)->dynode_node; - return EEXIST; - } - } - - /* Finally, check the rest of the dynamic nodes for name collisions. */ - for (dynp = prevp; *dynp != NULL; dynp = &((*dynp)->dynode_next)) { - assert((*dynp)->dynode_id > id); - - if (!strcmp(name, (*dynp)->dynode_node.node_name)) { - *idp = (*dynp)->dynode_id; - *nodep = &(*dynp)->dynode_node; - return EEXIST; - } - } - - *idp = id; - *prevpp = prevp; - return OK; -} - -/* - * Copy in a string from the user process, located at the given remote address, - * into the given local buffer. If no buffer is given, just compute the length - * of the string. On success, return OK. If 'sizep' is not NULL, it will be - * filled with the string size, including the null terminator. If a non-NULL - * buffer was given, the string will be copied into the provided buffer (also - * including null terminator). Return an error code on failure, which includes - * the case that no null terminator was found within the range of bytes that - * would fit in the given buffer. - */ -static int -mib_copyin_str(struct mib_newp * __restrict newp, vir_bytes addr, - char * __restrict buf, size_t bufsize, size_t * __restrict sizep) -{ - char *ptr, *endp; - size_t chunk, len; - int r; - - assert(newp != NULL); - assert(bufsize <= SSIZE_MAX); - - if (addr == 0) - return EINVAL; - - /* - * NetBSD has a kernel routine for copying in a string from userland. - * MINIX3 does not, since its system call interface has always relied - * on userland passing in string lengths. The sysctl(2) API does not - * provide the string length, and thus, we have to do a bit of guess - * work. If we copy too little at once, performance suffers. If we - * copy too much at once, we may trigger an unneeded page fault. Make - * use of page boundaries to strike a balance between those two. If we - * are requested to just get the string length, use the scratch buffer. - */ - len = 0; - - while (bufsize > 0) { - chunk = PAGE_SIZE - (addr % PAGE_SIZE); - if (chunk > bufsize) - chunk = bufsize; - - ptr = (buf != NULL) ? &buf[len] : scratch; - if ((r = mib_copyin_aux(newp, addr, ptr, chunk)) != OK) - return r; - - if ((endp = memchr(ptr, '\0', chunk)) != NULL) { - /* A null terminator was found - success. */ - if (sizep != NULL) - *sizep = len + (size_t)(endp - ptr) + 1; - return OK; - } - - addr += chunk; - len += chunk; - bufsize -= chunk; - } - - /* No null terminator found. */ - return EINVAL; -} - -/* - * Increase the version of the root node, and copy this new version to all - * nodes on the path to the given node, including that node itself. - */ -static void -mib_upgrade(struct mib_node * node) -{ - uint32_t ver; - - assert(node != NULL); - - /* - * The root node determines the version of the entire tree. Do not use - * version number 0, as a zero version number indicates no interest in - * versions elsewhere. - */ - - ver = mib_root.node_ver + 1; - if (ver == 0) - ver = 1; - - /* Copy the new version to all the nodes on the path. */ - do { - node->node_ver = ver; - - node = node->node_parent; - } while (node != NULL); -} - -/* - * Add a new dynamically allocated node into the tree, inserting it into the - * linked-list position of the parent tree as given by 'prevp'. Also update - * versions and counters accordingly. This function never fails. - */ -static void -mib_add(struct mib_dynode * dynode, struct mib_dynode ** prevp) -{ - struct mib_node *parent; - - parent = dynode->dynode_node.node_parent; - assert(parent != NULL); - - /* Link the dynamic node into the list, in the right place. */ - assert(prevp != NULL); - dynode->dynode_next = *prevp; - *prevp = dynode; - - /* The parent node now has one more child. */ - parent->node_csize++; - parent->node_clen++; - - /* There is now one more node in the tree. */ - mib_nodes++; - - /* - * Bump the version of all nodes on the path to the new node, including - * the node itself. - */ - mib_upgrade(&dynode->dynode_node); -} - -/* - * Create a node. - */ -static ssize_t -mib_create(struct mib_call * call, struct mib_node * parent, - struct mib_oldp * oldp, struct mib_newp * newp) -{ - struct mib_dynode *dynode, **prevp; - struct mib_node *node; - struct sysctlnode scn; - size_t namelen, size; - ssize_t len; - bool b; - char c; - int r, id; - - /* This is a privileged operation. */ - if (!mib_authed(call)) - return EPERM; - - /* - * The parent must not be a remote node, but this is already implied by - * the fact that we got here at all. - */ - assert(SYSCTL_TYPE(parent->node_flags) == CTLTYPE_NODE); - assert(!(parent->node_flags & CTLFLAG_REMOTE)); - - /* The parent node must not be marked as read-only. */ - if (!(parent->node_flags & CTLFLAG_READWRITE)) - return EPERM; - - /* - * Has the parent reached its child node limit? This check is entirely - * theoretical as long as we support only 32-bit virtual memory. - */ - if (parent->node_csize == INT_MAX) - return EINVAL; - assert(parent->node_clen <= parent->node_csize); - - /* The caller must supply information on the child node to create. */ - if (newp == NULL) - return EINVAL; - - if ((r = mib_copyin(newp, &scn, sizeof(scn))) != OK) - return r; - - /* - * We perform as many checks as possible before we start allocating - * memory. Then again, after allocation, copying in data may still - * fail. Unlike when setting values, we do not first copy data into a - * temporary buffer here, because we do not need to: if the copy fails, - * the entire create operation fails, so atomicity is not an issue. - */ - if (SYSCTL_VERS(scn.sysctl_flags) != SYSCTL_VERSION) - return EINVAL; - - /* - * If a node version number is given, it must match the version of - * either the parent or the root node. The given version number is - * *not* used for the node being created. - */ - if (scn.sysctl_ver != 0 && scn.sysctl_ver != mib_root.node_ver && - scn.sysctl_ver != parent->node_ver) - return EINVAL; - - /* - * Validate the node flags. In addition to the NetBSD-allowed flags, - * we also allow UNSIGNED, and leave its interpretation to userland. - */ - if (SYSCTL_FLAGS(scn.sysctl_flags) & - ~(SYSCTL_USERFLAGS | CTLFLAG_UNSIGNED)) - return EINVAL; - - if (!(scn.sysctl_flags & CTLFLAG_IMMEDIATE)) { - /* - * Without either IMMEDIATE or OWNDATA, data pointers are - * actually kernel addresses--a concept we do not support. - * Otherwise, if IMMEDIATE is not set, we are going to have to - * allocate extra memory for the data, so force OWNDATA to be. - * set. Node-type nodes have no data, though. - */ - if (SYSCTL_TYPE(scn.sysctl_flags) != CTLTYPE_NODE) { - if (!(scn.sysctl_flags & CTLFLAG_OWNDATA) && - scn.sysctl_data != NULL) - return EINVAL; /* not meaningful on MINIX3 */ - - scn.sysctl_flags |= CTLFLAG_OWNDATA; - } - } else if (scn.sysctl_flags & CTLFLAG_OWNDATA) - return EINVAL; - - /* The READWRITE flag consists of multiple bits. Sanitize. */ - if (scn.sysctl_flags & CTLFLAG_READWRITE) - scn.sysctl_flags |= CTLFLAG_READWRITE; - - /* Validate the node type and size, and do some additional checks. */ - switch (SYSCTL_TYPE(scn.sysctl_flags)) { - case CTLTYPE_BOOL: - if (scn.sysctl_size != sizeof(bool)) - return EINVAL; - break; - case CTLTYPE_INT: - if (scn.sysctl_size != sizeof(int)) - return EINVAL; - break; - case CTLTYPE_QUAD: - if (scn.sysctl_size != sizeof(u_quad_t)) - return EINVAL; - break; - case CTLTYPE_STRING: - /* - * For strings, a zero length means that we are supposed to - * allocate a buffer size based on the given string size. - */ - if (scn.sysctl_size == 0 && scn.sysctl_data != NULL) { - if ((r = mib_copyin_str(newp, - (vir_bytes)scn.sysctl_data, NULL, SSIZE_MAX, - &size)) != OK) - return r; - scn.sysctl_size = size; - } - /* FALLTHROUGH */ - case CTLTYPE_STRUCT: - /* - * We do not set an upper size on the data size, since it would - * still be possible to create a large number of nodes, and - * this is a privileged operation ayway. - */ - if (scn.sysctl_size == 0 || scn.sysctl_size > SSIZE_MAX) - return EINVAL; - if (scn.sysctl_flags & CTLFLAG_IMMEDIATE) - return EINVAL; - break; - case CTLTYPE_NODE: - /* - * The zero size is an API requirement, but we also rely on the - * zero value internally, as the node has no static children. - */ - if (scn.sysctl_size != 0) - return EINVAL; - if (scn.sysctl_flags & (CTLFLAG_IMMEDIATE | CTLFLAG_OWNDATA)) - return EINVAL; - if (scn.sysctl_csize != 0 || scn.sysctl_clen != 0 || - scn.sysctl_child != NULL) - return EINVAL; - break; - default: - return EINVAL; - } - - if (scn.sysctl_func != NULL || scn.sysctl_parent != NULL) - return EINVAL; - - /* Verify that the given name is valid, and get its string length. */ - namelen = mib_check_name(scn.sysctl_name, sizeof(scn.sysctl_name)); - - if (namelen == 0) - return EINVAL; - - /* - * Find a free identifier, or check for ID collisions if a specific - * identifier was given. At the same time, scan for name collisions, - * and find the location at which to insert the new node in the list. - */ - r = mib_scan(parent, scn.sysctl_num, scn.sysctl_name, &id, &prevp, - &node); - - if (r != OK) { - /* - * On collisions, if requested, copy out the existing node. - * This does not quite fit the general interaction model, as - * the service must now return a nonzero old length from a call - * that actually failed (in contrast to ENOMEM failures). - */ - if (r == EEXIST && oldp != NULL) { - len = mib_copyout_node(call, oldp, 0, id, node); - - if (len > 0) - mib_setoldlen(call, len); - } - - return r; - } - - /* - * All checks so far have passed. "id" now contains the new node - * identifier, and "prevp" points to the pointer at which to insert the - * new node in its parent's linked list of dynamic nodes. - * - * We can now attempt to create and initialize a new dynamic node. - * Allocating nodes this way may cause heavy memory fragmentation over - * time, but we do not expect the tree to see heavy modification at run - * time, and the superuser has easier ways to get the MIB service in - * trouble. We note that even in low-memory conditions, the MIB - * service is always able to provide basic functionality. - */ - size = sizeof(*dynode) + namelen; - if (!(scn.sysctl_flags & CTLFLAG_IMMEDIATE)) - size += scn.sysctl_size; - - if ((dynode = malloc(size)) == NULL) - return EINVAL; /* do not return ENOMEM */ - mib_objects++; - - /* From here on, we have to free "dynode" before returning an error. */ - r = OK; - - memset(dynode, 0, sizeof(*dynode)); /* no need to zero all of "size" */ - dynode->dynode_id = id; - strlcpy(dynode->dynode_name, scn.sysctl_name, namelen + 1); - - node = &dynode->dynode_node; - node->node_flags = scn.sysctl_flags & ~SYSCTL_VERS_MASK; - if (SYSCTL_TYPE(scn.sysctl_flags) == CTLTYPE_NODE) - node->node_flags |= CTLFLAG_PARENT; - node->node_size = scn.sysctl_size; - node->node_parent = parent; - node->node_name = dynode->dynode_name; - - /* Initialize the node value. */ - if (scn.sysctl_flags & CTLFLAG_IMMEDIATE) { - switch (SYSCTL_TYPE(scn.sysctl_flags)) { - case CTLTYPE_BOOL: - /* Sanitize booleans. See the C99 _Bool comment. */ - memcpy(&c, &scn.sysctl_bdata, sizeof(c)); - node->node_bool = (bool)c; - break; - case CTLTYPE_INT: - node->node_int = scn.sysctl_idata; - break; - case CTLTYPE_QUAD: - node->node_quad = scn.sysctl_qdata; - break; - default: - assert(0); - } - } else if (SYSCTL_TYPE(scn.sysctl_flags) != CTLTYPE_NODE) { - node->node_data = dynode->dynode_name + namelen + 1; - - /* Did the user supply initial data? If not, use zeroes. */ - if (scn.sysctl_data != NULL) { - /* - * For strings, do not copy in more than needed. This - * is just a nice feature which allows initialization - * of large string buffers with short strings. - */ - if (SYSCTL_TYPE(scn.sysctl_flags) == CTLTYPE_STRING) - r = mib_copyin_str(newp, - (vir_bytes)scn.sysctl_data, - node->node_data, scn.sysctl_size, NULL); - else - r = mib_copyin_aux(newp, - (vir_bytes)scn.sysctl_data, - node->node_data, scn.sysctl_size); - } else - memset(node->node_data, 0, scn.sysctl_size); - - /* - * Sanitize booleans. See the C99 _Bool comment elsewhere. - * In this case it is not as big of a deal, as we will not be - * accessing the boolean value directly ourselves. - */ - if (r == OK && SYSCTL_TYPE(scn.sysctl_flags) == CTLTYPE_BOOL) { - b = (bool)*(char *)node->node_data; - memcpy(node->node_data, &b, sizeof(b)); - } - } - - /* - * Even though it would be entirely possible to set a description right - * away as well, this does not seem to be supported on NetBSD at all. - */ - - /* Deal with earlier failures now. */ - if (r != OK) { - free(dynode); - mib_objects--; - - return r; - } - - /* - * At this point, actual creation can no longer fail. Add the node - * into the tree, and update versions and counters. - */ - mib_add(dynode, prevp); - - /* - * Copy out the newly created node as resulting ("old") data. Do not - * undo the creation if this fails, though. - */ - return mib_copyout_node(call, oldp, 0, id, node); -} - -/* - * Remove the given node from the tree. If 'prevp' is NULL, the node is a - * static node which should be zeroed out. If 'prevp' is not NULL, the node is - * a dynamic node which should be freed; 'prevp' will then point to the pointer - * to its dynode container. Also update versions and counters as appropriate. - * This function never fails. - */ -static void -mib_remove(struct mib_node * node, struct mib_dynode ** prevp) -{ - struct mib_dynode *dynode; - struct mib_node *parent; - - parent = node->node_parent; - assert(parent != NULL); - - /* If the description was allocated, free it. */ - if (node->node_flags & CTLFLAG_OWNDESC) { - free(__UNCONST(node->node_desc)); - mib_objects--; - } - - /* - * Static nodes only use static memory, and dynamic nodes have the data - * area embedded in the dynode object. In neither case is data memory - * allocated separately, and thus, it need never be freed separately. - * Therefore we *must not* check CTLFLAG_OWNDATA here. - */ - - assert(parent->node_csize > 0); - assert(parent->node_clen > 0); - - /* - * Dynamic nodes must be freed. Freeing the dynode object also frees - * the node name and any associated data. Static nodes are zeroed out, - * and the static memory they referenced will become inaccessible. - */ - if (prevp != NULL) { - dynode = *prevp; - *prevp = dynode->dynode_next; - - assert(node == &dynode->dynode_node); - - free(dynode); - mib_objects--; - - parent->node_csize--; - } else - memset(node, 0, sizeof(*node)); - - parent->node_clen--; - - mib_nodes--; - - /* Bump the version of all nodes on the path to the destroyed node. */ - mib_upgrade(parent); -} - -/* - * Destroy a node. - */ -static ssize_t -mib_destroy(struct mib_call * call, struct mib_node * parent, - struct mib_oldp * oldp, struct mib_newp * newp) -{ - struct mib_dynode **prevp; - struct mib_node *node; - struct sysctlnode scn; - ssize_t r; - - /* This is a privileged operation. */ - if (!mib_authed(call)) - return EPERM; - - /* The parent node must not be marked as read-only. */ - if (!(parent->node_flags & CTLFLAG_READWRITE)) - return EPERM; - - /* The caller must specify which child node to destroy. */ - if (newp == NULL) - return EINVAL; - - if ((r = mib_copyin(newp, &scn, sizeof(scn))) != OK) - return r; - - if (SYSCTL_VERS(scn.sysctl_flags) != SYSCTL_VERSION) - return EINVAL; - - /* Locate the child node. */ - if ((node = mib_find(parent, scn.sysctl_num, &prevp)) == NULL) - return ENOENT; - - /* The node must not be marked as permanent. */ - if (node->node_flags & CTLFLAG_PERMANENT) - return EPERM; - - /* For node-type nodes, extra rules apply. */ - if (SYSCTL_TYPE(node->node_flags) == CTLTYPE_NODE) { - /* The node must not be a mount point. */ - if (node->node_flags & CTLFLAG_REMOTE) - return EBUSY; - - /* The node must not have an associated function. */ - if (!(node->node_flags & CTLFLAG_PARENT)) - return EPERM; - - /* The target node must itself not have child nodes. */ - if (node->node_clen != 0) - return ENOTEMPTY; - } - - /* If the user supplied a version, it must match the node version. */ - if (scn.sysctl_ver != 0 && scn.sysctl_ver != node->node_ver) - return EINVAL; /* NetBSD inconsistently throws ENOENT here */ - - /* If the user supplied a name, it must match the node name. */ - if (scn.sysctl_name[0] != '\0') { - if (memchr(scn.sysctl_name, '\0', - sizeof(scn.sysctl_name)) == NULL) - return EINVAL; - if (strcmp(scn.sysctl_name, node->node_name)) - return EINVAL; /* also ENOENT on NetBSD */ - } - - /* - * Copy out the old node if requested, otherwise return the length - * anyway. The node will be destroyed even if this call fails, - * because that is how NetBSD behaves. - */ - r = mib_copyout_node(call, oldp, 0, scn.sysctl_num, node); - - /* - * Remove the node from the tree. The procedure depends on whether the - * node is static (prevp == NULL) or dynamic (prevp != NULL). Also - * update versions and counters. - */ - mib_remove(node, prevp); - - return r; -} - -/* - * Copy out a node description to userland, using the exchange format for node - * descriptions (namely, a sysctldesc structure). Return the size of the - * object that is (or, if the description falls outside the requested data - * range, would be) copied out on success, or a negative error code on failure. - * The function may return 0 to indicate that nothing was copied out after all. - */ -static ssize_t -mib_copyout_desc(struct mib_call * call, struct mib_oldp * oldp, size_t off, - int id, const struct mib_node * node) -{ - struct sysctldesc *scd; - size_t size; - int r; - - /* Descriptions of private nodes are considered private too. */ - if ((node->node_flags & CTLFLAG_PRIVATE) && !mib_authed(call)) - return 0; - - /* The description length includes the null terminator. */ - if (node->node_desc != NULL) - size = strlen(node->node_desc) + 1; - else - size = 1; - - assert(sizeof(*scd) + size <= sizeof(scratch)); - - scd = (struct sysctldesc *)scratch; - memset(scd, 0, sizeof(*scd)); - scd->descr_num = id; - scd->descr_ver = node->node_ver; - scd->descr_len = size; - if (node->node_desc != NULL) - strlcpy(scd->descr_str, node->node_desc, - sizeof(scratch) - sizeof(*scd)); - else - scd->descr_str[0] = '\0'; - - size += offsetof(struct sysctldesc, descr_str); - - if ((r = mib_copyout(oldp, off, scratch, size)) < 0) - return r; - - /* - * By aligning just the size, we may leave garbage between the entries - * copied out, which is fine because it is userland's own data. - */ - return roundup2(size, sizeof(int32_t)); -} - -/* - * Retrieve node descriptions in bulk, or retrieve or assign a particular - * node's description. - */ -static ssize_t -mib_describe(struct mib_call * call, struct mib_node * parent, - struct mib_oldp * oldp, struct mib_newp * newp) -{ - struct sysctlnode scn; - struct mib_node *node; - struct mib_dynode *dynode; - size_t off; - int r, id; - - /* If new data are given, they identify a particular target node. */ - if (newp != NULL) { - if ((r = mib_copyin(newp, &scn, sizeof(scn))) != OK) - return r; - - if (SYSCTL_VERS(scn.sysctl_flags) != SYSCTL_VERSION) - return EINVAL; - - /* Locate the child node. */ - if ((node = mib_find(parent, scn.sysctl_num, NULL)) == NULL) - return ENOENT; - - /* Descriptions of private nodes are considered private too. */ - if ((node->node_flags & CTLFLAG_PRIVATE) && !mib_authed(call)) - return EPERM; - - /* - * If a description pointer was given, this is a request to - * set the node's description. - */ - if (scn.sysctl_desc != NULL) { - /* Such a request requires superuser privileges. */ - if (!mib_authed(call)) - return EPERM; - - /* - * The node must not be a mount point. Arguably this - * check is not necessary, since we use the description - * of the preexisting underlying node anyway. - */ - if (SYSCTL_TYPE(node->node_flags) == CTLTYPE_NODE && - (node->node_flags & CTLFLAG_REMOTE)) - return EBUSY; - - /* The node must not already have a description. */ - if (node->node_desc != NULL) - return EPERM; - - /* The node must not be marked as permanent. */ - if (node->node_flags & CTLFLAG_PERMANENT) - return EPERM; - - /* - * If the user supplied a version, it must match. - * NetBSD performs this check only when setting - * descriptions, and thus, so do we.. - */ - if (scn.sysctl_ver != 0 && - scn.sysctl_ver != node->node_ver) - return EINVAL; - - /* - * Copy in the description to the scratch buffer. - * The length of the description must be reasonable. - */ - if ((r = mib_copyin_str(newp, - (vir_bytes)scn.sysctl_desc, scratch, MAXDESCLEN, - NULL)) != OK) - return r; - - /* Allocate memory and store the description. */ - if ((node->node_desc = strdup(scratch)) == NULL) { - printf("MIB: out of memory!\n"); - - return EINVAL; /* do not return ENOMEM */ - } - mib_objects++; - - /* The description must now be freed with the node. */ - node->node_flags |= CTLFLAG_OWNDESC; - } - - /* - * Either way, copy out the requested node's description, which - * should indeed be the new description if one was just set. - * Note that we have already performed the permission check - * that could make this call return zero, so here it will not. - */ - return mib_copyout_desc(call, oldp, 0, scn.sysctl_num, node); - } - - /* See also the considerations laid out in mib_query(). */ - off = 0; - - /* First describe the static nodes. */ - for (id = 0; IS_STATIC_ID(parent, id); id++) { - node = &parent->node_scptr[id]; - - if (node->node_flags == 0) - continue; - - if ((r = mib_copyout_desc(call, oldp, off, id, node)) < 0) - return r; - off += r; - } - - /* Then describe the dynamic nodes. */ - for (dynode = parent->node_dcptr; dynode != NULL; - dynode = dynode->dynode_next) { - node = &dynode->dynode_node; - - if ((r = mib_copyout_desc(call, oldp, off, dynode->dynode_id, - node)) < 0) - return r; - off += r; - } - - return off; -} - -/* - * Return a pointer to the data associated with the given node, or NULL if the - * node has no associated data. Actual calls to this function should never - * result in NULL - as long as the proper rules are followed elsewhere. - */ -static void * -mib_getptr(struct mib_node * node) -{ - - switch (SYSCTL_TYPE(node->node_flags)) { - case CTLTYPE_BOOL: - if (node->node_flags & CTLFLAG_IMMEDIATE) - return &node->node_bool; - break; - case CTLTYPE_INT: - if (node->node_flags & CTLFLAG_IMMEDIATE) - return &node->node_int; - break; - case CTLTYPE_QUAD: - if (node->node_flags & CTLFLAG_IMMEDIATE) - return &node->node_quad; - break; - case CTLTYPE_STRING: - case CTLTYPE_STRUCT: - if (node->node_flags & CTLFLAG_IMMEDIATE) - return NULL; - break; - default: - return NULL; - } - - return node->node_data; -} - -/* - * Read current (old) data from a regular data node, if requested. Return the - * old data length. - */ -static ssize_t -mib_read(struct mib_node * node, struct mib_oldp * oldp) -{ - void *ptr; - size_t oldlen; - int r; - - if ((ptr = mib_getptr(node)) == NULL) - return EINVAL; - - if (SYSCTL_TYPE(node->node_flags) == CTLTYPE_STRING) - oldlen = strlen(node->node_data) + 1; - else - oldlen = node->node_size; - - if (oldlen > SSIZE_MAX) - return EINVAL; - - /* Copy out the current data, if requested at all. */ - if (oldp != NULL && (r = mib_copyout(oldp, 0, ptr, oldlen)) < 0) - return r; - - /* Return the current length in any case. */ - return (ssize_t)oldlen; -} - -/* - * Write new data into a regular data node, if requested. - */ -static int -mib_write(struct mib_call * call, struct mib_node * node, - struct mib_newp * newp, mib_verify_ptr verify) -{ - bool b[(sizeof(bool) == sizeof(char)) ? 1 : -1]; /* explained below */ - char *src, *dst; - size_t newlen; - int r; - - if (newp == NULL) - return OK; /* nothing to do */ - - /* - * When setting a new value, we cannot risk doing an in-place update: - * the copy from userland may fail halfway through, in which case an - * in-place update could leave the node value in a corrupted state. - * Thus, we must first fetch any new data into a temporary buffer. - * - * Given that we use intermediate data storage, we could support value - * swapping, where the user provides the same buffer for new and old - * data. We choose not to: NetBSD does not support it, it would make - * trace(1)'s job a lot harder, and it would convolute the code here. - */ - newlen = mib_getnewlen(newp); - - if ((dst = mib_getptr(node)) == NULL) - return EINVAL; - - switch (SYSCTL_TYPE(node->node_flags)) { - case CTLTYPE_BOOL: - case CTLTYPE_INT: - case CTLTYPE_QUAD: - case CTLTYPE_STRUCT: - /* Non-string types must have an exact size match. */ - if (newlen != node->node_size) - return EINVAL; - break; - case CTLTYPE_STRING: - /* - * Strings must not exceed their buffer size. There is a - * second check further below, because we allow userland to - * give us an unterminated string. In that case we terminate - * it ourselves, but then the null terminator must fit as well. - */ - if (newlen > node->node_size) - return EINVAL; - break; - default: - return EINVAL; - } - - /* - * If we cannot fit the data in the scratch buffer, then allocate a - * temporary buffer. We add one extra byte so that we can add a null - * terminator at the end of strings in case userland did not supply - * one. Either way, we must free the temporary buffer later! - * - * The alternative is to ensure that the given memory is accessible - * before starting the copy, but that would break if we ever add kernel - * threads or anything that allows asynchronous memory unmapping, etc. - */ - if (newlen + 1 > sizeof(scratch)) { - /* - * In practice, the temporary buffer is at least an entire - * memory page, which is reasonable by any standard. As a - * result, we can get away with refusing to perform dynamic - * allocation for unprivileged users. This limits the impact - * that unprivileged users can have on our memory space. - */ - if (!mib_authed(call)) - return EPERM; - - /* - * Do not return ENOMEM on allocation failure, because ENOMEM - * implies that a valid old length was returned. - */ - if ((src = malloc(newlen + 1)) == NULL) { - printf("MIB: out of memory!\n"); - - return EINVAL; - } - mib_objects++; - } else - src = scratch; - - /* Copy in the data. Note that newlen may be zero. */ - r = mib_copyin(newp, src, newlen); - - if (r == OK && verify != NULL && !verify(call, node, src, newlen)) - r = EINVAL; - - if (r == OK) { - /* Check and, if acceptable, store the new value. */ - switch (SYSCTL_TYPE(node->node_flags)) { - case CTLTYPE_BOOL: - /* - * Due to the nature of the C99 _Bool type, we can not - * test directly whether the given boolean value is a - * value that is not "true" and not "false". In the - * worst case, another value could invoke undefined - * behavior. We try our best to sanitize the value - * without looking at it directly, which unfortunately - * requires us to test for the size of the bool type. - * We do that at compile time, hence the 'b' "array". - * Any size other than one byte is an ABI violation. - */ - b[0] = (bool)src[0]; - memcpy(dst, &b[0], sizeof(b[0])); - break; - case CTLTYPE_INT: - case CTLTYPE_QUAD: - case CTLTYPE_STRUCT: - memcpy(dst, src, node->node_size); - break; - case CTLTYPE_STRING: - if (newlen == node->node_size && - src[newlen - 1] != '\0') { - /* Our null terminator does not fit! */ - r = EINVAL; - break; - } - /* - * We do not mind null characters in the middle. In - * general, the buffer may contain garbage after the - * first null terminator, but such garbage will never - * end up being copied out. - */ - src[newlen] = '\0'; - strlcpy(dst, src, node->node_size); - break; - default: - r = EINVAL; - } - } - - if (src != scratch) { - free(src); - mib_objects--; - } - - return r; -} - -/* - * Read and/or write the value of a regular data node. A regular data node is - * a leaf node. Typically, a leaf node has no associated function, in which - * case this function will be used instead. In addition, this function may be - * used from handler functions as part of their functionality. - */ -ssize_t -mib_readwrite(struct mib_call * call, struct mib_node * node, - struct mib_oldp * oldp, struct mib_newp * newp, mib_verify_ptr verify) -{ - ssize_t len; - int r; - - /* Copy out old data, if requested. Always get the old data length. */ - if ((r = len = mib_read(node, oldp)) < 0) - return r; - - /* Copy in new data, if requested. */ - if ((r = mib_write(call, node, newp, verify)) != OK) - return r; - - /* Return the old data length. */ - return len; -} - -/* - * Dispatch a sysctl call, by looking up the target node by its MIB name and - * taking the appropriate action on the resulting node, if found. Return the - * old data length on success, or a negative error code on failure. - */ -ssize_t -mib_dispatch(struct mib_call * call, struct mib_oldp * oldp, - struct mib_newp * newp) -{ - struct mib_node *parent, *node; - ssize_t r; - int id, is_leaf, can_restart, has_verify, has_func; - - assert(call->call_namelen <= CTL_MAXNAME); - - /* - * Resolve the name by descending into the node tree, level by level, - * starting at the MIB root. - */ - for (parent = &mib_root; call->call_namelen > 0; parent = node) { - id = call->call_name[0]; - call->call_name++; - call->call_namelen--; - - assert(SYSCTL_TYPE(parent->node_flags) == CTLTYPE_NODE); - assert(parent->node_flags & CTLFLAG_PARENT); - - /* - * Check for meta-identifiers. Regular identifiers are never - * negative, although node handler functions may take subpaths - * with negative identifiers that are not meta-identifiers - * (e.g., see KERN_PROC2). - */ - if (id < 0) { - /* - * A meta-identifier must always be the last name - * component. - */ - if (call->call_namelen > 0) - return EINVAL; - - switch (id) { - case CTL_QUERY: - return mib_query(call, parent, oldp, newp); - case CTL_CREATE: - return mib_create(call, parent, oldp, newp); - case CTL_DESTROY: - return mib_destroy(call, parent, oldp, newp); - case CTL_DESCRIBE: - return mib_describe(call, parent, oldp, newp); - case CTL_CREATESYM: - case CTL_MMAP: - default: - return EOPNOTSUPP; - } - } - - /* Locate the child node. */ - if ((node = mib_find(parent, id, NULL /*prevp*/)) == NULL) - return ENOENT; - - /* Check if access is permitted at this level. */ - if ((node->node_flags & CTLFLAG_PRIVATE) && !mib_authed(call)) - return EPERM; - - /* - * Start by checking if the node is a remote node. If so, let - * a remote service handle the remainder of this request. - * However, as part of attempting the remote call, we may - * discover that the remote service has died or that it is - * unmounting the subtree. If the node was not a temporary - * mountpoint, we should (and do) continue with the request - * locally - if it was, it will already be deallocated and we - * must be very careful not to access 'node' again! - */ - is_leaf = (SYSCTL_TYPE(node->node_flags) != CTLTYPE_NODE); - - if (!is_leaf && (node->node_flags & CTLFLAG_REMOTE)) { - /* Determine this before 'node' may disappear.. */ - can_restart = (node->node_flags & CTLFLAG_PARENT); - - r = mib_remote_call(call, node, oldp, newp); - - if (r != ERESTART || !can_restart) - return (r != ERESTART) ? r : ENOENT; - - /* Service died, subtree is unmounted, keep going. */ - assert(SYSCTL_TYPE(node->node_flags) == CTLTYPE_NODE); - assert(!(node->node_flags & CTLFLAG_REMOTE)); - } - - /* - * Is this a leaf node, and/or is this node handled by a - * function? If either is true, resolution ends at this level. - * In order to save a few bytes of memory per node, we use - * different ways to determine whether there is a function - * depending on whether the node is a leaf or not. - */ - if (is_leaf) { - has_verify = (node->node_flags & CTLFLAG_VERIFY); - has_func = (!has_verify && node->node_func != NULL); - } else { - has_verify = FALSE; - has_func = !(node->node_flags & CTLFLAG_PARENT); - } - - /* - * The name may be longer only if the node is not a leaf. That - * also applies to leaves with functions, so check this first. - */ - if (is_leaf && call->call_namelen > 0) - return ENOTDIR; - - /* - * If resolution indeed ends here, and the user supplied new - * data, check if writing is allowed. For functions, it is - * arguable whether we should do this check here already. - * However, for now, this approach covers all our use cases. - */ - if ((is_leaf || has_func) && newp != NULL) { - if (!(node->node_flags & CTLFLAG_READWRITE)) - return EPERM; - - /* - * Unless nonprivileged users may write to this node, - * ensure that the user has superuser privileges. The - * ANYWRITE flag does not override the READWRITE flag. - */ - if (!(node->node_flags & CTLFLAG_ANYWRITE) && - !mib_authed(call)) - return EPERM; - } - - /* If this node has a handler function, let it do the work. */ - if (has_func) - return node->node_func(call, node, oldp, newp); - - /* For regular data leaf nodes, handle generic access. */ - if (is_leaf) - return mib_readwrite(call, node, oldp, newp, - has_verify ? node->node_verify : NULL); - - /* No function and not a leaf? Descend further. */ - } - - /* If we get here, the name refers to a node array. */ - return EISDIR; -} - -/* - * Recursively initialize the static tree at initialization time. - */ -static void -mib_tree_recurse(struct mib_node * parent) -{ - struct mib_node *node; - int id; - - assert(SYSCTL_TYPE(parent->node_flags) == CTLTYPE_NODE); - assert(parent->node_flags & CTLFLAG_PARENT); - - /* - * Later on, node_csize and node_clen will also include dynamically - * created nodes. This means that we cannot use node_csize to iterate - * over the static nodes. - */ - parent->node_csize = parent->node_size; - - node = parent->node_scptr; - - for (id = 0; IS_STATIC_ID(parent, id); id++, node++) { - if (node->node_flags == 0) - continue; - - mib_nodes++; - - parent->node_clen++; - - node->node_ver = parent->node_ver; - node->node_parent = parent; - - /* Recursively apply this function to all node children. */ - if (SYSCTL_TYPE(node->node_flags) == CTLTYPE_NODE && - (node->node_flags & CTLFLAG_PARENT)) - mib_tree_recurse(node); - } -} - -/* - * Go through the entire static tree, recursively, initializing some values - * that could not be assigned at compile time. - */ -void -mib_tree_init(void) -{ - - /* Initialize some variables. */ - mib_nodes = 1; /* the root node itself */ - mib_objects = 0; - - /* - * The entire tree starts with the same, nonzero node version. - * The root node is the only node without a parent. - */ - mib_root.node_ver = 1; - mib_root.node_parent = NULL; - - /* Recursively initialize the static tree. */ - mib_tree_recurse(&mib_root); -} - -/* - * Process a subtree mount request from a remote service. Return OK on - * success, with a pointer to the resulting static-node structure stored in - * 'nodep'. Return a negative error code on failure. - */ -int -mib_mount(const int * mib, unsigned int miblen, unsigned int eid, uint32_t rid, - uint32_t flags, unsigned int csize, unsigned int clen, - struct mib_node ** nodep) -{ - struct mib_dynode *dynode, **prevp; - struct mib_node *parent, *node; - char name[SYSCTL_NAMELEN], *desc; - size_t size, namelen, desclen; - unsigned int n; - int r, id; - - /* - * Perform initial verification of the given parameters. Even stricter - * checks may be performed later. - */ - /* - * By policy, we forbid mounting top-level nodes. This is in effect - * also the only security-like restriction: a service should not be - * able to just take over, say, the entire "kern" subtree. There is - * currently little in the way of a service taking over an important - * set of second-level nodes, though. - * - * TODO: allow mounting of predefined mount points only, for example by - * having an internal node flag that permits mounting the subtree or - * any node in it. As an even better alternative, allow this to be - * controlled through a policy specification; unfortunately, this would - * also add a substantial amount of infrastructure. - */ - if (miblen < 2) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, path too short\n")); - - return EPERM; - } - - /* - * The flags field is highly restricted right now. Only a few flags - * may be given at all, and then when using an existing node as mount - * point, the flag must exactly match the existing node's flags. - */ - if (SYSCTL_VERS(flags) != SYSCTL_VERSION || - SYSCTL_TYPE(flags) != CTLTYPE_NODE || - (SYSCTL_FLAGS(flags) & ~(CTLFLAG_READONLY | CTLFLAG_READWRITE | - CTLFLAG_PERMANENT | CTLFLAG_HIDDEN)) != 0) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, invalid flags %"PRIx32 - "\n", flags)); - - return EINVAL; - } - - if (csize > (1U << MIB_RC_BITS) || clen > csize) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, invalid child size or " - "length (%u, %u)\n", csize, clen)); - - return EINVAL; - } - - /* - * Look up the parent node of the mount point. This parent node must - * exist - we don't want to create more than one temporary node in any - * case. All the nodes leading up to and including the parent node - * must be real, local, non-private, node-type nodes. The path may not - * be private, because that would allow an unprivileged service to - * intercept writes to privileged nodes--currently a total nonissue in - * practice, but still. Note that the service may itself restrict - * access to nodes in its own mounted subtree in any way it wishes. - */ - parent = &mib_root; - - for (n = 0; n < miblen - 1; n++) { - /* Meta-identifiers are obviously not allowed in the path. */ - if ((id = mib[n]) < 0) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, meta-ID in " - "path\n")); - - return EINVAL; - } - - /* Locate the child node. */ - if ((node = mib_find(parent, id, NULL /*prevp*/)) == NULL) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, path not " - "found\n")); - - return ENOENT; - } - - /* Make sure it is a regular node-type node. */ - if (SYSCTL_TYPE(node->node_flags) != CTLTYPE_NODE || - !(node->node_flags & CTLFLAG_PARENT) || - (node->node_flags & (CTLFLAG_REMOTE | CTLFLAG_PRIVATE))) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, unacceptable " - "node on path\n")); - - return EPERM; - } - - parent = node; - } - - /* Now see if the mount point itself exists. */ - if ((id = mib[miblen - 1]) < 0) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, meta-ID in path\n")); - - return EINVAL; - } - - /* - * If the target node exists and passes all tests, it will simply be - * converted to a mount point. If the target node does not exist, we - * have to allocate a temporary node as mount point. - */ - if ((node = mib_find(parent, id, NULL /*prevp*/)) != NULL) { - /* - * We are about to mount on an existing node. As stated above, - * the node flags must match the given flags exactly. - */ - if (SYSCTL_TYPE(node->node_flags) != CTLTYPE_NODE || - SYSCTL_FLAGS(node->node_flags) != - (SYSCTL_FLAGS(flags) | CTLFLAG_PARENT)) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, target node " - "mismatch (%"PRIx32", %"PRIx32")\n", - node->node_flags, flags)); - - return EPERM; - } - - /* - * If the node has dynamically added children, we will not be - * able to restore the node to its old state when unmounting. - */ - if (node->node_size != node->node_csize) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, node has " - "dynamic children\n")); - - return EBUSY; - } - - mib_upgrade(node); - } else { - /* - * We are going to create a temporary mount point. Much of the - * procedure that follows is a rather selective extract from - * mib_create(). Start with a check for the impossible. - */ - if (parent->node_csize == INT_MAX) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, parent node " - "full\n")); - - return EINVAL; - } - - /* - * In order to create the new node, we also need the node's - * name and description; those did not fit in the request - * message. Ask the caller to copy these strings to us. - */ - name[0] = '\0'; - scratch[0] = '\0'; - - if ((r = mib_remote_info(eid, rid, name, sizeof(name), scratch, - MAXDESCLEN)) != OK) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, node info " - "request yielded %d\n", r)); - - return r; - } - - /* Make sure the name is valid. */ - if ((namelen = mib_check_name(name, sizeof(name))) == 0) { - printf("MIB: mounting failed, bad name\n"); - - return EINVAL; - } - - /* Just forcefully terminate the description. */ - scratch[MAXDESCLEN - 1] = '\0'; - desclen = strlen(scratch); - - /* - * We know the identifier is not in use yet; make sure that the - * name is not, either. As a side effect, find out where the - * new node should be inserted upon success. - */ - if (mib_scan(parent, id, name, &id /*unused*/, &prevp, - &node /*unused*/) != OK) { - MIB_DEBUG_MOUNT(("MIB: mounting failed, name " - "conflict\n")); - - return EEXIST; - } - - /* - * Allocate a dynamic node. Unlike for user-created dynamic - * nodes, temporary mount points also include the description - * in the dynode object. - */ - size = sizeof(*dynode) + namelen + desclen + 1; - - if ((dynode = malloc(size)) == NULL) { - printf("MIB: out of memory!\n"); - - return ENOMEM; - } - mib_objects++; - - /* Initialize the dynamic node. */ - memset(dynode, 0, sizeof(*dynode)); - dynode->dynode_id = id; - strlcpy(dynode->dynode_name, name, namelen + 1); - desc = &dynode->dynode_name[namelen + 1]; - strlcpy(desc, scratch, desclen + 1); - - node = &dynode->dynode_node; - node->node_flags = flags & ~SYSCTL_VERS_MASK; - node->node_size = 0; - node->node_parent = parent; - node->node_name = dynode->dynode_name; - node->node_desc = desc; - - /* - * Add the new dynamic node into the tree, and adjust versions - * and counters. - */ - mib_add(dynode, prevp); - } - - /* Success! Perform the actual mount, and return the target node. */ - node->node_flags |= CTLFLAG_REMOTE; - node->node_eid = eid; - node->node_rcsize = csize; - node->node_rclen = clen; - node->node_rid = rid; - - mib_remotes++; - - *nodep = node; - return OK; -} - -/* - * Unmount the remote subtree identified by the given node. Release the mount - * point by reversing the action performed while mounting. Also bump the - * version numbers on the path, so that userland knows that it is to expect a - * change of contents in the subtree. This function always succeeds, and may - * deallocate the given node. - */ -void -mib_unmount(struct mib_node * node) -{ - struct mib_dynode **prevp; - struct mib_node *child; - int id; - - assert(SYSCTL_TYPE(node->node_flags) == CTLTYPE_NODE); - assert(node->node_flags & CTLFLAG_REMOTE); - - /* - * Given that the node has the CTLFLAG_REMOTE flag set, we can now tell - * whether the remote subtree obscured a preexisting node or we created - * a temporary mount point, by checking its CTLFLAG_PARENT flag. - */ - if (node->node_flags & CTLFLAG_PARENT) { - /* - * Return the node to its former pre-mount state. Restore the - * original node_clen field by recomputing it. - */ - node->node_flags &= ~CTLFLAG_REMOTE; - node->node_csize = node->node_size; - node->node_clen = 0; - - for (id = 0; IS_STATIC_ID(node, id); id++) { - child = &node->node_scptr[id]; - - if (child->node_flags != 0) - node->node_clen++; - } - - node->node_dcptr = NULL; - - /* Increase version numbers on the path to the node. */ - mib_upgrade(node); - } else { - /* - * We know that we dynamically allocated this node; find its - * parent's pointer to it. - */ - for (prevp = &node->node_parent->node_dcptr; *prevp != NULL; - prevp = &(*prevp)->dynode_next) { - if (&(*prevp)->dynode_node == node) - break; - } - assert(*prevp != NULL); - - /* Free the node, and adjust counts and versions. */ - mib_remove(node, prevp); - } - - assert(mib_remotes > 0); - mib_remotes--; -} diff --git a/minix/servers/mib/vm.c b/minix/servers/mib/vm.c deleted file mode 100644 index 5a9844fcd..000000000 --- a/minix/servers/mib/vm.c +++ /dev/null @@ -1,154 +0,0 @@ -/* MIB service - vm.c - implementation of the CTL_VM subtree */ - -#include "mib.h" - -#include -#include - -/* - * Implementation of CTL_VM VM_LOADAVG. - */ -static ssize_t -mib_vm_loadavg(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - struct loadavg loadavg; - struct loadinfo loadinfo; - unsigned long proc_load; - u32_t ticks_per_slot, ticks; - unsigned int p; - int unfilled_ticks; - int h, slots, latest, slot; - int minutes[3] = { 1, 5, 15 }; - - assert(__arraycount(loadavg.ldavg) == __arraycount(minutes)); - - if (sys_getloadinfo(&loadinfo) != OK) - return EINVAL; - - memset(&loadavg, 0, sizeof(loadavg)); - - /* - * The following code is inherited from the old MINIX libc. - */ - - /* How many ticks are missing from the newest-filled slot? */ - ticks_per_slot = _LOAD_UNIT_SECS * sys_hz(); - unfilled_ticks = - ticks_per_slot - (loadinfo.last_clock % ticks_per_slot); - - for (p = 0; p < __arraycount(loadavg.ldavg); p++) { - latest = loadinfo.proc_last_slot; - slots = minutes[p] * 60 / _LOAD_UNIT_SECS; - proc_load = 0; - - /* - * Add up the total number of process ticks for this number - * of minutes (minutes[p]). Start with the newest slot, which - * is latest, and count back for the number of slots that - * correspond to the right number of minutes. Take wraparound - * into account by calculating the index modulo _LOAD_HISTORY, - * which is the number of slots of history kept. - */ - for (h = 0; h < slots; h++) { - slot = (latest - h + _LOAD_HISTORY) % _LOAD_HISTORY; - proc_load += loadinfo.proc_load_history[slot]; - } - - /* - * The load average over this number of minutes is the number - * of process-ticks divided by the number of ticks, not - * counting the number of ticks the last slot hasn't been - * around yet. - */ - ticks = slots * ticks_per_slot - unfilled_ticks; - - loadavg.ldavg[p] = 100UL * proc_load / ticks; - } - - loadavg.fscale = 100L; - - return mib_copyout(oldp, 0, &loadavg, sizeof(loadavg)); -} - -/* - * Implementation of CTL_VM VM_UVMEXP2. - */ -static ssize_t -mib_vm_uvmexp2(struct mib_call * call __unused, - struct mib_node * node __unused, struct mib_oldp * oldp, - struct mib_newp * newp __unused) -{ - struct vm_stats_info vsi; - struct uvmexp_sysctl ues; - unsigned int shift; - - if (vm_info_stats(&vsi) != OK) - return EINVAL; - - memset(&ues, 0, sizeof(ues)); - - /* - * TODO: by far most of the structure is not filled correctly yet, - * since the MINIX3 system does not provide much of the information - * exposed by NetBSD. This will gradually have to be filled in. - * For now, we provide just some basic information used by top(1). - */ - ues.pagesize = vsi.vsi_pagesize; - ues.pagemask = vsi.vsi_pagesize - 1; - for (shift = 0; shift < CHAR_BIT * sizeof(void *); shift++) - if ((1U << shift) == vsi.vsi_pagesize) - break; - if (shift < CHAR_BIT * sizeof(void *)) - ues.pageshift = shift; - ues.npages = vsi.vsi_total; - ues.free = vsi.vsi_free; - ues.filepages = vsi.vsi_cached; - /* - * We use one of the structure's unused fields to expose information - * not exposed by NetBSD, namely the largest area of physically - * contiguous memory. If NetBSD repurposes this field, we have to find - * another home for it (or expose it through a separate node or so). - */ - ues.unused1 = vsi.vsi_largest; - - return mib_copyout(oldp, 0, &ues, sizeof(ues)); -} - -/* The CTL_VM nodes. */ -static struct mib_node mib_vm_table[] = { -/* 1*/ /* VM_METER: not yet supported */ -/* 2*/ [VM_LOADAVG] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, - sizeof(struct loadavg), mib_vm_loadavg, - "loadavg", "System load average history"), -/* 3*/ /* VM_UVMEXP: not yet supported */ -/* 4*/ /* VM_NKMEMPAGES: not yet supported */ -/* 5*/ [VM_UVMEXP2] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, - sizeof(struct uvmexp_sysctl), - mib_vm_uvmexp2, "uvmexp2", - "Detailed system-wide virtual memory " - "statistics (MI)"), -/* 6*/ /* VM_ANONMIN: not yet supported */ -/* 7*/ /* VM_EXECMIN: not yet supported */ -/* 8*/ /* VM_FILEMIN: not yet supported */ -/* 9*/ [VM_MAXSLP] = MIB_INT(_P | _RO, MAXSLP, "maxslp", - "Maximum process sleep time before being " - "swapped"), -/*10*/ [VM_USPACE] = MIB_INT(_P | _RO, 0, "uspace", "Number of " - "bytes allocated for a kernel stack"), - /* MINIX3 processes don't have k-stacks */ -/*11*/ /* VM_ANONMAX: not yet supported */ -/*12*/ /* VM_EXECMAX: not yet supported */ -/*13*/ /* VM_FILEMAX: not yet supported */ -}; - -/* - * Initialize the CTL_VM subtree. - */ -void -mib_vm_init(struct mib_node * node) -{ - - MIB_INIT_ENODE(node, mib_vm_table); -} diff --git a/minix/servers/pm/Makefile b/minix/servers/pm/Makefile deleted file mode 100644 index 72a9f43a8..000000000 --- a/minix/servers/pm/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -.include - -# Makefile for Process Manager (PM) -PROG= pm -SRCS= main.c forkexit.c exec.c time.c alarm.c \ - signal.c utility.c table.c trace.c getset.c misc.c \ - profile.c mcontext.c schedule.c event.c - -DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers - -CPPFLAGS.main.c+= -I${NETBSDSRCDIR}/minix -CPPFLAGS.misc.c+= -I${NETBSDSRCDIR}/minix -CPPFLAGS.schedule.c+= -I${NETBSDSRCDIR}/minix -CPPFLAGS.utility.c+= -I${NETBSDSRCDIR}/minix - -.include diff --git a/minix/servers/pm/getset.c b/minix/servers/pm/getset.c deleted file mode 100644 index f3d2e1202..000000000 --- a/minix/servers/pm/getset.c +++ /dev/null @@ -1,223 +0,0 @@ -/* This file handles the 6 system calls that get and set uids and gids. - * It also handles getpid(), setsid(), and getpgrp(). The code for each - * one is so tiny that it hardly seemed worthwhile to make each a separate - * function. - */ - -#include "pm.h" -#include -#include -#include -#include -#include -#include "mproc.h" - -/*===========================================================================* - * do_get * - *===========================================================================*/ -int -do_get(void) -{ -/* Handle PM_GETUID, PM_GETGID, PM_GETGROUPS, PM_GETPID, PM_GETPGRP, PM_GETSID, - * PM_ISSETUGID. - */ - register struct mproc *rmp = mp; - int r; - int ngroups; - - switch(call_nr) { - case PM_GETGROUPS: - ngroups = m_in.m_lc_pm_groups.num; - if (ngroups > NGROUPS_MAX || ngroups < 0) - return(EINVAL); - - if (ngroups == 0) { - r = rmp->mp_ngroups; - break; - } - - if (ngroups < rmp->mp_ngroups) - /* Asking for less groups than available */ - return(EINVAL); - - r = sys_datacopy(SELF, (vir_bytes) rmp->mp_sgroups, who_e, - m_in.m_lc_pm_groups.ptr, ngroups * sizeof(gid_t)); - - if (r != OK) - return(r); - - r = rmp->mp_ngroups; - break; - case PM_GETUID: - r = rmp->mp_realuid; - rmp->mp_reply.m_pm_lc_getuid.euid = rmp->mp_effuid; - break; - - case PM_GETGID: - r = rmp->mp_realgid; - rmp->mp_reply.m_pm_lc_getgid.egid = rmp->mp_effgid; - break; - - case PM_GETPID: - r = mproc[who_p].mp_pid; - rmp->mp_reply.m_pm_lc_getpid.parent_pid = mproc[rmp->mp_parent].mp_pid; - break; - - case PM_GETPGRP: - r = rmp->mp_procgrp; - break; - - case PM_GETSID: - { - struct mproc *target; - pid_t p = m_in.m_lc_pm_getsid.pid; - target = p ? find_proc(p) : &mproc[who_p]; - r = ESRCH; - if(target) - r = target->mp_procgrp; - break; - } - case PM_ISSETUGID: - r = !!(rmp->mp_flags & TAINTED); - break; - - default: - r = EINVAL; - break; - } - return(r); -} - -/*===========================================================================* - * do_set * - *===========================================================================*/ -int -do_set(void) -{ -/* Handle PM_SETUID, PM_SETEUID, PM_SETGID, PM_SETGROUPS, PM_SETEGID, and - * SETSID. These calls have in common that, if successful, they will be - * forwarded to VFS as well. - */ - register struct mproc *rmp = mp; - message m; - int r, i; - int ngroups; - uid_t uid; - gid_t gid; - - memset(&m, 0, sizeof(m)); - - switch(call_nr) { - case PM_SETUID: - uid = m_in.m_lc_pm_setuid.uid; - /* NetBSD specific semantics: setuid(geteuid()) may fail. */ - if (rmp->mp_realuid != uid && rmp->mp_effuid != SUPER_USER) - return(EPERM); - /* BSD semantics: always update all three fields. */ - rmp->mp_realuid = uid; - rmp->mp_effuid = uid; - rmp->mp_svuid = uid; - - m.m_type = VFS_PM_SETUID; - m.VFS_PM_ENDPT = rmp->mp_endpoint; - m.VFS_PM_EID = rmp->mp_effuid; - m.VFS_PM_RID = rmp->mp_realuid; - - break; - - case PM_SETEUID: - uid = m_in.m_lc_pm_setuid.uid; - /* BSD semantics: seteuid(geteuid()) may fail. */ - if (rmp->mp_realuid != uid && rmp->mp_svuid != uid && - rmp->mp_effuid != SUPER_USER) - return(EPERM); - rmp->mp_effuid = uid; - - m.m_type = VFS_PM_SETUID; - m.VFS_PM_ENDPT = rmp->mp_endpoint; - m.VFS_PM_EID = rmp->mp_effuid; - m.VFS_PM_RID = rmp->mp_realuid; - - break; - - case PM_SETGID: - gid = m_in.m_lc_pm_setgid.gid; - if (rmp->mp_realgid != gid && rmp->mp_effuid != SUPER_USER) - return(EPERM); - rmp->mp_realgid = gid; - rmp->mp_effgid = gid; - rmp->mp_svgid = gid; - - m.m_type = VFS_PM_SETGID; - m.VFS_PM_ENDPT = rmp->mp_endpoint; - m.VFS_PM_EID = rmp->mp_effgid; - m.VFS_PM_RID = rmp->mp_realgid; - - break; - - case PM_SETEGID: - gid = m_in.m_lc_pm_setgid.gid; - if (rmp->mp_realgid != gid && rmp->mp_svgid != gid && - rmp->mp_effuid != SUPER_USER) - return(EPERM); - rmp->mp_effgid = gid; - - m.m_type = VFS_PM_SETGID; - m.VFS_PM_ENDPT = rmp->mp_endpoint; - m.VFS_PM_EID = rmp->mp_effgid; - m.VFS_PM_RID = rmp->mp_realgid; - - break; - - case PM_SETGROUPS: - if (rmp->mp_effuid != SUPER_USER) - return(EPERM); - - ngroups = m_in.m_lc_pm_groups.num; - - if (ngroups > NGROUPS_MAX || ngroups < 0) - return(EINVAL); - - if (ngroups > 0 && m_in.m_lc_pm_groups.ptr == 0) - return(EFAULT); - - r = sys_datacopy(who_e, m_in.m_lc_pm_groups.ptr, SELF, - (vir_bytes) rmp->mp_sgroups, - ngroups * sizeof(gid_t)); - if (r != OK) - return(r); - - for (i = 0; i < ngroups; i++) { - if (rmp->mp_sgroups[i] > GID_MAX) - return(EINVAL); - } - for (i = ngroups; i < NGROUPS_MAX; i++) { - rmp->mp_sgroups[i] = 0; - } - rmp->mp_ngroups = ngroups; - - m.m_type = VFS_PM_SETGROUPS; - m.VFS_PM_ENDPT = rmp->mp_endpoint; - m.VFS_PM_GROUP_NO = rmp->mp_ngroups; - m.VFS_PM_GROUP_ADDR = (char *) rmp->mp_sgroups; - - break; - case PM_SETSID: - if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM); - rmp->mp_procgrp = rmp->mp_pid; - - m.m_type = VFS_PM_SETSID; - m.VFS_PM_ENDPT = rmp->mp_endpoint; - - break; - - default: - return(EINVAL); - } - - /* Send the request to VFS */ - tell_vfs(rmp, &m); - - /* Do not reply until VFS has processed the request */ - return(SUSPEND); -} diff --git a/minix/servers/rs/Makefile b/minix/servers/rs/Makefile deleted file mode 100644 index 3edcb53f4..000000000 --- a/minix/servers/rs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -.include - -# Makefile for Reincarnation Server (RS) -PROG= rs -SRCS= exec.c main.c request.c manager.c table.c utility.c error.c update.c - -.if ${USE_PCI} != "no" -CPPFLAGS+= -DUSE_PCI -.endif - -.if ${USE_PCI} != "no" -CPPFLAGS+= -DUSE_PCI -.endif - -DPADD+= ${LIBSYS} ${LIBEXEC} -LDADD+= -lsys -lexec - -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -.include diff --git a/minix/servers/vfs/path.c b/minix/servers/vfs/path.c deleted file mode 100644 index 5360d2c1f..000000000 --- a/minix/servers/vfs/path.c +++ /dev/null @@ -1,933 +0,0 @@ -/* lookup() is the main routine that controls the path name lookup. It - * handles mountpoints and symbolic links. The actual lookup requests - * are sent through the req_lookup wrapper function. - */ - -#include "fs.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vmnt.h" -#include "vnode.h" -#include "path.h" - -/* Set to following define to 1 if you really want to use the POSIX definition - * (IEEE Std 1003.1, 2004) of pathname resolution. POSIX requires pathnames - * with a traling slash (and that do not entirely consist of slash characters) - * to be treated as if a single dot is appended. This means that for example - * mkdir("dir/", ...) and rmdir("dir/") will fail because the call tries to - * create or remove the directory '.'. Historically, Unix systems just ignore - * trailing slashes. - */ -#define DO_POSIX_PATHNAME_RES 0 - -static int lookup(struct vnode *dirp, struct lookup *resolve, - node_details_t *node, struct fproc *rfp); - -/*===========================================================================* - * advance * - *===========================================================================*/ -struct vnode * -advance(struct vnode *dirp, struct lookup *resolve, struct fproc *rfp) -{ -/* Resolve a path name starting at dirp to a vnode. */ - int r; - int do_downgrade = 1; - struct vnode *new_vp, *vp; - struct vmnt *vmp; - struct node_details res = {0,0,0,0,0,0,0}; - tll_access_t initial_locktype; - - assert(dirp); - assert(resolve->l_vnode_lock != TLL_NONE); - assert(resolve->l_vmnt_lock != TLL_NONE); - - if (resolve->l_vnode_lock == VNODE_READ) - initial_locktype = VNODE_OPCL; - else - initial_locktype = resolve->l_vnode_lock; - - /* Get a free vnode and lock it */ - if ((new_vp = get_free_vnode()) == NULL) return(NULL); - lock_vnode(new_vp, initial_locktype); - - /* Lookup vnode belonging to the file. */ - if ((r = lookup(dirp, resolve, &res, rfp)) != OK) { - err_code = r; - unlock_vnode(new_vp); - return(NULL); - } - - /* Check whether we already have a vnode for that file */ - if ((vp = find_vnode(res.fs_e, res.inode_nr)) != NULL) { - unlock_vnode(new_vp); /* Don't need this anymore */ - do_downgrade = (lock_vnode(vp, initial_locktype) != EBUSY); - - /* Unfortunately, by the time we get the lock, another thread might've - * rid of the vnode (e.g., find_vnode found the vnode while a - * req_putnode was being processed). */ - if (vp->v_ref_count == 0) { /* vnode vanished! */ - /* As the lookup before increased the usage counters in the FS, - * we can simply set the usage counters to 1 and proceed as - * normal, because the putnode resulted in a use count of 1 in - * the FS. Other data is still valid, because the vnode was - * marked as pending lock, so get_free_vnode hasn't - * reinitialized the vnode yet. */ - vp->v_fs_count = 1; - if (vp->v_mapfs_e != NONE) vp->v_mapfs_count = 1; - } else { - vp->v_fs_count++; /* We got a reference from the FS */ - } - - } else { - /* Vnode not found, fill in the free vnode's fields */ - - new_vp->v_fs_e = res.fs_e; - new_vp->v_inode_nr = res.inode_nr; - new_vp->v_mode = res.fmode; - new_vp->v_size = res.fsize; - new_vp->v_uid = res.uid; - new_vp->v_gid = res.gid; - new_vp->v_sdev = res.dev; - - if( (vmp = find_vmnt(new_vp->v_fs_e)) == NULL) - panic("advance: vmnt not found"); - - new_vp->v_vmnt = vmp; - new_vp->v_dev = vmp->m_dev; - new_vp->v_fs_count = 1; - - vp = new_vp; - } - - dup_vnode(vp); - if (do_downgrade) { - /* Only downgrade a lock if we managed to lock it in the first place */ - *(resolve->l_vnode) = vp; - - if (initial_locktype != resolve->l_vnode_lock) - tll_downgrade(&vp->v_lock); - -#if LOCK_DEBUG - if (resolve->l_vnode_lock == VNODE_READ) - fp->fp_vp_rdlocks++; -#endif - } - - return(vp); -} - -/*===========================================================================* - * eat_path * - *===========================================================================*/ -struct vnode * -eat_path(struct lookup *resolve, struct fproc *rfp) -{ -/* Resolve path to a vnode. advance does the actual work. */ - struct vnode *start_dir; - - start_dir = (resolve->l_path[0] == '/' ? rfp->fp_rd : rfp->fp_wd); - return advance(start_dir, resolve, rfp); -} - -/*===========================================================================* - * last_dir * - *===========================================================================*/ -struct vnode * -last_dir(struct lookup *resolve, struct fproc *rfp) -{ -/* Parse a path, as far as the last directory, fetch the vnode - * for the last directory into the vnode table, and return a pointer to the - * vnode. In addition, return the final component of the path in 'string'. If - * the last directory can't be opened, return NULL and the reason for - * failure in 'err_code'. We can't parse component by component as that would - * be too expensive. Alternatively, we cut off the last component of the path, - * and parse the path up to the penultimate component. - */ - - size_t len; - char *cp; - char dir_entry[NAME_MAX+1]; - struct vnode *start_dir, *res_vp, *sym_vp, *sym_vp_l, *loop_start; - struct vmnt *sym_vmp = NULL; - int r, symloop = 0, ret_on_symlink = 0; - struct lookup symlink; - - *resolve->l_vnode = NULL; - *resolve->l_vmp = NULL; - loop_start = NULL; - sym_vp = NULL; - - ret_on_symlink = !!(resolve->l_flags & PATH_RET_SYMLINK); - - do { - /* Is the path absolute or relative? Initialize 'start_dir' - * accordingly. Use loop_start in case we're looping. - */ - if (loop_start != NULL) - start_dir = loop_start; - else - start_dir = (resolve->l_path[0] == '/' ? rfp->fp_rd:rfp->fp_wd); - - len = strlen(resolve->l_path); - - /* If path is empty, return ENOENT. */ - if (len == 0) { - err_code = ENOENT; - res_vp = NULL; - break; - } - -#if !DO_POSIX_PATHNAME_RES - /* Remove trailing slashes */ - while (len > 1 && resolve->l_path[len-1] == '/') { - len--; - resolve->l_path[len]= '\0'; - } -#endif - - cp = strrchr(resolve->l_path, '/'); - if (cp == NULL) { - /* Just an entry in the current working directory. Prepend - * "./" in front of the path and resolve it. - */ - if (strlcpy(dir_entry, resolve->l_path, NAME_MAX+1) >= NAME_MAX + 1) { - err_code = ENAMETOOLONG; - res_vp = NULL; - break; - } - dir_entry[NAME_MAX] = '\0'; - resolve->l_path[0] = '.'; - resolve->l_path[1] = '\0'; - } else if (cp[1] == '\0') { - /* Path ends in a slash. The directory entry is '.' */ - strlcpy(dir_entry, ".", NAME_MAX+1); - } else { - /* A path name for the directory and a directory entry */ - if (strlcpy(dir_entry, cp+1, NAME_MAX+1) >= NAME_MAX + 1) { - err_code = ENAMETOOLONG; - res_vp = NULL; - break; - } - cp[1] = '\0'; - dir_entry[NAME_MAX] = '\0'; - } - - /* Remove trailing slashes */ - while (cp > resolve->l_path && cp[0] == '/') { - cp[0]= '\0'; - cp--; - } - - /* Resolve up to and including the last directory of the path. Turn off - * PATH_RET_SYMLINK, because we do want to follow the symlink in this - * case. That is, the flag is meant for the actual filename of the path, - * not the last directory. - */ - resolve->l_flags &= ~PATH_RET_SYMLINK; - if ((res_vp = advance(start_dir, resolve, rfp)) == NULL) { - break; - } - - /* If the directory entry is not a symlink we're done now. If it is a - * symlink, then we're not at the last directory, yet. */ - - /* Copy the directory entry back to user_fullpath */ - strlcpy(resolve->l_path, dir_entry, NAME_MAX + 1); - - /* Look up the directory entry, but do not follow the symlink when it - * is one. Note: depending on the previous advance, we might not be - * able to lock the resulting vnode. For example, when we look up "./." - * and request a VNODE_WRITE lock on the result, then the previous - * advance has "./" locked. The next advance to "." will try to lock - * the same vnode with a VNODE_READ lock, and fail. When that happens, - * sym_vp_l will be NULL and we must not unlock the vnode. If we would - * unlock, we actually unlock the vnode locked by the previous advance. - */ - lookup_init(&symlink, resolve->l_path, - resolve->l_flags|PATH_RET_SYMLINK, &sym_vmp, &sym_vp_l); - symlink.l_vmnt_lock = VMNT_READ; - symlink.l_vnode_lock = VNODE_READ; - sym_vp = advance(res_vp, &symlink, rfp); - - if (sym_vp == NULL) break; - - if (S_ISLNK(sym_vp->v_mode)) { - /* Last component is a symlink, but if we've been asked to not - * resolve it, return now. - */ - if (ret_on_symlink) { - break; - } - - r = req_rdlink(sym_vp->v_fs_e, sym_vp->v_inode_nr, NONE, - (vir_bytes) resolve->l_path, PATH_MAX - 1, 1); - - if (r < 0) { - /* Failed to read link */ - err_code = r; - unlock_vnode(res_vp); - unlock_vmnt(*resolve->l_vmp); - put_vnode(res_vp); - *resolve->l_vmp = NULL; - *resolve->l_vnode = NULL; - res_vp = NULL; - break; - } - resolve->l_path[r] = '\0'; - - if (strrchr(resolve->l_path, '/') != NULL) { - if (sym_vp_l != NULL) - unlock_vnode(sym_vp); - unlock_vmnt(*resolve->l_vmp); - if (sym_vmp != NULL) - unlock_vmnt(sym_vmp); - *resolve->l_vmp = NULL; - put_vnode(sym_vp); - sym_vp = NULL; - - symloop++; - - /* Relative symlinks are relative to res_vp, not cwd */ - if (resolve->l_path[0] != '/') { - loop_start = res_vp; - } else { - /* Absolute symlink, forget about res_vp */ - unlock_vnode(res_vp); - put_vnode(res_vp); - } - - continue; - } - } else { - symloop = 0; /* Not a symlink, so restart counting */ - - /* If we're crossing a mount point, return root node of mount - * point on which the file resides. That's the 'real' last - * dir that holds the file we're looking for. - */ - if (sym_vp->v_fs_e != res_vp->v_fs_e) { - assert(sym_vmp != NULL); - - /* Unlock final file, it might have wrong lock types */ - if (sym_vp_l != NULL) - unlock_vnode(sym_vp); - unlock_vmnt(sym_vmp); - put_vnode(sym_vp); - sym_vp = NULL; - - /* Also unlock and release erroneous result */ - unlock_vnode(*resolve->l_vnode); - unlock_vmnt(*resolve->l_vmp); - put_vnode(res_vp); - - /* Relock vmnt and vnode with correct lock types */ - lock_vmnt(sym_vmp, resolve->l_vmnt_lock); - lock_vnode(sym_vmp->m_root_node, resolve->l_vnode_lock); - res_vp = sym_vmp->m_root_node; - dup_vnode(res_vp); - *resolve->l_vnode = res_vp; - *resolve->l_vmp = sym_vmp; - - /* We've effectively resolved the final component, so - * change it to current directory to prevent future - * 'advances' of returning erroneous results. - */ - strlcpy(dir_entry, ".", NAME_MAX+1); - } - } - break; - } while (symloop < _POSIX_SYMLOOP_MAX); - - if (symloop >= _POSIX_SYMLOOP_MAX) { - err_code = ELOOP; - res_vp = NULL; - } - - if (sym_vp != NULL) { - if (sym_vp_l != NULL) { - unlock_vnode(sym_vp); - } - if (sym_vmp != NULL) { - unlock_vmnt(sym_vmp); - } - put_vnode(sym_vp); - } - - if (loop_start != NULL) { - unlock_vnode(loop_start); - put_vnode(loop_start); - } - - /* Copy the directory entry back to user_fullpath */ - strlcpy(resolve->l_path, dir_entry, NAME_MAX + 1); - - /* Turn PATH_RET_SYMLINK flag back on if it was on */ - if (ret_on_symlink) resolve->l_flags |= PATH_RET_SYMLINK; - - return(res_vp); -} - -/*===========================================================================* - * lookup * - *===========================================================================*/ -static int -lookup(struct vnode *start_node, struct lookup *resolve, node_details_t *result_node, struct fproc *rfp) -{ -/* Resolve a path name relative to start_node. */ - - int r, symloop; - endpoint_t fs_e; - size_t path_off, path_left_len; - ino_t dir_ino, root_ino; - uid_t uid; - gid_t gid; - struct vnode *dir_vp; - struct vmnt *vmp, *vmpres; - struct lookup_res res; - tll_access_t mnt_lock_type; - - assert(resolve->l_vmp); - assert(resolve->l_vnode); - - *(resolve->l_vmp) = vmpres = NULL; /* No vmnt found nor locked yet */ - - /* Empty (start) path? */ - if (resolve->l_path[0] == '\0') { - result_node->inode_nr = 0; - return(ENOENT); - } - - if (!rfp->fp_rd || !rfp->fp_wd) { - printf("VFS: lookup %d: no rd/wd\n", rfp->fp_endpoint); - return(ENOENT); - } - - fs_e = start_node->v_fs_e; - dir_ino = start_node->v_inode_nr; - vmpres = find_vmnt(fs_e); - - if (vmpres == NULL) return(EIO); /* mountpoint vanished? */ - - /* Is the process' root directory on the same partition?, - * if so, set the chroot directory too. */ - if (rfp->fp_rd->v_dev == start_node->v_dev) - root_ino = rfp->fp_rd->v_inode_nr; - else - root_ino = 0; - - /* Set user and group ids according to the system call */ - uid = (job_call_nr == VFS_ACCESS ? rfp->fp_realuid : rfp->fp_effuid); - gid = (job_call_nr == VFS_ACCESS ? rfp->fp_realgid : rfp->fp_effgid); - - symloop = 0; /* Number of symlinks seen so far */ - - /* Lock vmnt */ - if (resolve->l_vmnt_lock == VMNT_READ) - mnt_lock_type = VMNT_WRITE; - else - mnt_lock_type = resolve->l_vmnt_lock; - - if ((r = lock_vmnt(vmpres, mnt_lock_type)) != OK) { - if (r == EBUSY) /* vmnt already locked */ - vmpres = NULL; - else - return(r); - } - *(resolve->l_vmp) = vmpres; - - /* Issue the request */ - r = req_lookup(fs_e, dir_ino, root_ino, uid, gid, resolve, &res, rfp); - - if (r != OK && r != EENTERMOUNT && r != ELEAVEMOUNT && r != ESYMLINK) { - if (vmpres) unlock_vmnt(vmpres); - *(resolve->l_vmp) = NULL; - return(r); /* i.e., an error occured */ - } - - /* While the response is related to mount control set the - * new requests respectively */ - while (r == EENTERMOUNT || r == ELEAVEMOUNT || r == ESYMLINK) { - /* Update user_fullpath to reflect what's left to be parsed. */ - path_off = res.char_processed; - path_left_len = strlen(&resolve->l_path[path_off]); - memmove(resolve->l_path, &resolve->l_path[path_off], path_left_len); - resolve->l_path[path_left_len] = '\0'; /* terminate string */ - - /* Update the current value of the symloop counter */ - symloop += res.symloop; - if (symloop > _POSIX_SYMLOOP_MAX) { - if (vmpres) unlock_vmnt(vmpres); - *(resolve->l_vmp) = NULL; - return(ELOOP); - } - - /* Symlink encountered with absolute path */ - if (r == ESYMLINK) { - dir_vp = rfp->fp_rd; - vmp = NULL; - } else if (r == EENTERMOUNT) { - /* Entering a new partition */ - dir_vp = NULL; - /* Start node is now the mounted partition's root node */ - for (vmp = &vmnt[0]; vmp != &vmnt[NR_MNTS]; ++vmp) { - if (vmp->m_dev != NO_DEV && vmp->m_mounted_on) { - if (vmp->m_mounted_on->v_inode_nr == res.inode_nr && - vmp->m_mounted_on->v_fs_e == res.fs_e) { - dir_vp = vmp->m_root_node; - break; - } - } - } - if (dir_vp == NULL) { - printf("VFS: path lookup error; root node not found\n"); - if (vmpres) unlock_vmnt(vmpres); - *(resolve->l_vmp) = NULL; - return(EIO); - } - } else { - /* Climbing up mount */ - /* Find the vmnt that represents the partition on - * which we "climb up". */ - if ((vmp = find_vmnt(res.fs_e)) == NULL) { - panic("VFS lookup: can't find parent vmnt"); - } - - /* Make sure that the child FS does not feed a bogus path - * to the parent FS. That is, when we climb up the tree, we - * must've encountered ".." in the path, and that is exactly - * what we're going to feed to the parent */ - if(strncmp(resolve->l_path, "..", 2) != 0 || - (resolve->l_path[2] != '\0' && resolve->l_path[2] != '/')) { - printf("VFS: bogus path: %s\n", resolve->l_path); - if (vmpres) unlock_vmnt(vmpres); - *(resolve->l_vmp) = NULL; - return(ENOENT); - } - - /* Start node is the vnode on which the partition is - * mounted */ - dir_vp = vmp->m_mounted_on; - } - - /* Set the starting directories inode number and FS endpoint */ - fs_e = dir_vp->v_fs_e; - dir_ino = dir_vp->v_inode_nr; - - /* Is the process' root directory on the same partition?, - * if so, set the chroot directory too. */ - if (dir_vp->v_dev == rfp->fp_rd->v_dev) - root_ino = rfp->fp_rd->v_inode_nr; - else - root_ino = 0; - - /* Unlock a previously locked vmnt if locked and lock new vmnt */ - if (vmpres) unlock_vmnt(vmpres); - vmpres = find_vmnt(fs_e); - if (vmpres == NULL) return(EIO); /* mount point vanished? */ - if ((r = lock_vmnt(vmpres, mnt_lock_type)) != OK) { - if (r == EBUSY) - vmpres = NULL; /* Already locked */ - else - return(r); - } - *(resolve->l_vmp) = vmpres; - - r = req_lookup(fs_e, dir_ino, root_ino, uid, gid, resolve, &res, rfp); - - if (r != OK && r != EENTERMOUNT && r != ELEAVEMOUNT && r != ESYMLINK) { - if (vmpres) unlock_vmnt(vmpres); - *(resolve->l_vmp) = NULL; - return(r); - } - } - - if (*(resolve->l_vmp) != NULL && resolve->l_vmnt_lock != mnt_lock_type) { - /* downgrade VMNT_WRITE to VMNT_READ */ - downgrade_vmnt_lock(*(resolve->l_vmp)); - } - - /* Fill in response fields */ - result_node->inode_nr = res.inode_nr; - result_node->fmode = res.fmode; - result_node->fsize = res.fsize; - result_node->dev = res.dev; - result_node->fs_e = res.fs_e; - result_node->uid = res.uid; - result_node->gid = res.gid; - - return(r); -} - -/*===========================================================================* - * lookup_init * - *===========================================================================*/ -void -lookup_init(struct lookup *resolve, char *path, int flags, struct vmnt **vmp, struct vnode **vp) -{ - assert(vmp != NULL); - assert(vp != NULL); - - resolve->l_path = path; - resolve->l_flags = flags; - resolve->l_vmp = vmp; - resolve->l_vnode = vp; - resolve->l_vmnt_lock = TLL_NONE; - resolve->l_vnode_lock = TLL_NONE; - *vmp = NULL; /* Initialize lookup result to NULL */ - *vp = NULL; -} - -/*===========================================================================* - * get_name * - *===========================================================================*/ -int -get_name(struct vnode *dirp, struct vnode *entry, char ename[NAME_MAX + 1]) -{ -#define DIR_ENTRIES 8 -#define DIR_ENTRY_SIZE (sizeof(struct dirent) + NAME_MAX) - off_t pos, new_pos; - int r, consumed, totalbytes, name_len; - char buf[DIR_ENTRY_SIZE * DIR_ENTRIES]; - struct dirent *cur; - - pos = 0; - - if (!S_ISDIR(dirp->v_mode)) return(EBADF); - - do { - r = req_getdents(dirp->v_fs_e, dirp->v_inode_nr, pos, (vir_bytes)buf, - sizeof(buf), &new_pos, 1); - - if (r == 0) { - return(ENOENT); /* end of entries -- matching inode !found */ - } else if (r < 0) { - return(r); /* error */ - } - - consumed = 0; /* bytes consumed */ - totalbytes = r; /* number of bytes to consume */ - - do { - cur = (struct dirent *) (buf + consumed); - name_len = cur->d_reclen - offsetof(struct dirent, d_name) - 1; - - if(cur->d_name + name_len+1 > &buf[sizeof(buf)]) - return(EINVAL); /* Rubbish in dir entry */ - if (entry->v_inode_nr == cur->d_fileno) { - /* found the entry we were looking for */ - int copylen = MIN(name_len + 1, NAME_MAX + 1); - if (strlcpy(ename, cur->d_name, copylen) >= copylen) { - return(ENAMETOOLONG); - } - ename[NAME_MAX] = '\0'; - return(OK); - } - - /* not a match -- move on to the next dirent */ - consumed += cur->d_reclen; - } while (consumed < totalbytes); - - pos = new_pos; - } while (1); -} - -/*===========================================================================* - * canonical_path * - *===========================================================================*/ -int -canonical_path(char orig_path[PATH_MAX], struct fproc *rfp) -{ -/* Find canonical path of a given path */ - int len = 0; - int r, symloop = 0; - struct vnode *dir_vp, *parent_dir; - struct vmnt *dir_vmp, *parent_vmp; - char component[NAME_MAX+1]; /* NAME_MAX does /not/ include '\0' */ - char temp_path[PATH_MAX]; - struct lookup resolve; - - parent_dir = dir_vp = NULL; - parent_vmp = dir_vmp = NULL; - strlcpy(temp_path, orig_path, PATH_MAX); - temp_path[PATH_MAX - 1] = '\0'; - - /* First resolve path to the last directory holding the file */ - do { - if (dir_vp) { - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(dir_vp); - } - - lookup_init(&resolve, temp_path, PATH_NOFLAGS, &dir_vmp, &dir_vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - if ((dir_vp = last_dir(&resolve, rfp)) == NULL) return(err_code); - - /* dir_vp points to dir and resolve path now contains only the - * filename. - */ - strlcpy(orig_path, temp_path, NAME_MAX+1); /* Store file name */ - - /* If we're just crossing a mount point, our name has changed to '.' */ - if (!strcmp(orig_path, ".")) orig_path[0] = '\0'; - - /* check if the file is a symlink, if so resolve it */ - r = rdlink_direct(orig_path, temp_path, rfp); - - if (r <= 0) - break; - - /* encountered a symlink -- loop again */ - strlcpy(orig_path, temp_path, PATH_MAX); - symloop++; - } while (symloop < _POSIX_SYMLOOP_MAX); - - if (symloop >= _POSIX_SYMLOOP_MAX) { - if (dir_vp) { - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(dir_vp); - } - return(ELOOP); - } - - /* We've got the filename and the actual directory holding the file. From - * here we start building up the canonical path by climbing up the tree */ - while (dir_vp != rfp->fp_rd) { - - strlcpy(temp_path, "..", NAME_MAX+1); - - /* check if we're at the root node of the file system */ - if (dir_vp->v_vmnt->m_root_node == dir_vp) { - if (dir_vp->v_vmnt->m_mounted_on == NULL) { - /* Bail out, we can't go any higher */ - break; - } - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(dir_vp); - dir_vp = dir_vp->v_vmnt->m_mounted_on; - dir_vmp = dir_vp->v_vmnt; - if (lock_vmnt(dir_vmp, VMNT_READ) != OK) - panic("failed to lock vmnt"); - if (lock_vnode(dir_vp, VNODE_READ) != OK) - panic("failed to lock vnode"); - dup_vnode(dir_vp); - } - - lookup_init(&resolve, temp_path, PATH_NOFLAGS, &parent_vmp, - &parent_dir); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - - if ((parent_dir = advance(dir_vp, &resolve, rfp)) == NULL) { - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(dir_vp); - return(err_code); - } - - /* now we have to retrieve the name of the parent directory */ - if ((r = get_name(parent_dir, dir_vp, component)) != OK) { - unlock_vnode(parent_dir); - unlock_vmnt(parent_vmp); - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(parent_dir); - put_vnode(dir_vp); - return(r); - } - - len += strlen(component) + 1; - if (len >= PATH_MAX) { - /* adding the component to orig_path would exceed PATH_MAX */ - unlock_vnode(parent_dir); - unlock_vmnt(parent_vmp); - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(parent_dir); - put_vnode(dir_vp); - return(ENOMEM); - } - - /* Store result of component in orig_path. First make space by moving - * the contents of orig_path to the right. Move strlen + 1 bytes to - * include the terminating '\0'. Move to strlen + 1 bytes to reserve - * space for the slash. - */ - memmove(orig_path+strlen(component)+1, orig_path, strlen(orig_path)+1); - /* Copy component into canon_path */ - memmove(orig_path, component, strlen(component)); - /* Put slash into place */ - orig_path[strlen(component)] = '/'; - - /* Store parent_dir result, and continue the loop once more */ - unlock_vnode(dir_vp); - unlock_vmnt(dir_vmp); - put_vnode(dir_vp); - dir_vp = parent_dir; - dir_vmp = parent_vmp; - parent_vmp = NULL; - } - - unlock_vmnt(dir_vmp); - unlock_vnode(dir_vp); - put_vnode(dir_vp); - - /* add the leading slash */ - len = strlen(orig_path); - if (strlen(orig_path) >= PATH_MAX) return(ENAMETOOLONG); - memmove(orig_path+1, orig_path, len + 1 /* include terminating nul */); - orig_path[0] = '/'; - - /* remove trailing slash if there is any */ - if (len > 1 && orig_path[len] == '/') orig_path[len] = '\0'; - - return(OK); -} - -/*===========================================================================* - * do_socketpath * - *===========================================================================*/ -int do_socketpath(void) -{ -/* - * Perform a path action on an on-disk socket file. This call may be performed - * by the UDS service only. The action is always on behalf of a user process - * that is currently making a socket call to the UDS service, and thus, VFS may - * rely on the fact that the user process is blocked. TODO: there should be - * checks in place to prevent (even accidental) abuse of this function, though. - */ - int r, what, slot; - endpoint_t ep; - cp_grant_id_t io_gr; - size_t pathlen; - struct vnode *dirp, *vp; - struct vmnt *vmp, *vmp2; - struct fproc *rfp; - char path[PATH_MAX]; - struct lookup resolve, resolve2; - mode_t bits; - - /* This should be replaced by an ACL check. */ - if (!super_user) return EPERM; - - ep = job_m_in.m_lsys_vfs_socketpath.endpt; - io_gr = job_m_in.m_lsys_vfs_socketpath.grant; - pathlen = job_m_in.m_lsys_vfs_socketpath.count; - what = job_m_in.m_lsys_vfs_socketpath.what; - - if (isokendpt(ep, &slot) != OK) return(EINVAL); - rfp = &fproc[slot]; - - /* Copy in the path name, which must not be empty. It is typically not null - * terminated. - */ - if (pathlen < 1 || pathlen >= sizeof(path)) return(EINVAL); - r = sys_safecopyfrom(who_e, io_gr, (vir_bytes)0, (vir_bytes)path, pathlen); - if (r != OK) return(r); - path[pathlen] = '\0'; - - /* Now perform the requested action. For the SPATH_CHECK action, a socket - * file is expected to exist already, and we should check whether the given - * user process has access to it. For the SPATH_CREATE action, no file is - * expected to exist yet, and a socket file should be created on behalf of - * the user process. In both cases, on success, return the socket file's - * device and inode numbers to the caller. - * - * Since the above canonicalization releases all locks once done, we need to - * recheck absolutely everything now. TODO: do not release locks in between. - */ - switch (what) { - case SPATH_CHECK: - lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - if ((vp = eat_path(&resolve, rfp)) == NULL) return(err_code); - - /* Check file type and permissions. */ - if (!S_ISSOCK(vp->v_mode)) - r = ENOTSOCK; /* not in POSIX spec; this is what NetBSD does */ - else - r = forbidden(rfp, vp, R_BIT | W_BIT); - - if (r == OK) { - job_m_out.m_vfs_lsys_socketpath.device = vp->v_dev; - job_m_out.m_vfs_lsys_socketpath.inode = vp->v_inode_nr; - } - - unlock_vnode(vp); - unlock_vmnt(vmp); - put_vnode(vp); - break; - - case SPATH_CREATE: - /* This is effectively simulating a mknod(2) call by the user process, - * including the application of its umask to the file permissions. - */ - lookup_init(&resolve, path, PATH_RET_SYMLINK, &vmp, &dirp); - resolve.l_vmnt_lock = VMNT_WRITE; - resolve.l_vnode_lock = VNODE_WRITE; - - if ((dirp = last_dir(&resolve, rfp)) == NULL) return(err_code); - - bits = S_IFSOCK | (ACCESSPERMS & rfp->fp_umask); - - if (!S_ISDIR(dirp->v_mode)) - r = ENOTDIR; - else if ((r = forbidden(rfp, dirp, W_BIT | X_BIT)) == OK) { - r = req_mknod(dirp->v_fs_e, dirp->v_inode_nr, path, - rfp->fp_effuid, rfp->fp_effgid, bits, NO_DEV); - if (r == OK) { - /* Now we need to find out the device and inode number - * of the socket file we just created. The vmnt lock - * should prevent any trouble here. - */ - lookup_init(&resolve2, resolve.l_path, - PATH_RET_SYMLINK, &vmp2, &vp); - resolve2.l_vmnt_lock = VMNT_READ; - resolve2.l_vnode_lock = VNODE_READ; - vp = advance(dirp, &resolve2, rfp); - assert(vmp2 == NULL); - if (vp != NULL) { - job_m_out.m_vfs_lsys_socketpath.device = - vp->v_dev; - job_m_out.m_vfs_lsys_socketpath.inode = - vp->v_inode_nr; - unlock_vnode(vp); - put_vnode(vp); - } else { - /* Huh. This should never happen. If it does, - * we assume the socket file has somehow been - * lost, so we do not try to unlink it. - */ - printf("VFS: socketpath did not find created " - "node at %s (%d)\n", path, err_code); - r = err_code; - } - } else if (r == EEXIST) - r = EADDRINUSE; - } - - unlock_vnode(dirp); - unlock_vmnt(vmp); - put_vnode(dirp); - break; - - default: - r = ENOSYS; - } - - return(r); -} diff --git a/minix/servers/vfs/stadir.c b/minix/servers/vfs/stadir.c deleted file mode 100644 index f7d8d3ace..000000000 --- a/minix/servers/vfs/stadir.c +++ /dev/null @@ -1,446 +0,0 @@ -/* This file contains the code for performing four system calls relating to - * status and directories. - * - * The entry points into this file are - * do_chdir: perform the CHDIR system call - * do_chroot: perform the CHROOT system call - * do_lstat: perform the LSTAT system call - * do_stat: perform the STAT system call - * do_fstat: perform the FSTAT system call - * do_statvfs: perform the STATVFS1 system call - * do_fstatvfs: perform the FSTATVFS1 system call - * do_getvfsstat: perform the GETVFSSTAT system call - */ - -#include "fs.h" -#include -#include -#include -#include -#include "file.h" -#include "path.h" -#include -#include -#include "vnode.h" -#include "vmnt.h" - -static int change_into(struct vnode **iip, struct vnode *vp); - -/*===========================================================================* - * do_fchdir * - *===========================================================================*/ -int do_fchdir(void) -{ - /* Change directory on already-opened fd. */ - struct filp *rfilp; - int r, rfd; - - rfd = job_m_in.m_lc_vfs_fchdir.fd; - - /* Is the file descriptor valid? */ - if ((rfilp = get_filp(rfd, VNODE_READ)) == NULL) return(err_code); - r = change_into(&fp->fp_wd, rfilp->filp_vno); - unlock_filp(rfilp); - return(r); -} - -/*===========================================================================* - * do_chdir * - *===========================================================================*/ -int do_chdir(void) -{ -/* Perform the chdir(name) system call. - * syscall might provide 'name' embedded in the message. - */ - - int r; - struct vnode *vp; - struct vmnt *vmp; - char fullpath[PATH_MAX]; - struct lookup resolve; - - if (copy_path(fullpath, sizeof(fullpath)) != OK) - return(err_code); - - /* Try to open the directory */ - lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); - - r = change_into(&fp->fp_wd, vp); - - unlock_vnode(vp); - unlock_vmnt(vmp); - put_vnode(vp); - - return(r); -} - -/*===========================================================================* - * do_chroot * - *===========================================================================*/ -int do_chroot(void) -{ -/* Perform the chroot(name) system call. - * syscall might provide 'name' embedded in the message. - */ - int r; - struct vnode *vp; - struct vmnt *vmp; - char fullpath[PATH_MAX]; - struct lookup resolve; - - if (!super_user) return(EPERM); /* only su may chroot() */ - - if (copy_path(fullpath, sizeof(fullpath)) != OK) - return(err_code); - - /* Try to open the directory */ - lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); - - r = change_into(&fp->fp_rd, vp); - - unlock_vnode(vp); - unlock_vmnt(vmp); - put_vnode(vp); - - return(r); -} - -/*===========================================================================* - * change_into * - *===========================================================================*/ -static int change_into(struct vnode **result, struct vnode *vp) -{ - int r; - - if (*result == vp) return(OK); /* Nothing to do */ - - /* It must be a directory and also be searchable */ - if (!S_ISDIR(vp->v_mode)) - r = ENOTDIR; - else - r = forbidden(fp, vp, X_BIT); /* Check if dir is searchable*/ - if (r != OK) return(r); - - /* Everything is OK. Make the change. */ - put_vnode(*result); /* release the old directory */ - dup_vnode(vp); - *result = vp; /* acquire the new one */ - return(OK); -} - -/*===========================================================================* - * do_stat * - *===========================================================================*/ -int do_stat(void) -{ -/* Perform the stat(name, buf) system call. */ - int r; - struct vnode *vp; - struct vmnt *vmp; - char fullpath[PATH_MAX]; - struct lookup resolve; - vir_bytes vname1, statbuf; - size_t vname1_length; - - vname1 = job_m_in.m_lc_vfs_stat.name; - vname1_length = job_m_in.m_lc_vfs_stat.len; - statbuf = job_m_in.m_lc_vfs_stat.buf; - - lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - - if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); - if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); - r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, statbuf); - - unlock_vnode(vp); - unlock_vmnt(vmp); - - put_vnode(vp); - return r; -} - -/*===========================================================================* - * do_fstat * - *===========================================================================*/ -int do_fstat(void) -{ -/* Perform the fstat(fd, buf) system call. */ - register struct filp *rfilp; - int r, rfd; - vir_bytes statbuf; - - statbuf = job_m_in.m_lc_vfs_fstat.buf; - rfd = job_m_in.m_lc_vfs_fstat.fd; - - /* Is the file descriptor valid? */ - if ((rfilp = get_filp(rfd, VNODE_READ)) == NULL) return(err_code); - - r = req_stat(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr, - who_e, statbuf); - - unlock_filp(rfilp); - - return(r); -} - -/*===========================================================================* - * update_statvfs * - *===========================================================================*/ -int update_statvfs(struct vmnt *vmp, struct statvfs *buf) -{ -/* Get statistics from a file system, and cache part of the results. */ - int r; - - if ((r = req_statvfs(vmp->m_fs_e, buf)) != OK) - return r; - - vmp->m_stats.f_flag = buf->f_flag; - vmp->m_stats.f_bsize = buf->f_bsize; - vmp->m_stats.f_frsize = buf->f_frsize; - vmp->m_stats.f_iosize = buf->f_iosize; - - vmp->m_stats.f_blocks = buf->f_blocks; - vmp->m_stats.f_bfree = buf->f_bfree; - vmp->m_stats.f_bavail = buf->f_bavail; - vmp->m_stats.f_bresvd = buf->f_bresvd; - - vmp->m_stats.f_files = buf->f_files; - vmp->m_stats.f_ffree = buf->f_ffree; - vmp->m_stats.f_favail = buf->f_favail; - vmp->m_stats.f_fresvd = buf->f_fresvd; - - vmp->m_stats.f_syncreads = buf->f_syncreads; - vmp->m_stats.f_syncwrites = buf->f_syncwrites; - - vmp->m_stats.f_asyncreads = buf->f_asyncreads; - vmp->m_stats.f_asyncwrites = buf->f_asyncwrites; - - vmp->m_stats.f_namemax = buf->f_namemax; - - return OK; -} - -/*===========================================================================* - * fill_statvfs * - *===========================================================================*/ -static int fill_statvfs(struct vmnt *vmp, endpoint_t endpt, vir_bytes buf_addr, - int flags) -{ -/* Fill a statvfs structure in a userspace process. First let the target file - * server fill in most fields, or use the cached copy if ST_NOWAIT is given. - * Then fill in some remaining fields with local information. Finally, copy - * the result to user space. - */ - struct statvfs buf; - - if (!(flags & ST_NOWAIT)) { - /* Get fresh statistics from the file system. */ - if (update_statvfs(vmp, &buf) != OK) - return EIO; - } else { - /* Use the cached statistics. */ - memset(&buf, 0, sizeof(buf)); - - buf.f_flag = vmp->m_stats.f_flag; - buf.f_bsize = vmp->m_stats.f_bsize; - buf.f_frsize = vmp->m_stats.f_frsize; - buf.f_iosize = vmp->m_stats.f_iosize; - - buf.f_blocks = vmp->m_stats.f_blocks; - buf.f_bfree = vmp->m_stats.f_bfree; - buf.f_bavail = vmp->m_stats.f_bavail; - buf.f_bresvd = vmp->m_stats.f_bresvd; - - buf.f_files = vmp->m_stats.f_files; - buf.f_ffree = vmp->m_stats.f_ffree; - buf.f_favail = vmp->m_stats.f_favail; - buf.f_fresvd = vmp->m_stats.f_fresvd; - - buf.f_syncreads = vmp->m_stats.f_syncreads; - buf.f_syncwrites = vmp->m_stats.f_syncwrites; - - buf.f_asyncreads = vmp->m_stats.f_asyncreads; - buf.f_asyncwrites = vmp->m_stats.f_asyncwrites; - - buf.f_namemax = vmp->m_stats.f_namemax; - } - - if (vmp->m_flags & VMNT_READONLY) - buf.f_flag |= ST_RDONLY; - - buf.f_fsid = (unsigned long)vmp->m_dev; - buf.f_fsidx.__fsid_val[0] = (long)vmp->m_dev; /* This is what is done on NetBSD */ - buf.f_fsidx.__fsid_val[1] = 0; /* Here they convert the FS type name into a number. */ - - strlcpy(buf.f_fstypename, vmp->m_fstype, sizeof(buf.f_fstypename)); - strlcpy(buf.f_mntonname, vmp->m_mount_path, sizeof(buf.f_mntonname)); - strlcpy(buf.f_mntfromname, vmp->m_mount_dev, sizeof(buf.f_mntfromname)); - - return sys_datacopy_wrapper(SELF, (vir_bytes) &buf, - endpt, buf_addr, sizeof(buf)); -} - -/*===========================================================================* - * do_statvfs * - *===========================================================================*/ -int do_statvfs(void) -{ -/* Perform the statvfs1(name, buf, flags) system call. */ - int r, flags; - struct vnode *vp; - struct vmnt *vmp; - char fullpath[PATH_MAX]; - struct lookup resolve; - vir_bytes vname1, statbuf; - size_t vname1_length; - - vname1 = job_m_in.m_lc_vfs_statvfs1.name; - vname1_length = job_m_in.m_lc_vfs_statvfs1.len; - statbuf = job_m_in.m_lc_vfs_statvfs1.buf; - flags = job_m_in.m_lc_vfs_statvfs1.flags; - - lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - - if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); - if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); - r = fill_statvfs(vp->v_vmnt, who_e, statbuf, flags); - - unlock_vnode(vp); - unlock_vmnt(vmp); - - put_vnode(vp); - return r; -} - -/*===========================================================================* - * do_fstatvfs * - *===========================================================================*/ -int do_fstatvfs(void) -{ -/* Perform the fstatvfs1(fd, buf, flags) system call. */ - register struct filp *rfilp; - int r, rfd, flags; - vir_bytes statbuf; - - rfd = job_m_in.m_lc_vfs_statvfs1.fd; - statbuf = job_m_in.m_lc_vfs_statvfs1.buf; - flags = job_m_in.m_lc_vfs_statvfs1.flags; - - /* Is the file descriptor valid? */ - if ((rfilp = get_filp(rfd, VNODE_READ)) == NULL) return(err_code); - r = fill_statvfs(rfilp->filp_vno->v_vmnt, who_e, statbuf, flags); - - unlock_filp(rfilp); - - return(r); -} - -/*===========================================================================* - * do_getvfsstat * - *===========================================================================*/ -int do_getvfsstat(void) -{ -/* Perform the getvfsstat(buf, bufsize, flags) system call. */ - struct vmnt *vmp; - vir_bytes buf; - size_t bufsize; - int r, flags, count, do_lock; - - buf = job_m_in.m_lc_vfs_getvfsstat.buf; - bufsize = job_m_in.m_lc_vfs_getvfsstat.len; - flags = job_m_in.m_lc_vfs_getvfsstat.flags; - - count = 0; - - if (buf != 0) { - /* We only need to lock target file systems if we are going to query - * them. This will only happen if ST_NOWAIT is not given. If we do - * not lock, we rely on the VMNT_CANSTAT flag to protect us from - * concurrent (un)mount operations. Note that procfs relies on - * ST_NOWAIT calls being lock free, as it is a file system itself. - */ - do_lock = !(flags & ST_NOWAIT); - - for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) { - /* If there is no more space, return the count so far. */ - if (bufsize < sizeof(struct statvfs)) - break; - - /* Lock the file system before checking any fields. */ - if (do_lock && (r = lock_vmnt(vmp, VMNT_READ)) != OK) - return r; - - /* Obtain information for this file system, if it is in use and - * can be reported. File systems that are being (un)mounted - * are skipped, as is PFS. The fill call will block only if - * ST_NOWAIT was not given. - */ - if (vmp->m_dev != NO_DEV && (vmp->m_flags & VMNT_CANSTAT)) { - if ((r = fill_statvfs(vmp, who_e, buf, flags)) != OK) { - if (do_lock) - unlock_vmnt(vmp); - - return r; - } - - count++; - buf += sizeof(struct statvfs); - bufsize -= sizeof(struct statvfs); - } - - if (do_lock) - unlock_vmnt(vmp); - } - } else { - /* Just report a file system count. No need to lock, as above. */ - for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) { - if (vmp->m_dev != NO_DEV && (vmp->m_flags & VMNT_CANSTAT)) - count++; - } - } - - return count; -} - -/*===========================================================================* - * do_lstat * - *===========================================================================*/ -int do_lstat(void) -{ -/* Perform the lstat(name, buf) system call. */ - struct vnode *vp; - struct vmnt *vmp; - int r; - char fullpath[PATH_MAX]; - struct lookup resolve; - vir_bytes vname1, statbuf; - size_t vname1_length; - - vname1 = job_m_in.m_lc_vfs_stat.name; - vname1_length = job_m_in.m_lc_vfs_stat.len; - statbuf = job_m_in.m_lc_vfs_stat.buf; - - lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &vp); - resolve.l_vmnt_lock = VMNT_READ; - resolve.l_vnode_lock = VNODE_READ; - - if (fetch_name(vname1, vname1_length, fullpath) != OK) return(err_code); - if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code); - r = req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, statbuf); - - unlock_vnode(vp); - unlock_vmnt(vmp); - - put_vnode(vp); - return(r); -} diff --git a/minix/servers/vm/Makefile b/minix/servers/vm/Makefile deleted file mode 100644 index bf440261d..000000000 --- a/minix/servers/vm/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile for VM server -.include - -PROG= vm -SRCS= main.c alloc.c utility.c exit.c fork.c break.c \ - mmap.c slaballoc.c region.c pagefaults.c pagetable.c \ - rs.c pb.c regionavl.c \ - mem_anon.c mem_directphys.c mem_anon_contig.c mem_shared.c \ - mem_cache.c cache.c vfs.c mem_file.c fdref.c acl.c - -.if ${MACHINE_ARCH} == "earm" -LDFLAGS+= -T ${.CURDIR}/arch/${MACHINE_ARCH}/vm.lds -.endif - -.if ${MKPAE:Uno} != "no" -CPPFLAGS+= -DPAE=1 -.endif - -DPADD+= ${LIBSYS} ${LIBEXEC} -LDADD+= -lsys -lexec - -CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch/${MACHINE_ARCH} -CPPFLAGS+= -I${NETBSDSRCDIR}/minix - -# For all other services, magic instrumentation involves instrumenting the -# libc malloc code, hooking its nested mmap/munmap calls, and ignoring its -# data. For VM, we need to do the exact opposite, since for VM, the malloc -# state is transferred as is. Thus, if the magic pass is enabled, tell it -# to skip the regular malloc instrumentation features. -MAGICFLAGS= -magic-disable-mem-functions -magic-disable-malloc-skip - -.include "arch/${MACHINE_ARCH}/Makefile.inc" -.include diff --git a/minix/usr.bin/trace/Makefile b/minix/usr.bin/trace/Makefile deleted file mode 100644 index e875453c1..000000000 --- a/minix/usr.bin/trace/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -.include - -PROG= trace -SRCS= call.o error.o escape.o format.o ioctl.o kernel.o mem.o output.o \ - proc.o signal.o trace.o -.PATH: ${.CURDIR}/service -SRCS+= pm.o vfs.o rs.o mib.o vm.o ipc.o -.PATH: ${.CURDIR}/ioctl -SRCS+= block.o char.o net.o svrctl.o - -CPPFLAGS+= -D_MINIX_SYSTEM=1 -I${.CURDIR} -I${NETBSDSRCDIR}/minix - -COPTS.format.c+= -Wno-format-nonliteral - -error.c: error.awk ${NETBSDSRCDIR}/sys/sys/errno.h - ${TOOL_AWK} -f ${.ALLSRC} > ${.TARGET} - -signal.c: signal.awk ${NETBSDSRCDIR}/sys/sys/signal.h - ${TOOL_AWK} -f ${.ALLSRC} > ${.TARGET} - -CLEANFILES+= error.c signal.c - -WARNS?= 5 - -.include