Do not blindly use ftok() in snapscani_mutex_open(). Compute an IPC key based

on the product ID, bus number and device number for libusb devices; fallback
to ftok() otherwise and check the return value.
merge-requests/1/head
Julien BLACHE 2008-03-28 20:39:02 +00:00
rodzic 1ee8fa1d8f
commit 8ed0d66582
4 zmienionych plików z 106 dodań i 5 usunięć

Wyświetl plik

@ -1,3 +1,12 @@
2008-03-28 Julien Blache <jb@jblache.org>
* sanei/sanei_usb.c, include/sane/sanei_usb.h: add
sanei_usb_get_vendor_product_byname().
* backend/snapscan-mutex.c: do not use ftok() in
snapscani_mutex_open(); ftok() will fail with anything for which
the devicename is not a filename. Construct an IPC key based on
the product ID, bus number and device number for libusb devices,
otherwise fallback to ftok() and check its return value.
2008-03-28 m. allan noah <kitno455 a t gmail d o t com>
* backend/hp-scl.c: add usleep to improve usb performance, from
jim a t meyering d o t net

Wyświetl plik

@ -118,13 +118,51 @@ static struct sembuf sem_signal = { 0, 1, 0 };
static int snapscani_mutex_open(snapscan_mutex_t* sem_id, const char* dev)
{
*sem_id = semget( ftok(dev,0x12), 1, IPC_CREAT | 0660 );
if (*sem_id != -1)
static const char *me = "snapscani_mutex_open";
key_t ipc_key;
int pid, devnum, busnum;
if (strstr(dev, "libusb:") == dev)
{
semop(*sem_id, &sem_signal, 1);
return 1;
if (sanei_usb_get_vendor_product_byname(dev, NULL, &pid) != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR, "%s: could not obtain USB product ID for device %s\n", me, dev);
return 0;
}
if (sscanf(dev, "libusb:%d:%d", &busnum, &devnum) != 2)
{
DBG (DL_MAJOR_ERROR, "%s: could not parse device string: %s\n", me, strerror(errno));
return 0;
}
ipc_key = pid << 16;
ipc_key |= (busnum & 0xff) << 8;
ipc_key |= (devnum & 0xff);
DBG (DL_INFO, "%s: using IPC key 0x%08x for device %s (pid 0x%04x, bus 0x%02x, dev 0x%02x)\n",
me, ipc_key, dev, pid, busnum, devnum);
}
return 0;
else
{
ipc_key = ftok(dev, 0x12);
if (ipc_key == -1)
{
DBG (DL_MAJOR_ERROR, "%s: could not obtain IPC key for device %s: %s\n", me, dev, strerror(errno));
return 0;
}
}
*sem_id = semget( ipc_key, 1, IPC_CREAT | 0660 );
if (*sem_id == -1)
{
DBG (DL_MAJOR_ERROR, "%s: semget failed: %s\n", me, strerror(errno));
return 0;
}
semop(*sem_id, &sem_signal, 1);
return 1;
}
static void snapscani_mutex_close(snapscan_mutex_t* sem_id)

Wyświetl plik

@ -180,6 +180,22 @@ struct sanei_usb_dev_descriptor
*/
extern void sanei_usb_init (void);
/** Get the vendor and product ids by device name.
*
* @param devname
* @param vendor vendor id
* @param product product id
*
* @return
* - SANE_STATUS_GOOD - if the ids could be determined
* - SANE_STATUS_INVAL - if the device is not found
* - SANE_STATUS_UNSUPPORTED - if this method is not supported with the current
* access method
*/
SANE_Status
sanei_usb_get_vendor_product_byname (SANE_String_Const devname,
SANE_Word * vendor, SANE_Word * product);
/** Get the vendor and product ids.
*
* Currently, only libusb devices and scanners supported by the Linux USB

Wyświetl plik

@ -646,6 +646,44 @@ sanei_usb_attach_matching_devices (const char *name,
(*attach) (name);
}
SANE_Status
sanei_usb_get_vendor_product_byname (SANE_String_Const devname,
SANE_Word * vendor, SANE_Word * product)
{
int devcount;
SANE_Bool found = SANE_FALSE;
for (devcount = 0; devcount < MAX_DEVICES && devices[devcount].devname != 0;
devcount++)
{
if (strcmp (devices[devcount].devname, devname) == 0)
{
found = SANE_TRUE;
break;
}
}
if (!found)
{
DBG (1, "sanei_usb_get_vendor_product_byname: can't find device `%s' in list\n", devname);
return SANE_STATUS_INVAL;
}
if ((devices[devcount].vendor == 0) && (devices[devcount].product == 0))
{
DBG (1, "sanei_usb_get_vendor_product_byname: not support for this method\n");
return SANE_STATUS_UNSUPPORTED;
}
if (vendor)
*vendor = devices[devcount].vendor;
if (product)
*product = devices[devcount].product;
return SANE_STATUS_GOOD;
}
SANE_Status
sanei_usb_get_vendor_product (SANE_Int dn, SANE_Word * vendor,
SANE_Word * product)