revised patches to go with bug report #1497 (esound)



Argh!  Overlapping modifications...

These revised patches work against esound/esdlib.c version 1.50, (as
opposed to 1.49).

:wishes he had CVS access...

--Richard
--- esdlib.c.orig	Wed Jun 16 14:52:54 1999
+++ esdlib.c	Wed Jun 16 14:58:34 1999
@@ -24,6 +24,8 @@
 int esd_set_socket_buffers( int sock, int src_format, 
 			    int src_rate, int base_rate );
 static void dummy_signal(int signum);
+static int host_is_localhost(const char* host);
+static const char* host_getfromenv(const char *host);
 
 /* dummy handler */
 static void dummy_signal(int signum) {
@@ -64,6 +66,23 @@
 #endif
 
 /*******************************************************************/
+/* Determine whether a hostname corresponds to localhost or not */
+static int host_is_localhost(const char *host)
+{
+    /* FIXME - there must be a better way than this... */
+    if(host == NULL) return 1;
+    if(!strcmp(host, "localhost")) return 1;
+    return 0;
+}
+
+/*******************************************************************/
+/* Read hostname from environment vars if appropriate */
+static const char* host_getfromenv(const char *host)
+{
+    return host ? host : getenv("ESPEAKER");
+}
+
+/*******************************************************************/
 /* set socket buffer lengths to optimal length for audio data transfer */
 int esd_set_socket_buffers( int sock, int src_format, 
 			    int src_rate, int base_rate )
@@ -351,7 +370,10 @@
   unsigned int host_div = 0;
   
   /* see if we have a remote speaker to play to */
-  espeaker = host ? host : getenv( "ESPEAKER" );
+  /* FIXME - tidy all this code up - for starters the espeaker env
+   * variable has already been checked now. */
+  /* espeaker = host ? host : getenv( "ESPEAKER" );*/
+  espeaker = host;
   if ( espeaker != NULL ) {
     /* split the espeaker host into host:port */
     host_div = strcspn( espeaker, ":" );
@@ -389,7 +411,7 @@
   socket_out = socket( AF_INET, SOCK_STREAM, 0 );
   if ( socket_out < 0 ) 
     {
-      fprintf(stderr,"Unable to create tcp socket\n");
+      fprintf(stderr,"Unable to create socket\n");
       return( -1 );
     }
   
@@ -451,92 +473,103 @@
   
   if ( connect( socket_out,
 	       (struct sockaddr *) &socket_unix,
-	       sizeof(struct sockaddr_un) ) < 0 )
+	       sizeof(socket_unix.sun_family) + 
+	       strlen(socket_unix.sun_path) ) < 0 )
     return -1;
   
   return socket_out;
 }
 
 /*******************************************************************/
