diff options
author | Bill Nottingham <notting@redhat.com> | 2004-12-22 23:10:31 +0000 |
---|---|---|
committer | Bill Nottingham <notting@redhat.com> | 2004-12-22 23:10:31 +0000 |
commit | 301385f8dc2d7fd0c11ea1305991dd2e64f063a3 (patch) | |
tree | ae95e8bb4fa45e0853c82451d346691091b01e49 | |
parent | 3002083491f885f01a554739479762226391c151 (diff) | |
download | initscripts-301385f8dc2d7fd0c11ea1305991dd2e64f063a3.tar initscripts-301385f8dc2d7fd0c11ea1305991dd2e64f063a3.tar.gz initscripts-301385f8dc2d7fd0c11ea1305991dd2e64f063a3.tar.bz2 initscripts-301385f8dc2d7fd0c11ea1305991dd2e64f063a3.tar.xz initscripts-301385f8dc2d7fd0c11ea1305991dd2e64f063a3.zip |
in order to avoid probing twice on startup, add a daemon mode that
waits for a connection on an abstract socket, and then dumps the
probe information. Requires a corresponding kudzu change to read
from said socket...
-rw-r--r-- | src/kmodule.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/src/kmodule.c b/src/kmodule.c index d7906ebe..8d1ea042 100644 --- a/src/kmodule.c +++ b/src/kmodule.c @@ -20,6 +20,9 @@ #include <popt.h> #include <sys/mman.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> #include <sys/utsname.h> #include <kudzu/kudzu.h> @@ -61,10 +64,68 @@ int isAvailable(char *modulename) return 0; } +char *dumpDevices(struct device **devlist) +{ + int fds[2],x; + FILE *tmp; + char *buf = NULL; + + pipe(fds); + tmp = fdopen(fds[1],"w"); + + buf = NULL; + for (x = 0; devlist[x]; x++) { + char b[4096]; + + devlist[x]->writeDevice(tmp,devlist[x]); + fflush(tmp); + memset(b,'\0',4096); + while (read(fds[0],b,4096)) { + if (!buf) { + buf = calloc(strlen(b)+1,sizeof(char)); + strcpy(buf,b); + buf[strlen(b)] = '\0'; + } else { + buf = realloc(buf, strlen(buf)+strlen(b)+1); + sprintf(buf,"%s%s",buf,b); + buf[strlen(buf)+strlen(b)] = '\0'; + } + if (strlen(b) != 4096) + break; + } + } + close(fds[0]); + close(fds[1]); + return buf; +} + +void waitForConnection(char *buf) +{ + int sock, fd, socklen; + struct sockaddr_un addr; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock == -1) return; + memset(addr.sun_path,'\0',sizeof(addr.sun_path)); + sprintf(addr.sun_path, "akudzu_config_socket"); + addr.sun_family= AF_UNIX; + addr.sun_path[0] = '\0'; + if (bind(sock, &addr, sizeof(struct sockaddr_un)) == -1) + return; + if (listen(sock, 1) == -1) + return; + fd = accept(sock, &addr, &socklen); + if (fd == -1) + return; + write(fd,buf,strlen(buf)); + close(fd); + close(sock); +} + int main(int argc, char **argv) { - char *bus = NULL, *class = NULL; - int x, rc; + char *bus = NULL, *class = NULL, *buf = NULL; + int x, rc, isdaemon = 0; enum deviceBus probeBus = BUS_UNSPEC & ~BUS_SERIAL; enum deviceClass probeClass = CLASS_UNSPEC; poptContext context; @@ -79,6 +140,9 @@ int main(int argc, char **argv) "probe only for the specified 'class'", NULL }, + { "daemon", 'd', POPT_ARG_NONE, &isdaemon, 0, + NULL, NULL + }, { 0, 0, 0, 0, 0, 0 } }; @@ -108,7 +172,7 @@ int main(int argc, char **argv) } initializeBusDeviceList(probeBus); - devs = probeDevices(probeClass, probeBus, PROBE_NOLOAD|PROBE_SAFE); + devs = probeDevices(probeClass, probeBus, PROBE_ALL|PROBE_NOLOAD|PROBE_SAFE); if (!devs) return 0; for (x = 0; devs[x]; x++) { @@ -122,5 +186,10 @@ int main(int argc, char **argv) printf("%s %s\n",classes[i].string,devs[x]->driver); } } + if (isdaemon) { + buf = dumpDevices(devs); + daemon(0,0); + waitForConnection(buf); + } return 0; } |