+2006-01-23 Vasilis Vasaitis <v.vasaitis@sms.ed.ac.uk>
+
+ * utils/start-stop-daemon.c (pid_is_exec) [OSLinux]: Change function
+ prototype to take a constant string instead of a struct stat. Compare
+ the filename pointed by the '/proc/<pid>/exe' symlink, instead of the
+ stat device and inode numbers. Fix all callers.
+
2006-01-23 Frank Lichtenheld <djpig@debian.org>
* scripts/dpkg-shlibdeps.pl: Rewrite of the script
* Add support for architecture wildcards, but for now they will only be
exposed in debian/control files, not in binary nor source packages.
Closes: #291939
+ * Change start-stop-daemon's --exec option behaviour on GNU/Linux to
+ compare the filename pointed by '/proc/<pid>/exe' instead of the inode
+ and device numbers. Thanks to Vasilis Vasaitis <v.vasaitis@sms.ed.ac.uk>.
+ Closes: #337942
-- Frank Lichtenheld <djpig@debian.org> Mon, 23 Jan 2006 14:22:59 +0100
static void do_pidfile(const char *name);
static void do_stop(int signal_nr, int quietmode,
int *n_killed, int *n_notkilled, int retry_nr);
-#if defined(OSLinux) || defined(OShpux)
+#if defined(OSLinux)
+static int pid_is_exec(pid_t pid, const char *name);
+#elif defined(OShpux)
static int pid_is_exec(pid_t pid, const struct stat *esb);
#endif
#if defined(OSLinux)
static int
-pid_is_exec(pid_t pid, const struct stat *esb)
+pid_is_exec(pid_t pid, const char *name)
{
- struct stat sb;
- char buf[32];
-
- sprintf(buf, "/proc/%d/exe", pid);
- if (stat(buf, &sb) != 0)
+ char lname[32];
+ char *lcontents;
+ int lcontlen, nread, res;
+
+ /* Allow one extra character for the link contents, which should
+ * be enough to determine if the file names are the same. */
+ lcontlen = strlen(name) + 1;
+ lcontents = xmalloc(lcontlen);
+ sprintf(lname, "/proc/%d/exe", pid);
+ nread = readlink(lname, lcontents, lcontlen);
+ if (nread == -1) {
+ free(lcontents);
return 0;
- return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
+ }
+ if (nread < lcontlen)
+ lcontents[nread] = '\0';
+
+ res = (strncmp(lcontents, name, lcontlen) == 0);
+ free(lcontents);
+
+ return res;
}
static void
check(pid_t pid)
{
-#if defined(OSLinux) || defined(OShpux)
+#if defined(OSLinux)
+ if (execname && !pid_is_exec(pid, execname))
+#elif defined(OShpux)
if (execname && !pid_is_exec(pid, &exec_stat))
#elif defined(OSHURD) || defined(OSFreeBSD) || defined(OSNetBSD)
/* I will try this to see if it works */