--- src/killall5.c +++ src/killall5.c 2009-01-27 16:32:40.048701097 +0100 @@ -59,6 +59,8 @@ typedef struct proc { pid_t pid; /* Process ID. */ int sid; /* Session ID. */ char kernel; /* Kernel thread or zombie. */ + char isfuse; /* Provides FUSE filesystems */ + char isudev; /* Is the uevent handler */ char nfs; /* Binary is loacted on NFS part. */ struct proc *next; /* Pointer to next struct. */ } PROC; @@ -283,6 +285,38 @@ int readarg(FILE *fp, char *buf, int sz) } /* + * Scan the filedescriptors of pid for /dev/fuse + */ +int is_fuse(const char *pid) { + DIR *dir; + char path[256]; + char buf[256]; + struct dirent *d; + ssize_t len; + + /* Open /proc/pid/fd/ */ + snprintf(path, sizeof(path), "/proc/%s/fd", pid); + if ((dir = opendir(path)) != NULL) { + int dfd = dirfd(dir); + /* Walk through the directory. */ + while ((d = readdir(dir)) != NULL) { + if (*d->d_name == '.') + continue; + /* check for /dev/fuse */ + if ((len = readlinkat(dfd, d->d_name, buf, sizeof(buf))) > 0) { + buf[len] = '\0'; + if (strcmp("/dev/fuse", buf) == 0) + return 1; /* Fuse filesystem */ + } + } + closedir(dir); + } + + /* Not a fuse filesystem */ + return 0; +} + +/* * Read the proc filesystem. */ int readproc() @@ -438,13 +472,19 @@ int readproc() /* Try to stat the executable. */ snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name); - if (check4nfs(path, NULL)) + if (check4nfs(path, buf)) p->nfs = 1; if ((p->nfs == 0) && (stat(path, &st) == 0)) { p->dev = st.st_dev; p->ino = st.st_ino; } + /* Check for uevent handler */ + p->isudev = (strncmp(buf, "/sbin/udevd", 11) == 0); + + /* Check for provider of FUSE filesystems */ + p->isfuse = is_fuse(d->d_name); + /* Link it into the list. */ p->next = plist; plist = p; @@ -779,14 +819,16 @@ int main(int argc, char **argv) exit(1); } - /* Now kill all processes except our session. */ + /* Now kill all processes except init (pid 1), our session, and FUSE filesystems. */ sid = (int)getsid(0); pid = (int)getpid(); for (p = plist; p; p = p->next) { - if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel) { + if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel || p->isfuse) { kill(p->pid, SIGCONT); continue; } + if (((sig == SIGTERM) || (sig == SIGKILL)) && p->isudev) + continue; kill(p->pid, sig); }