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