Using fork or pthread makes no difference.

A sleep at the end of main() works wonders.

But not for the other exit() functions. 'scanimage -h' or 'scanimage -A'
still hang with the same issue.

I suggest to replace atexit and all exit() functions by the existing
scanimage_exit() function.

Please check if attached patch is running with your installations.

Cheers,
Rolf

Am 18.08.2015 um 03:31 schrieb m. allan noah:
> Good point. Rolf- any chance you could insert a sleep at the end of
> main()? Also, does the backend in question use fork() on this distro?
> 
> allan
> 
> On Mon, Aug 17, 2015 at 8:30 PM, Olaf Meeuwissen
> <olaf.meeuwis...@avasys.jp> wrote:
>>
>> m. allan noah writes:
>>
>>> I don't understand. Registered atexit handlers should be called when
>>> main() returns, which is after sane_cancel. What version of
>>> libusb-compat is in use?
>>
>> Please remember that sane_cancel() only *initiates* cancellation.  So
>> cancellation may not have finished yet when main() returns.  I'm not
>> sure if this is causing the problem but thought I'd mention it anyway.
>>
>> Hope this helps,
>> --
>> Olaf Meeuwissen, LPIC-2     FLOSS Engineer -- EPSON AVASYS CORPORATION
>> FSF Associate Member #1962               Help support software freedom
>>                  http://www.fsf.org/jf?referrer=1962
> 
> 
> 
--- ./scanimage.c	2015-08-18 13:02:23.132264339 +0200
+++ ../sane-backends/frontend/scanimage.c	2015-08-18 13:02:39.791040702 +0200
@@ -135,7 +135,7 @@
 static const char *icc_profile = NULL;
 
 static void fetch_options (SANE_Device * device);
-static void scanimage_exit (void);
+static void scanimage_exit (int);
 
 static SANE_Word tl_x = 0;
 static SANE_Word tl_y = 0;
@@ -687,7 +687,7 @@
       fprintf (stderr,
 	       "%s: option --%s: bad option value (rest of option: %s)\n",
 	       prog_name, opt->name, str);
-      exit (1);
+      scanimage_exit (1);
     }
   str = end;
 
@@ -796,7 +796,7 @@
 	    {
 	      fprintf (stderr, "%s: option --%s: closing bracket missing "
 		       "(rest of option: %s)\n", prog_name, opt->name, str);
-	      exit (1);
+	      scanimage_exit (1);
 	    }
 	  str = end + 1;
 	}
@@ -808,20 +808,20 @@
 	  fprintf (stderr,
 		   "%s: option --%s: index %d out of range [0..%ld]\n",
 		   prog_name, opt->name, index, (long) vector_length - 1);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       /* read value */
       str = parse_scalar (opt, str, &value);
       if (!str)
-	exit (1);
+        scanimage_exit (1);
 
       if (*str && *str != '-' && *str != ',')
 	{
 	  fprintf (stderr,
 		   "%s: option --%s: illegal separator (rest of option: %s)\n",
 		   prog_name, opt->name, str);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       /* store value: */
@@ -874,7 +874,7 @@
   if (opt == NULL)
     {
       fprintf (stderr, "Could not get option descriptor for option 0\n");
-      exit (1);
+      scanimage_exit (1);
     }
 
   status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE,
@@ -883,7 +883,7 @@
     {
       fprintf (stderr, "Could not get value for option 0: %s\n",
                sane_strstatus (status));
-      exit (1);
+      scanimage_exit (1);
     }
 
   /* build the full table of long options */
@@ -894,7 +894,7 @@
       if (opt == NULL)
 	{
 	  fprintf (stderr, "Could not get option descriptor for option %d\n",i);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       /* create command line option only for settable options */
@@ -1013,7 +1013,7 @@
     {
       fprintf (stderr, "%s: setting of option --%s failed (%s)\n",
 	       prog_name, opt->name, sane_strstatus (status));
-      exit (1);
+      scanimage_exit (1);
     }
 
   if ((info & SANE_INFO_INEXACT) && opt->size == sizeof (SANE_Word))
@@ -1048,7 +1048,7 @@
     {
       fprintf (stderr, "%s: attempted to set inactive option %s\n",
 	       prog_name, opt->name);
-      exit (1);
+      scanimage_exit (1);
     }
 
   if ((opt->cap & SANE_CAP_AUTOMATIC) && optarg &&
@@ -1061,7 +1061,7 @@
 	  fprintf (stderr,
 		   "%s: failed to set option --%s to automatic (%s)\n",
 		   prog_name, opt->name, sane_strstatus (status));
-	  exit (1);
+	  scanimage_exit (1);
 	}
       return;
     }
@@ -1081,7 +1081,7 @@
 	    {
 	      fprintf (stderr, "%s: option --%s: bad option value `%s'\n",
 		       prog_name, opt->name, optarg);
-	      exit (1);
+	      scanimage_exit (1);
 	    }
 	}
       break;
@@ -1097,7 +1097,7 @@
 	  if (!vector)
 	    {
 	      fprintf (stderr, "%s: out of memory\n", prog_name);
-	      exit (1);
+	      scanimage_exit (1);
 	    }
 	}
       parse_vector (opt, optarg, vector, vector_length);
