File sysvinit-2.90-no-kill.patch of Package sysvinit

---
 src/killall5.c |  145 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 132 insertions(+), 13 deletions(-)

--- src/killall5.c
+++ src/killall5.c	2023-05-02 14:14:02.198263058 +0000
@@ -67,6 +67,9 @@
 #endif
 
 #define STATNAMELEN	15
+#define DO_NETFS 2
+#define DO_STAT 1
+#define NO_STAT 0
 
 /* Info about a process. */
 typedef struct proc {
@@ -76,6 +79,8 @@ typedef struct proc {
 	char *argv1;		/* Name as found out from argv[1] */
 	char *argv1base;	/* `basename argv[1]`		  */
 	char *statname;		/* the statname without braces    */
+	ino_t ino;		/* Inode number			  */
+	dev_t dev;		/* Device it is on		  */
 	pid_t pid;		/* Process ID.			  */
 	pid_t sid;		/* Session ID.			  */
 	char kernel;		/* Kernel thread or zombie.	  */
@@ -473,20 +478,54 @@ 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.
  *	CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
  */
-int readproc()
+int readproc(int do_stat)
 {
 	DIR		*dir;
 	FILE		*fp;
 	PROC		*p, *n;
 	struct dirent	*d;
+	struct stat	st;
 	char		path[PATH_MAX+1];
 	char		buf[PATH_MAX+1];
 	char		*s, *q;
 	unsigned long	startcode, endcode;
 	int		pid, f;
+	ssize_t		len;
         char            process_status[11];
 
 	/* Open the /proc directory. */
@@ -593,8 +632,12 @@ int readproc()
 				p->kernel = 1;
 			fclose(fp);
                         if ( (! list_dz_processes) &&
-                               (strchr(process_status, 'Z') != NULL) ) {
-                           /* Ignore zombie processes */
+                             ( (strchr(process_status, 'D') != NULL) ||
+                               (strchr(process_status, 'Z') != NULL) ) ){
+                           /* Ignore zombie processes or processes in
+                              disk sleep, as attempts
+                              to access the stats of these will
+                              sometimes fail. */
                               if (p->argv0) free(p->argv0);
                               if (p->argv1) free(p->argv1);
                               if (p->statname) free(p->statname);
@@ -661,11 +704,76 @@ int readproc()
 
 		/* Try to stat the executable. */
 		snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
-                p->pathname = (char *)xmalloc(PATH_MAX);
-                memset(p->pathname, 0, PATH_MAX);
- 		if (readlink(path, p->pathname, PATH_MAX) == -1) {
- 			p->pathname = NULL;
- 		}
+
+		p->nfs = 0;
+
+		switch (do_stat) {
+		case NO_STAT:
+			if ((len = readlink(path, buf, PATH_MAX)) < 0)
+				break;
+			buf[len] = '\0';
+
+			/* Check for uevent handler, mdmon, and for providers
+			   of FUSE filesystems */
+			if ((strncmp(buf, "/usr/sbin/mdmon", 15) == 0) ||
+			    (strncmp(buf, "/sbin/mdmon", 11) == 0) ||
+			    (strncmp(buf, "/usr/lib/systemd/systemd-udevd", 30) == 0) ||
+			    (is_fuse(d->d_name))) {
+				OMIT *restrict optr;
+
+				xmemalign((void*)&optr, sizeof(void*), alignof(OMIT));
+				optr->next = omit;
+				optr->prev = (OMIT*)0;
+				optr->pid  = pid;
+				omit = optr;
+			}
+
+			break;
+		case DO_NETFS:
+			if ((p->nfs = check4nfs(path, buf)))
+				goto link;
+			 /* else fall through */
+		case DO_STAT:
+			if (stat(path, &st) != 0) {
+				char * ptr;
+
+				len = readlink(path, buf, PATH_MAX);
+				if (len <= 0)
+					break;
+				buf[len] = '\0';
+
+				ptr = strstr(buf, " (deleted)");
+				if (!ptr)
+					break;
+				*ptr = '\0';
+				len -= strlen(" (deleted)");
+
+				if (stat(buf, &st) != 0)
+					break;
+				p->dev = st.st_dev;
+				p->ino = st.st_ino;
+				p->pathname = (char *)xmalloc(len + 1);
+				memcpy(p->pathname, buf, len);
+				p->pathname[len] = '\0';
+
+				/* All done */
+				break;
+			}
+
+			p->dev = st.st_dev;
+			p->ino = st.st_ino;
+
+			/* Fall through */
+		default:
+		link:
+			len = readlink(path, buf, PATH_MAX);
+			if (len > 0) {
+				p->pathname = (char *)xmalloc(len + 1);
+				memcpy(p->pathname, buf, len);
+				p->pathname[len] = '\0';
+			}
+			break;
+		}
 
 		/* Link it into the list. */
 		p->next = plist;
@@ -728,6 +836,7 @@ PIDQ_HEAD *pidof(char *prog)
 {
 	PROC		*p;
 	PIDQ_HEAD	*q;
+	struct stat	st;
 	char		*s;
 	int		nfs = 0;
 	int		dostat = 0;
@@ -742,7 +851,15 @@ PIDQ_HEAD *pidof(char *prog)
 	/* Try to stat the executable. */
 	memset(real_path, 0, sizeof(real_path));
 	if ( (prog[0] == '/') && ( realpath(prog, real_path) ) ) {
-		dostat++;
+
+		if (check4nfs(prog, real_path))
+			nfs++;
+
+		if (real_path[0] != '\0')
+			prog = &real_path[0];	/* Binary located on network FS. */
+
+		if ((nfs == 0) && (stat(prog, &st) == 0))
+			dostat++;		/* Binary located on a local FS. */
 	}
 
 	/* Get basename of program. */
@@ -758,9 +875,11 @@ PIDQ_HEAD *pidof(char *prog)
 	q = init_pid_q(q);
 
 	/* First try to find a match based on dev/ino pair. */
-	if (dostat) {
+	if (dostat && !nfs) {
 		for (p = plist; p; p = p->next) {
-			if (p->pathname && strcmp(real_path, p->pathname) == 0) {
+			if (p->nfs)
+				continue;
+			if (p->dev == st.st_dev && p->ino == st.st_ino) {
 				add_pid_to_q(q, p);
 				foundone++;
 			}
@@ -1026,7 +1145,7 @@ int main_pidof(int argc, char **argv)
 		init_nfs();		/* Which network based FS are online? */
 
 	/* Print out process-ID's one by one. */
-	readproc();
+	readproc((flags & PIDOF_NETFS) ? DO_NETFS : DO_STAT);
 
 	for(f = 0; f < argc; f++) {
 		if ((q = pidof(argv[f])) != NULL) {
@@ -1171,7 +1290,7 @@ int main(int argc, char **argv)
         }
 
 	/* Read /proc filesystem */
-	if (readproc() < 0) {
+	if (readproc(NO_STAT) < 0) {
              if (sent_sigstop)
 		kill(-1, SIGCONT);
   	     return(1);
openSUSE Build Service is sponsored by