diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/common_device_name.c | 22 | ||||
-rw-r--r-- | src/common_vgaarb.c | 2 | ||||
-rw-r--r-- | src/freebsd_pci.c | 8 | ||||
-rw-r--r-- | src/linux_sysfs.c | 26 | ||||
-rw-r--r-- | src/netbsd_pci.c | 4 | ||||
-rw-r--r-- | src/openbsd_pci.c | 2 | ||||
-rw-r--r-- | src/pciaccess_private.h | 13 | ||||
-rw-r--r-- | src/solx_devfs.c | 6 | ||||
-rw-r--r-- | src/x86_pci.c | 4 |
10 files changed, 60 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac index d63ad25..159ddf7 100644 --- a/configure.ac +++ b/configure.ac @@ -31,6 +31,7 @@ AC_CONFIG_HEADERS([config.h]) # Initialize Automake AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE +AC_USE_SYSTEM_EXTENSIONS # Initialize libtool AC_PROG_LIBTOOL diff --git a/src/common_device_name.c b/src/common_device_name.c index b2765dd..ad9ed9d 100644 --- a/src/common_device_name.c +++ b/src/common_device_name.c @@ -51,6 +51,7 @@ #define DO_MATCH(a,b) (((a) == PCI_MATCH_ANY) || ((a) == (b))) #ifdef HAVE_ZLIB + #include <zlib.h> typedef gzFile pci_id_file; @@ -68,11 +69,28 @@ pci_id_file_open(void) #define pci_id_file_gets(l, s, f) gzgets(f, l, s) #define pci_id_file_close(f) gzclose(f) -#else + +#else /* not zlib */ + typedef FILE * pci_id_file; -#define pci_id_file_open() fopen(PCIIDS_PATH "/pci.ids", "r") + +static pci_id_file +pci_id_file_open(void) +{ + pci_id_file result; + +#ifndef __sun + result = fopen(PCIIDS_PATH "/pci.ids", "re"); + if (result) + return result; +#endif + + return fopen(PCIIDS_PATH "/pci.ids", "r"); +} + #define pci_id_file_gets(l, s, f) fgets(l, s, f) #define pci_id_file_close(f) fclose(f) + #endif /** diff --git a/src/common_vgaarb.c b/src/common_vgaarb.c index 86eceb5..ab3c5e8 100644 --- a/src/common_vgaarb.c +++ b/src/common_vgaarb.c @@ -129,7 +129,7 @@ pci_device_vgaarb_init(void) if (!pci_sys) return -1; - if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR)) < 0) { + if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR | O_CLOEXEC)) < 0) { return errno; } diff --git a/src/freebsd_pci.c b/src/freebsd_pci.c index d11535d..cc50e91 100644 --- a/src/freebsd_pci.c +++ b/src/freebsd_pci.c @@ -108,7 +108,7 @@ pci_device_freebsd_map_range(struct pci_device *dev, int fd, err = 0; - fd = open("/dev/mem", O_RDWR); + fd = open("/dev/mem", O_RDWR | O_CLOEXEC); if (fd == -1) return errno; @@ -153,7 +153,7 @@ pci_device_freebsd_unmap_range( struct pci_device *dev, if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) || (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) { - fd = open("/dev/mem", O_RDWR); + fd = open("/dev/mem", O_RDWR | O_CLOEXEC); if (fd != -1) { mrd.mr_base = map->base; mrd.mr_len = map->size; @@ -293,7 +293,7 @@ pci_device_freebsd_read_rom( struct pci_device * dev, void * buffer ) } printf("Using rom_base = 0x%lx\n", (long)rom_base); - memfd = open( "/dev/mem", O_RDONLY ); + memfd = open( "/dev/mem", O_RDONLY | O_CLOEXEC ); if ( memfd == -1 ) return errno; @@ -585,7 +585,7 @@ pci_system_freebsd_create( void ) int i; /* Try to open the PCI device */ - pcidev = open( "/dev/pci", O_RDWR ); + pcidev = open( "/dev/pci", O_RDWR | O_CLOEXEC ); if ( pcidev == -1 ) return ENXIO; diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 9566d40..b817860 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -98,7 +98,7 @@ pci_system_linux_sysfs_create( void ) if ( pci_sys != NULL ) { pci_sys->methods = & linux_sysfs_methods; #ifdef HAVE_MTRR - pci_sys->mtrr_fd = open("/proc/mtrr", O_WRONLY); + pci_sys->mtrr_fd = open("/proc/mtrr", O_WRONLY | O_CLOEXEC); #endif err = populate_entries(pci_sys); } @@ -245,7 +245,7 @@ pci_device_linux_sysfs_probe( struct pci_device * dev ) dev->bus, dev->dev, dev->func ); - fd = open( name, O_RDONLY ); + fd = open( name, O_RDONLY | O_CLOEXEC); if ( fd != -1 ) { char * next; pciaddr_t low_addr; @@ -307,7 +307,7 @@ pci_device_linux_sysfs_read_rom( struct pci_device * dev, void * buffer ) dev->dev, dev->func ); - fd = open( name, O_RDWR ); + fd = open( name, O_RDWR | O_CLOEXEC); if ( fd == -1 ) { #ifdef LINUX_ROM /* If reading the ROM using sysfs fails, fall back to the old @@ -388,7 +388,7 @@ pci_device_linux_sysfs_read( struct pci_device * dev, void * data, dev->dev, dev->func ); - fd = open( name, O_RDONLY ); + fd = open( name, O_RDONLY | O_CLOEXEC); if ( fd == -1 ) { return errno; } @@ -448,7 +448,7 @@ pci_device_linux_sysfs_write( struct pci_device * dev, const void * data, dev->dev, dev->func ); - fd = open( name, O_WRONLY ); + fd = open( name, O_WRONLY | O_CLOEXEC); if ( fd == -1 ) { return errno; } @@ -499,7 +499,7 @@ pci_device_linux_sysfs_map_range_wc(struct pci_device *dev, dev->dev, dev->func, map->region); - fd = open(name, open_flags); + fd = open(name, open_flags | O_CLOEXEC); if (fd == -1) return errno; @@ -564,7 +564,7 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev, dev->func, map->region); - fd = open(name, open_flags); + fd = open(name, open_flags | O_CLOEXEC); if (fd == -1) { return errno; } @@ -687,7 +687,7 @@ static void pci_device_linux_sysfs_enable(struct pci_device *dev) dev->dev, dev->func ); - fd = open( name, O_RDWR ); + fd = open( name, O_RDWR | O_CLOEXEC); if (fd == -1) return; @@ -709,7 +709,7 @@ static int pci_device_linux_sysfs_boot_vga(struct pci_device *dev) dev->dev, dev->func ); - fd = open( name, O_RDONLY ); + fd = open( name, O_RDONLY | O_CLOEXEC); if (fd == -1) return 0; @@ -752,7 +752,7 @@ pci_device_linux_sysfs_open_device_io(struct pci_io_handle *ret, snprintf(name, PATH_MAX, "%s/%04x:%02x:%02x.%1u/resource%d", SYS_BUS_PCI, dev->domain, dev->bus, dev->dev, dev->func, bar); - ret->fd = open(name, O_RDWR); + ret->fd = open(name, O_RDWR | O_CLOEXEC); if (ret->fd < 0) return NULL; @@ -775,7 +775,7 @@ pci_device_linux_sysfs_open_legacy_io(struct pci_io_handle *ret, snprintf(name, PATH_MAX, "/sys/class/pci_bus/%04x:%02x/legacy_io", dev->domain, dev->bus); - ret->fd = open(name, O_RDWR); + ret->fd = open(name, O_RDWR | O_CLOEXEC); if (ret->fd >= 0) break; @@ -897,7 +897,7 @@ pci_device_linux_sysfs_map_legacy(struct pci_device *dev, pciaddr_t base, snprintf(name, PATH_MAX, "/sys/class/pci_bus/%04x:%02x/legacy_mem", dev->domain, dev->bus); - fd = open(name, flags); + fd = open(name, flags | O_CLOEXEC); if (fd >= 0) break; @@ -906,7 +906,7 @@ pci_device_linux_sysfs_map_legacy(struct pci_device *dev, pciaddr_t base, /* If not, /dev/mem is the best we can do */ if (!dev) - fd = open("/dev/mem", flags); + fd = open("/dev/mem", flags | O_CLOEXEC); if (fd < 0) return errno; diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c index d351e8f..63585e3 100644 --- a/src/netbsd_pci.c +++ b/src/netbsd_pci.c @@ -94,7 +94,7 @@ pci_device_netbsd_map_range(struct pci_device *dev, struct mtrr mtrr; int fd, error, nmtrr, prot = PROT_READ; - if ((fd = open("/dev/mem", O_RDWR)) == -1) + if ((fd = open("/dev/mem", O_RDWR | O_CLOEXEC)) == -1) return errno; if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE) @@ -328,7 +328,7 @@ pci_system_netbsd_create(void) int bus, dev, func, ndevs, nfuncs; uint32_t reg; - pcifd = open("/dev/pci0", O_RDWR); + pcifd = open("/dev/pci0", O_RDWR | O_CLOEXEC); if (pcifd == -1) return ENXIO; diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c index 14e976d..74b3636 100644 --- a/src/openbsd_pci.c +++ b/src/openbsd_pci.c @@ -568,7 +568,7 @@ pci_system_openbsd_create(void) for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) { snprintf(path, sizeof(path), "/dev/pci%d", domain); - pcifd[domain] = open(path, O_RDWR); + pcifd[domain] = open(path, O_RDWR | O_CLOEXEC); if (pcifd[domain] == -1) break; ndomains++; diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h index 32f8a75..fea9c9f 100644 --- a/src/pciaccess_private.h +++ b/src/pciaccess_private.h @@ -37,6 +37,19 @@ # define _pci_hidden #endif /* GNUC >= 4 */ +/* + * O_CLOEXEC fixes an fd leak case (see 'man 2 open' for details). I don't + * know of any OS we support where this isn't available in a sufficiently + * new version, so warn unconditionally. + */ +#include <sys/fcntl.h> + +#ifndef O_CLOEXEC +#warning O_CLOEXEC not available, please upgrade. +#define O_CLOEXEC 0 +#endif + + struct pci_device_mapping; int pci_fill_capabilities_generic( struct pci_device * dev ); diff --git a/src/solx_devfs.c b/src/solx_devfs.c index 5e91a14..2079df0 100644 --- a/src/solx_devfs.c +++ b/src/solx_devfs.c @@ -663,7 +663,7 @@ probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg) nexus_path, first_bus, last_bus); #endif - if ((fd = open(nexus_path, O_RDWR)) >= 0) { + if ((fd = open(nexus_path, O_RDWR | O_CLOEXEC)) >= 0) { nexus->fd = fd; nexus->path = strdup(nexus_path); nexus_dev_path = di_devfs_path(di_node); @@ -931,7 +931,7 @@ pci_device_solx_devfs_map_range(struct pci_device *dev, else strcpy (map_dev, "/dev/fb0"); - if ((map_fd = open(map_dev, O_RDWR)) < 0) { + if ((map_fd = open(map_dev, O_RDWR | O_CLOEXEC)) < 0) { err = errno; (void) fprintf(stderr, "can not open %s: %s\n", map_dev, strerror(errno)); @@ -944,7 +944,7 @@ pci_device_solx_devfs_map_range(struct pci_device *dev, * Still used xsvc to do the user space mapping */ if (xsvc_fd < 0) { - if ((xsvc_fd = open("/dev/xsvc", O_RDWR)) < 0) { + if ((xsvc_fd = open("/dev/xsvc", O_RDWR | O_CLOEXEC)) < 0) { err = errno; (void) fprintf(stderr, "can not open /dev/xsvc: %s\n", strerror(errno)); diff --git a/src/x86_pci.c b/src/x86_pci.c index c42d3e0..78e5f6c 100644 --- a/src/x86_pci.c +++ b/src/x86_pci.c @@ -330,7 +330,7 @@ pci_device_x86_read_rom(struct pci_device *dev, void *buffer) return ENOSYS; } - memfd = open("/dev/mem", O_RDONLY); + memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC); if (memfd == -1) return errno; @@ -475,7 +475,7 @@ static int pci_device_x86_map_range(struct pci_device *dev, struct pci_device_mapping *map) { - int memfd = open("/dev/mem", O_RDWR); + int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC); int prot = PROT_READ; if (memfd == -1) |