[alsa-devel] [Pkg-alsa-devel] Bug#436502: alsa-tools -> usx2yloader

Takashi Iwai tiwai at suse.de
Tue Sep 18 17:42:45 CEST 2007


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 at 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;
 		}


More information about the Alsa-devel mailing list