At Mon, 17 Sep 2007 17:17:29 +0200, I wrote:
At Thu, 13 Sep 2007 02:23:36 -0600, Michael Bourgeous wrote:
On 9/12/07, Elimar Riesebieter riesebie@lxtec.de wrote:
Attached is a patch for the Makefiles and an udev rule which should work anyway. I don't have TASCAM US-122 usb hardware handy, so I would be very pleased if someone could test it.
Thanks
Elimar
I can't remember for sure, but the included rules file might have problems loading the us428control program. I think there might have been problems I encountered with using the tascam_fpga script directly from udev, since us428control doesn't self-daemonize. I'll attach the .rules file that I use, which might be useful as an example to fix the .rules file provided already if it's found that there are problems with udev and the existing tascam_fpga script. As I recall, since us428control was still holding on to its stdout, udev would hang and not load any devices after the US-428.
A better option might be a patch to us428control to add a daemonize switch (which, of course, could be as simple as fclose()-ing stdin, stdout, and stderr, and dealing with any I/O functions accordingly).
Yeah, I'll add the daemonize option soon. (The patch is already on my local tree but I forgot my laptop at home :)
... or an easy solution would be to use startproc (or start_daemon) to wrap us428control. And you can call killproc for ACTION=="remove", too.
Anyway, an untested patch is below.
Takashi
diff -r e82775d19938 us428control/us428control.cc --- a/us428control/us428control.cc Mon Jun 04 15:16:24 2007 +0200 +++ b/us428control/us428control.cc Tue Sep 18 17:42:19 2007 +0200 @@ -63,9 +63,16 @@ static void usage(void) { printf("Tascam US-428 Control\n"); printf("version %s\n", VERSION); - printf("usage: "PROGNAME" [-v verbosity_level 0..2] [-c card] [-D device] [-u usb-device] [-m mode]\n"); - printf("mode is one of (us224, us428, mixxx)\n"); -} + fputs("usage: "PROGNAME" [-options]\n" + " -v level specify verbosity level (0..2)\n" + " -c card specify card number\n" + " -D device specify device string\n" + " -u device specify USB device name\n" + " -m mode specify running mode: us224, us428, or mixxx\n" + " -d daemonize\n", + stdout); +} + /* * check the name id of the given hwdep handle */ @@ -86,7 +93,34 @@ static int check_hwinfo(snd_hwdep_t *hw, return 0; /* ok */ }
-int US428Control(const char* DevName, int mode, int y) +static void daemonize(void) +{ + pid_t pid, sid; + + if (getppid() == 1) + return; /* already a daemon */ + + pid = fork(); + if (pid < 0) + exit(1); + if (pid > 0) + exit(0); + + umask(0); + sid = setsid(); + if (sid < 0) + exit(1); + + if (chdir("/") < 0) + exit(1); + + /* Redirect standard files to /dev/null */ + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); +} + +static int US428Control(const char* DevName, int mode, int y, int to_daemon) { snd_hwdep_t *hw; int err; @@ -109,6 +143,9 @@ int US428Control(const char* DevName, in
if (verbose > 0) fprintf(stderr, PROGNAME ": US-X2Y-compatible card found on hwdep %s\n", DevName); + + if (to_daemon) + daemonize();
Midi.CreatePorts();
@@ -167,14 +204,18 @@ int main (int argc, char *argv[]) int y = 8; int mode = 0; int card = -1; + int to_daemon = 0; char *device_name = NULL, *usb_device_name = getenv("DEVICE"); char name[64];
- while ((c = getopt(argc, argv, "c:D:u:v:m:")) != -1) { + while ((c = getopt(argc, argv, "cd:D:u:v:m:")) != -1) { switch (c) { case 'c': card = atoi(optarg); + break; + case 'd': + to_daemon = 1; break; case 'D': device_name = optarg; @@ -214,18 +255,18 @@ int main (int argc, char *argv[]) } } if (device_name) { - return US428Control(device_name, mode, y) != 0; + return US428Control(device_name, mode, y, to_daemon) != 0; } if (card >= 0) { sprintf(name, "hw:%d", card); - return US428Control(name, mode, y) != 0; + return US428Control(name, mode, y, to_daemon) != 0; }
/* probe the all cards */ for (c = 0; c < SND_CARDS; c++) { // verbose--; sprintf(name, "hw:%d", c); - if (US428Control(name, mode, y) == 0) { + if (US428Control(name, mode, y, to_daemon) == 0) { card = c; break; }