Signed-off-by: Jack Mitchell <jack@embed.me.uk>
Upstream-Status: Pending
Bug-Report: http://sourceforge.net/p/net-snmp/bugs/2449/

diff --git a/agent/mibgroup/if-mib/data_access/interface_linux.c b/agent/mibgroup/if-mib/data_access/interface_linux.c
index 3419811..d6eb91a 100644
--- a/agent/mibgroup/if-mib/data_access/interface_linux.c
+++ b/agent/mibgroup/if-mib/data_access/interface_linux.c
@@ -18,7 +18,31 @@ netsnmp_feature_require(interface_ioctl_flags_set)
 
 #ifdef HAVE_PCI_LOOKUP_NAME
 #include <pci/pci.h>
+#include <setjmp.h>
 static struct pci_access *pci_access;
+
+/* Avoid letting libpci call exit(1) when no PCI bus is available. */
+static int do_longjmp =0;
+static jmp_buf err_buf;
+static void
+netsnmp_pci_error(char *msg, ...)
+{
+    va_list args;
+    char *buf;
+    int buflen;
+
+    va_start(args, msg);
+    buflen = strlen("pcilib: ")+strlen(msg)+2;
+    buf = malloc(buflen);
+    snprintf(buf, buflen, "pcilib: %s\n", msg);
+    snmp_vlog(LOG_ERR, buf, args);
+    free(buf);
+    va_end(args);
+    if (do_longjmp)
+	longjmp(err_buf, 1);
+    else
+	exit(1);
+}
 #endif
 
 #ifdef HAVE_LINUX_ETHTOOL_H
@@ -147,10 +171,22 @@ netsnmp_arch_interface_init(void)
 
 #ifdef HAVE_PCI_LOOKUP_NAME
     pci_access = pci_alloc();
-    if (pci_access)
+    if (!pci_access) {
+	snmp_log(LOG_ERR, "pcilib: pci_alloc failed\n");
+	return;
+    }
+
+    pci_access->error = netsnmp_pci_error;
+
+    do_longjmp = 1;
+    if (setjmp(err_buf)) {
+        pci_cleanup(pci_access);
+	snmp_log(LOG_ERR, "pcilib: pci_init failed\n");
+        pci_access = NULL;
+    }
+    else if (pci_access)
 	pci_init(pci_access);
-    else
-	snmp_log(LOG_ERR, "Unable to create pci access method\n");
+    do_longjmp = 0;
 #endif
 }
 
