mirror of
https://github.com/RPCS3/libusb.git
synced 2026-07-19 21:03:32 -04:00
linux: Apply v2 version of patch for CLOEXEC changes
Somehow I managed to push v1 of the patch, which didn't handle older
versions of the kernel or C library that don't support the O_CLOEXEC
flag (suggested by Tim Roberts). This commit amends the original
changes in aa73b2ec and provides this backwards compatibility.
Closes #286
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This commit is contained in:
+36
-6
@@ -81,6 +81,10 @@ static const char *usbfs_path = NULL;
|
||||
/* 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
|
||||
@@ -180,6 +184,16 @@ struct linux_transfer_priv {
|
||||
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);
|
||||
@@ -194,7 +208,7 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
||||
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 */
|
||||
|
||||
@@ -205,7 +219,7 @@ static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
|
||||
/* 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 */
|
||||
}
|
||||
@@ -387,6 +401,15 @@ static int op_init(struct libusb_context *ctx)
|
||||
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);
|
||||
@@ -526,7 +549,7 @@ static int _open_sysfs_attr(struct libusb_device *dev, const char *attr)
|
||||
|
||||
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);
|
||||
@@ -542,12 +565,12 @@ static int __read_sysfs_attr(struct libusb_context *ctx,
|
||||
{
|
||||
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). */
|
||||
@@ -557,6 +580,13 @@ static int __read_sysfs_attr(struct libusb_context *ctx,
|
||||
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) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define LIBUSB_NANO 11194
|
||||
#define LIBUSB_NANO 11195
|
||||
|
||||
Reference in New Issue
Block a user