DF-5106 / trig.c
/* * trig - unprivileged user side of the DF-5106 reproduction. * * 1. open()s the MIDI cdev (mode 0666, any user can open it) * 2. writes MIDI bytes in a loop - each write arms M_TXEN which keeps * the mpu401 callout (m->timer) perpetually re-armed, calling * m->si(m->cookie) with cookie == the driver softc * 3. holds the fd open across the admin-side trigger * (sysctl hw.simid.detach=1 for stage A, kldunload for stage B) * * usage: trig <seconds> [device] */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> int main(int argc, char **argv) { int fd, i, secs = 10; const char *dev = "/dev/midi0.0"; unsigned char note_on[3] = { 0x90, 0x40, 0x40 }; if (argc > 1) secs = atoi(argv[1]); if (argc > 2) dev = argv[2]; fd = open(dev, O_RDWR); if (fd < 0) { printf("trig: open(%s) failed: %s\n", dev, strerror(errno)); return (1); } printf("trig: opened %s fd=%d uid=%d\n", dev, fd, getuid()); for (i = 0; i < secs * 10; i++) { if (write(fd, note_on, 3) != 3) { printf("trig: write failed at %d: %s\n", i, strerror(errno)); /* keep the fd open even if writes start failing */ } usleep(100 * 1000); } printf("trig: done, closing\n"); close(fd); return (0); } |