-/* initialize the socket to send data to the sound daemon */
-int esd_open_sound( const char *host )
-{
-  int connect_count = 0;
-  int socket_out = -1;
-  char use_unix = 0;
-  
-  if (access(ESD_UNIX_SOCKET_NAME, R_OK | W_OK) == -1)
+/* try spawning a new esd (but only if config file allows us)
+ * This function returns 1 if spawning happened, 0 if not. */
+static int esd_try_spawning() {
+    int childpid;
+
+    esd_config_read();
+    if (esd_no_spawn) return 0;
+
+    childpid = fork();
+    if (!childpid)
     {
-      if (errno == EACCES) 
-	{
-	  /* not allowed access - can't init unix socket comms - esd already */
-	  /* there */
-          socket_out = esd_connect_tcpip(host);
-	}
-      else if (errno == ENOENT)
+	if (!fork())
 	{
-	  use_unix = 1;
-	  /* does not exist - try tcp/ip */
-	  socket_out = esd_connect_tcpip(host);	  
+	    char *cmd;
+
+	    setsid();
+
+	    cmd = malloc(sizeof("esd ") + strlen(esd_spawn_options));
+	    sprintf(cmd, "esd %s", esd_spawn_options);
+
+	    execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
+	    perror("execl");
+	    _exit(1);
 	}
+	else
+	    _exit(0);
     }
-  else
-    use_unix = 1;
-
-  /* tcp/ip fialed or we havent tried unix sockets yet */
-  if (socket_out < 0)
+    else
     {
-      if (use_unix)
-	socket_out = esd_connect_unix(host);
-      else
-	socket_out = esd_connect_tcpip(host);
+	int estat;
+	waitpid(childpid, &estat, 0); /* reap zombie */
     }
+    return 1;
+}
 
-  /* try tcp/ip, if we tried via usock and it didn't work */
-  if ((socket_out < 0) && use_unix)
-    socket_out = esd_connect_tcpip(host);
-
-  /* esd basically is uncontactable - lets run it and try again */
-  if (socket_out < 0)
-    {
-      esd_config_read();
+/*******************************************************************/
+/* initialize the socket to send data to the sound daemon */
+int esd_open_sound( const char *host )
+{
+  int connect_count = 0;
+  int socket_out = -1;
+  char try_unix = 1;   /* Whether it's worth trying UNIX sockets */
+  char try_spawn = 1;  /* Whether it's worth trying to spawn a new esd */
+  int spawned = 0;
+
+  /* Read hostname from environment vars if appropriate */
+  host = host_getfromenv(host);
+
+  if (!host_is_localhost(host))
+    {
+      /* Host is not local - so we MUST use TCP sockets, and there's
+       * no point in trying to spawn. */
+	try_unix = 0;
+	try_spawn = 0;
+    }
+
+  if (try_unix)
+    if (access(ESD_UNIX_SOCKET_NAME, R_OK | W_OK) == -1)
+      {
+	if (errno == EACCES) 
+	  {
+	    /* not allowed access - can't init unix socket comms
+	     * This means that something is already there, so we're
+	     * not going to be able to make unix sockets work */
+	    try_unix = 0;
+	  }
+	else if (errno == ENOENT)
+	  {
+	    /* does not exist - try tcp/ip, but if this fails we
+	     * can still try to set things up using unix sockets */
+	    socket_out = esd_connect_tcpip(host);
+	  }
+      }
 
-      if (!esd_no_spawn && !getenv("ESPEAKER"))
-	{
-	  int childpid;
+  /* Try making a UNIX connection */
+  if ((socket_out < 0) && try_unix)
+    socket_out = esd_connect_unix(host);
 
-	  childpid = fork();
-	  if (!childpid)
-	    {
-	      if (!fork())
-		{
-		  char *cmd;
-
-		  setsid();
-		  
-		  cmd = malloc(sizeof("esd ") + strlen(esd_spawn_options));
-		  sprintf(cmd, "esd %s", esd_spawn_options);
-
-		  execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
-		  perror("execl");
-		  _exit(1);
-		}
-	      else
-		_exit(0);
-	    }
-	  else
-	    {
-	      int estat;
-	      waitpid(childpid, &estat, 0); /* reap zombie */
-	    }
-	}
-      else
-	return socket_out;
-    }
+  /* If no connection yet, try TCP */
+  if (socket_out < 0)
+    socket_out = esd_connect_tcpip(host);
 
-  /* sit and spin for a bit to wait for esd to start - try 5 times over */
-  /* 5 seconds - if esd still hasnt started - give up */
-  while ((socket_out < 0) && (connect_count < 60))
+  /* ESD is uncontactable - try running it and try again */
+  if ((socket_out < 0) && try_spawn)
+    spawned = esd_try_spawning();
+
+  /* sit and spin for a bit to wait for esd to start - try 50 times */
+  /* in 5 seconds - if esd still hasnt started - give up */
+  while (spawned && (socket_out < 0) && (connect_count < 50))
     {
 #if defined(HAVE_NANOSLEEP) && !defined(HAVE_USLEEP)
       struct timespec timewait;
@@ -545,15 +578,19 @@
       socket_out = esd_connect_unix(host);
       if (socket_out < 0)
 	socket_out = esd_connect_tcpip(host);
-      connect_count++;
 
+      if (socket_out < 0)
+	{
+	  connect_count++;
+	  /* Wait 100ms */
 #if defined(HAVE_USLEEP)
-      usleep(1000);
+	  usleep(100000);
 #elif defined(HAVE_NANOSLEEP)
-      timewait.tv_sec = 0;
-      timewait.tv_nsec = 10000000;
-      nanosleep(&timewait, NULL);
+	  timewait.tv_sec = 0;
+	  timewait.tv_nsec = 100000000;
+	  nanosleep(&timewait, NULL);
 #endif
+	}
     }
 
   if (socket_out >= 0)
@@ -639,8 +676,9 @@
     if ( socket_out >= 0 ) 
 	return socket_out;
 
-    /* if ESPEAKER is set, this is an error, bail out */
-    if ( getenv( "ESPEAKER" ) )
+    /* if we're not trying to connect to localhost, this is an error
+     * so bail out. */
+    if (!host_is_localhost(host_getfromenv(host)));
 	return -1;
 
     /* go for /dev/dsp */
@@ -847,8 +885,9 @@
     if ( socket_out >= 0 ) 
 	return socket_out;
 
-    /* if ESPEAKER is set, this is an error, bail out */
-    if ( getenv( "ESPEAKER" ) )
+    /* if we're not trying to connect to localhost, this is an error
+     * so bail out. */
+    if (!host_is_localhost(host_getfromenv(host)));
 	return -1;
 
     /* go for /dev/dsp */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]