summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/common_device_name.c22
-rw-r--r--src/common_vgaarb.c2
-rw-r--r--src/freebsd_pci.c8
-rw-r--r--src/linux_sysfs.c26
-rw-r--r--src/netbsd_pci.c4
-rw-r--r--src/openbsd_pci.c2
-rw-r--r--src/pciaccess_private.h13
-rw-r--r--src/solx_devfs.c6
-rw-r--r--src/x86_pci.c4
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)