[PATCH] pccardctl: don't break lspcmcia if /sys/class/*/*/device is removed
The lspcmcia code-path now contains a workaround which allows it to produce
the same output even if the symlink /sys/class/*/*/device is removed.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
diff --git a/Makefile b/Makefile
index 7e8ca96..0c544c3 100644
--- a/Makefile
+++ b/Makefile
@@ -73,7 +73,7 @@
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
-SYMLINK = /usr/bin/ln -s
+SYMLINK = /usr/bin/ln -sf
# place to put our hotplug scripts nodes
hotplugdir = ${etcdir}/hotplug
diff --git a/src/pccardctl.c b/src/pccardctl.c
index eb2fd81..c4b370f 100644
--- a/src/pccardctl.c
+++ b/src/pccardctl.c
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
+#include <libgen.h>
#include <locale.h>
#include <ctype.h>
@@ -497,8 +498,10 @@
static int lspcmcia(unsigned long socket_no, int verbose)
{
char file[SYSFS_PATH_MAX];
- char drv[SYSFS_PATH_MAX];
- char dev[SYSFS_PATH_MAX];
+ char drv_s[SYSFS_PATH_MAX];
+ char dev_s[SYSFS_PATH_MAX];
+ char *drv;
+ char *dev;
char *res;
int ret, i;
@@ -506,24 +509,33 @@
return -ENODEV;
snprintf(file, SYSFS_PATH_MAX, "/sys/class/pcmcia_socket/pcmcia_socket%lu/device", socket_no);
- ret = readlink(file, dev, sizeof(dev) - 1);
- if (ret <= 0)
- return -EINVAL;
- else {
- dev[ret]='\0';
+ ret = readlink(file, dev_s, sizeof(dev_s) - 1);
+ if (ret > 0) {
+ dev_s[ret]='\0';
+ dev = basename(dev_s);
+ } else {
+ snprintf(file, SYSFS_PATH_MAX, "/sys/class/pcmcia_socket/pcmcia_socket%lu", socket_no);
+ ret = readlink(file, dev_s, sizeof(dev_s) - 1);
+ if (ret <= 0)
+ return -ENODEV;
+ dev_s[ret]='\0';
+ dev = basename(dirname(dev_s));
}
snprintf(file, SYSFS_PATH_MAX, "/sys/class/pcmcia_socket/pcmcia_socket%lu/device/driver", socket_no);
- ret = readlink(file, drv, sizeof(drv) - 1);
- if (ret <= 0)
- return -EINVAL;
- else {
- drv[ret]='\0';
+ ret = readlink(file, drv_s, sizeof(drv_s) - 1);
+ if (ret <= 0) {
+ snprintf(file, SYSFS_PATH_MAX, "/sys/class/pcmcia_socket/pcmcia_socket%lu/../driver", socket_no);
+ ret = readlink(file, drv_s, sizeof(drv_s) - 1);
+ if (ret <= 0)
+ return -ENODEV;
}
+ drv_s[ret]='\0';
+ drv = basename(drv_s);
- printf("Socket %lu Bridge: \t[%s] \t(bus ID: %s)\n", socket_no, basename(drv), basename(dev));
+ printf("Socket %lu Bridge: \t[%s] \t(bus ID: %s)\n", socket_no, drv, dev);
if (verbose)
- lspcmcia_socket(socket_no, verbose, basename(drv));
+ lspcmcia_socket(socket_no, verbose, drv);
pccardctl_get_string_socket(socket_no, "card_type", &res);
@@ -545,12 +557,12 @@
snprintf(file, SYSFS_PATH_MAX, "/sys/bus/pcmcia/devices/%lu.%u/driver",
socket_no, i);
- ret = readlink(file, drv, sizeof(drv) - 1);
+ ret = readlink(file, drv_s, sizeof(drv_s) - 1);
if (ret <= 0)
printf("[-- no driver --]\t");
else if (ret > 0) {
- drv[ret]='\0';
- printf("[%s]\t\t", basename(drv));
+ drv_s[ret]='\0';
+ printf("[%s]\t\t", basename(drv_s));
}
printf("(bus ID: %lu.%d)\n", socket_no, i);