/* use usbdev*.* device names in /dev instead of the usbfs bus directories */
static int usbdev_names = 0;
+/* Linux 2.6.23 adds support for O_CLOEXEC when opening files, which marks the
+ * close-on-exec flag in the underlying file descriptor. */
+static int supports_flag_cloexec = -1;
+
/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically
* allows us to mark URBs as being part of a specific logical transfer when
* we submit them to the kernel. then, on any error except a cancellation, all
int iso_packet_offset;
};
+static int _open(const char *path, int flags)
+{
+#if defined(O_CLOEXEC)
+ if (supports_flag_cloexec)
+ return open(path, flags | O_CLOEXEC);
+ else
+#endif
+ return open(path, flags);
+}
+
static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
{
struct libusb_context *ctx = DEVICE_CTX(dev);
snprintf(path, PATH_MAX, "%s/%03d/%03d",
usbfs_path, dev->bus_number, dev->device_address);
- fd = open(path, mode | O_CLOEXEC);
+ fd = _open(path, mode);
if (fd != -1)
return fd; /* Success */
/* Wait 10ms for USB device path creation.*/
nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000UL}, NULL);
- fd = open(path, mode | O_CLOEXEC);
+ fd = _open(path, mode);
if (fd != -1)
return fd; /* Success */
}
if (monotonic_clkid == -1)
monotonic_clkid = find_monotonic_clock();
+ if (supports_flag_cloexec == -1) {
+ /* O_CLOEXEC flag available from Linux 2.6.23 */
+ supports_flag_cloexec = kernel_version_ge(2,6,23);
+ if (supports_flag_cloexec == -1) {
+ usbi_err(ctx, "error checking for O_CLOEXEC support");
+ return LIBUSB_ERROR_OTHER;
+ }
+ }
+
if (supports_flag_bulk_continuation == -1) {
/* bulk continuation URB flag available from Linux 2.6.32 */
supports_flag_bulk_continuation = kernel_version_ge(2,6,32);
snprintf(filename, PATH_MAX, "%s/%s/%s",
SYSFS_DEVICE_PATH, priv->sysfs_dir, attr);
- fd = open(filename, O_RDONLY | O_CLOEXEC);
+ fd = _open(filename, O_RDONLY);
if (fd < 0) {
usbi_err(DEVICE_CTX(dev),
"open %s failed ret=%d errno=%d", filename, fd, errno);
{
char filename[PATH_MAX];
FILE *f;
- int r, value;
+ int fd, r, value;
snprintf(filename, PATH_MAX, "%s/%s/%s", SYSFS_DEVICE_PATH,
devname, attr);
- f = fopen(filename, "re");
- if (f == NULL) {
+ fd = _open(filename, O_RDONLY);
+ if (fd == -1) {
if (errno == ENOENT) {
/* File doesn't exist. Assume the device has been
disconnected (see trac ticket #70). */
return LIBUSB_ERROR_IO;
}
+ f = fdopen(fd, "r");
+ if (f == NULL) {
+ usbi_err(ctx, "fdopen %s failed errno=%d", filename, errno);
+ close(fd);
+ return LIBUSB_ERROR_OTHER;
+ }
+
r = fscanf(f, "%d", &value);
fclose(f);
if (r != 1) {