Browse Source

s-s-d: Add a native FreeBSD pid_is_exec() method

Use the KERN_PROC_PATHNAME sysctl interface to retrieve the process
pathname. This will allow to stop requiring the linprocfs fileystem
which is not the native procfs and is not usually mounted by default
anyway.

This still has the problem that the pathname cannot be retrieved when
the inode has been unlinked, in the same way as when accessing the
/proc/<PID>/exe symlink from linprocfs.
Guillem Jover 12 years ago
parent
commit
8d70815833
2 changed files with 30 additions and 0 deletions
  1. 4 0
      debian/changelog
  2. 26 0
      utils/start-stop-daemon.c

+ 4 - 0
debian/changelog

@@ -57,6 +57,10 @@ dpkg (1.17.7) UNRELEASED; urgency=low
     - Add a generic KVM-based implementation to initialize the entire
     - Add a generic KVM-based implementation to initialize the entire
       process list.
       process list.
     - Fix FreeBSD KVM code to use current kinfo_proc layout.
     - Fix FreeBSD KVM code to use current kinfo_proc layout.
+    - Add a native FreeBSD pid_is_exec() method, which is more reliable than
+      the KVM-based one, and means neither linprocfs nor procfs are required
+      on such system anymore. Note that GNU/kFreeBSD is still using Linux
+      procfs code (which ends up using linprocfs).
 
 
   [ Updated dpkg translations ]
   [ Updated dpkg translations ]
   * German (Sven Joachim).
   * German (Sven Joachim).

+ 26 - 0
utils/start-stop-daemon.c

@@ -1199,6 +1199,32 @@ pid_is_exec(pid_t pid, const struct stat *esb)
 	return ((dev_t)pst.pst_text.psf_fsid.psfs_id == esb->st_dev &&
 	return ((dev_t)pst.pst_text.psf_fsid.psfs_id == esb->st_dev &&
 	        (ino_t)pst.pst_text.psf_fileid == esb->st_ino);
 	        (ino_t)pst.pst_text.psf_fileid == esb->st_ino);
 }
 }
+#elif defined(OSFreeBSD)
+static bool
+pid_is_exec(pid_t pid, const struct stat *esb)
+{
+	struct stat sb;
+	int error, name[4];
+	size_t len;
+	char pathname[PATH_MAX];
+
+	name[0] = CTL_KERN;
+	name[1] = KERN_PROC;
+	name[2] = KERN_PROC_PATHNAME;
+	name[3] = pid;
+	len = sizeof(pathname);
+
+	error = sysctl(name, 4, pathname, &len, NULL, 0);
+	if (error != 0 && errno != ESRCH)
+		return false;
+	if (len == 0)
+		pathname[0] = '\0';
+
+	if (stat(pathname, &sb) != 0)
+		return false;
+
+	return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
+}
 #elif defined(HAVE_KVM_H)
 #elif defined(HAVE_KVM_H)
 static bool
 static bool
 pid_is_exec(pid_t pid, const struct stat *esb)
 pid_is_exec(pid_t pid, const struct stat *esb)