@@ -1109,7 +1109,7 @@
       if (!valuep)
 	{
 	  fprintf (stderr, "%s: out of memory\n", prog_name);
-	  exit (1);
+	  scanimage_exit (1);
 	}
       strncpy (valuep, optarg, opt->size);
       ((char *) valuep)[opt->size - 1] = 0;
@@ -1648,7 +1648,7 @@
 }
 
 static void
-scanimage_exit (void)
+scanimage_exit (int status)
 {
   if (device)
     {
@@ -1666,6 +1666,7 @@
     free (option_number);
   if (verbose > 1)
     fprintf (stderr, "scanimage: finished\n");
+  exit (status);
 }
 
 /** @brief print device options to stdout
@@ -1721,7 +1722,9 @@
   SANE_Int version_code;
   FILE *ofp = NULL;
 
+/* Fixme: atexit() isn't working with all Linux and libusb-compat installations
   atexit (scanimage_exit);
+*/
 
   buffer_size = (32 * 1024);	/* default size */
 
@@ -1819,7 +1822,7 @@
 	      {
 		fprintf (stderr, "%s: sane_get_devices() failed: %s\n",
 			 prog_name, sane_strstatus (status));
-		exit (1);
+		scanimage_exit (1);
 	      }
 
 	    if (ch == 'L')
@@ -1916,7 +1919,7 @@
 
 	    if (defdevname)
 	      printf ("default device is `%s'\n", defdevname);
-	    exit (0);
+	    scanimage_exit (0);
 	  }
 
 	case 'V':
@@ -1924,7 +1927,7 @@
 		  VERSION, SANE_VERSION_MAJOR (version_code),
 		  SANE_VERSION_MINOR (version_code),
 		  SANE_VERSION_BUILD (version_code));
-	  exit (0);
+	  scanimage_exit (0);
 
 	default:
 	  break;		/* ignore device specific options for now */
@@ -1985,12 +1988,12 @@
 	    {
 	      fprintf (stderr, "%s: sane_get_devices() failed: %s\n",
 		       prog_name, sane_strstatus (status));
-	      exit (1);
+	      scanimage_exit (1);
 	    }
 	  if (!device_list[0])
 	    {
 	      fprintf (stderr, "%s: no SANE devices found\n", prog_name);
-	      exit (1);
+	      scanimage_exit (1);
 	    }
 	  devname = device_list[0]->name;
 	}
@@ -2012,7 +2015,7 @@
       if (help)
 	device = 0;
       else
-	exit (1);
+        scanimage_exit (1);
     }
 
   if (device)
@@ -2025,7 +2028,7 @@
 	{
 	  fprintf (stderr, "%s: unable to get option count descriptor\n",
 		   prog_name);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       /* We got a device, find out how many options it has */
@@ -2035,7 +2038,7 @@
 	{
 	  fprintf (stderr, "%s: unable to determine option count\n",
 		   prog_name);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       /* malloc global option lists */
@@ -2047,7 +2050,7 @@
 	{
 	  fprintf (stderr, "%s: out of memory in main()\n",
 		   prog_name);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       /* load global option lists */
@@ -2078,7 +2081,7 @@
 	if (!full_optstring)
 	  {
 	    fprintf (stderr, "%s: out of memory\n", prog_name);
-	    exit (1);
+	    scanimage_exit (1);
 	  }
 
 	strcpy (full_optstring, BASE_OPTSTRING);
@@ -2099,7 +2102,7 @@
 	    {
 	    case ':':
 	    case '?':
-	      exit (1);		/* error message is printed by getopt_long() */
+	      scanimage_exit (1);		/* error message is printed by getopt_long() */
 
 	    case 'd':
 	    case 'h':
@@ -2139,7 +2142,7 @@
 	  fprintf (stderr, "%s: argument without option: `%s'; ", prog_name,
 		   argv[argc - 1]);
 	  fprintf (stderr, "try %s --help\n", prog_name);
-	  exit (1);
+	  scanimage_exit (1);
 	}
 
       free (full_optstring);
@@ -2172,7 +2175,7 @@
 	{
 	  printf ("\nAll options specific to device `%s':\n", devname);
 	  print_options(device, num_dev_options, SANE_TRUE);
-          exit (0);
+	  scanimage_exit (0);
 	}
     }
 
@@ -2205,11 +2208,11 @@
 	    }
 	}
       fputc ('\n', stdout);
-      exit (0);
+      scanimage_exit (0);
     }
 
   if (dont_scan)
-    exit (0);
+    scanimage_exit (0);
 
   if (output_format != OUTPUT_PNM)
     resolution_value = get_resolution ();
@@ -2245,7 +2248,7 @@
 
       else if(isatty(fileno(ofp))){
 	fprintf (stderr,"%s: output is not a file, exiting\n", prog_name);
-        exit (1);
+	scanimage_exit (1);
       }
 
       buffer = malloc (buffer_size);
@@ -2388,5 +2391,7 @@
   else
     status = test_it ();
 
+  scanimage_exit (status);
+  /* the line below avoids compiler warnings */
   return status;
 }
-- 
sane-devel mailing list: sane-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel
Unsubscribe: Send mail with subject "unsubscribe your_password"
             to sane-devel-requ...@lists.alioth.debian.org

Reply via email to