setproctitle() and /usr/ucb/ps

Miroslaw Luc mirecki at nask.pl
Fri Dec 9 14:30:52 UTC 2005


Solaris 8,9; INN 2.4.
setproctitle() does not work correctly with /usr/ucb/ps:
pippin: /news > ps axw
  4692 ?        S  0:00 - nnrpd: olorin.nask.waw.pl group
         nask.waw.pl group
         ^^^^^^^^^^^^^^^^^
 12006 ?        S  0:00 - ovdb_monitor: deadlock    r: deadlock
                                                    ^^^^^^^^^^^
The fragments marked above are argv[1] of those processes. After looking
at http://cvs.opensolaris.org/source/raw/on/usr/src/ucbcmd/ps/ps.c:

1. ps reads all of the strings from argv[], not just argv[0] to the
nearest NULL. Setting argv[1] to NULL helps ps to read only argv[0];)

2. If the length of the initial args > argv[0] modified by setproctitle()
then ps discards the latter and displays the initial args. The problem is
that it is always true because of using SPACES in ovdb_monitor/ovdb_server
and `-s' in nnrpd. For example (after argv[1]=NULL):
alfa: /news > ps axw
  1034 ?        S  0:00 /news/bin/nnrpd -s
          |"end of padding"
 17044 ?        S  0:00 ovdb_monitor                |"end of SPACES"

We can / should:
1. Set argv[1] to NULL in setproctitle().
2. Move the environment to malloc()'ed space to make a room for argv[0].
3. Spawn nnrpd without `-s'.
4. Remove SPACES from ovdb_init,monitor,server.

The patch attached below works ok for me.

-Mirek
<------------------------------------------------------------------------->
diff -ru inn-STABLE-20051208-orig/frontends/ovdb_init.c inn-STABLE-20051208/frontends/ovdb_init.c
--- inn-STABLE-20051208-orig/frontends/ovdb_init.c	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/frontends/ovdb_init.c	Fri Dec  9 11:17:32 2005
@@ -455,7 +455,7 @@
 	case 0:
 	    setsid();
 	    execl(concatpath(innconf->pathbin, "ovdb_monitor"),
-		"ovdb_monitor", SPACES, NULL);
+		OVDB_M, NULL);
             syswarn("cannot exec ovdb_monitor");
 	    _exit(1);
 	}
@@ -472,7 +472,7 @@
 	    case 0:
 		setsid();
 		execl(concatpath(innconf->pathbin, "ovdb_server"),
-		    "ovdb_server", SPACES, NULL);
+		    OVDB_S, NULL);
                 syswarn("cannot exec ovdb_server");
 		_exit(1);
 	    }
diff -ru inn-STABLE-20051208-orig/frontends/ovdb_monitor.c inn-STABLE-20051208/frontends/ovdb_monitor.c
--- inn-STABLE-20051208-orig/frontends/ovdb_monitor.c	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/frontends/ovdb_monitor.c	Fri Dec  9 11:17:59 2005
@@ -283,16 +283,16 @@
 }


-int main(int argc, char **argv)
+int main(int argc, char *argv[], char *envp[])
 {
     char *pidfile;

-    setproctitle_init(argc, argv);
+    setproctitle_init(argc, argv, envp);

     openlog("ovdb_monitor", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
     message_program_name = "ovdb_monitor";

-    if(argc != 2 || strcmp(argv[1], SPACES))
+    if(argc != 1 || strcmp(argv[0], OVDB_M))
         die("should be started by ovdb_init");
     message_handlers_warn(1, message_log_syslog_err);
     message_handlers_die(1, message_log_syslog_err);
diff -ru inn-STABLE-20051208-orig/frontends/ovdb_server.c inn-STABLE-20051208/frontends/ovdb_server.c
--- inn-STABLE-20051208-orig/frontends/ovdb_server.c	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/frontends/ovdb_server.c	Fri Dec  9 11:18:15 2005
@@ -607,7 +607,7 @@
 }

 int
-main(int argc, char *argv[])
+main(int argc, char *argv[], char *envp[])
 {
     int i, ret;
     socklen_t salen;
@@ -620,12 +620,12 @@
     struct timeval tv;
     fd_set rdset;

-    setproctitle_init(argc, argv);
+    setproctitle_init(argc, argv, envp);

     openlog("ovdb_server", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
     message_program_name = "ovdb_server";

-    if(argc != 2 || strcmp(argv[1], SPACES))
+    if(argc != 1 || strcmp(argv[0], OVDB_S))
         die("should be started by ovdb_init");
     message_handlers_warn(1, message_log_syslog_err);
     message_handlers_die(1, message_log_syslog_err);
diff -ru inn-STABLE-20051208-orig/include/portable/setproctitle.h inn-STABLE-20051208/include/portable/setproctitle.h
--- inn-STABLE-20051208-orig/include/portable/setproctitle.h	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/include/portable/setproctitle.h	Thu Dec  8 16:14:44 2005
@@ -17,9 +17,9 @@
 #endif

 #if HAVE_SETPROCTITLE || HAVE_PSTAT
-# define setproctitle_init(argc, argv)   /* empty */
+# define setproctitle_init(argc, argv, envp)   /* empty */
 #else
-void setproctitle_init(int argc, char *argv[]);
+void setproctitle_init(int argc, char *argv[], char *envp[]);
 #endif

 #endif /* !PORTABLE_SETPROCTITLE_H */
diff -ru inn-STABLE-20051208-orig/innd/rc.c inn-STABLE-20051208/innd/rc.c
--- inn-STABLE-20051208-orig/innd/rc.c	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/innd/rc.c	Thu Dec  8 16:14:44 2005
@@ -448,7 +448,7 @@
 void
 RChandoff(int fd, HANDOFF h)
 {
-    const char *argv[6];
+    const char *argv[5];
     char buff[SMBUF];
     int i;

@@ -472,8 +472,7 @@
     case HOnnrpd:	argv[0] = RCnnrpd;	break;
     case HOnntpd:	argv[0] = RCnntpd;	break;
     }
-    argv[1] = "-s                                                ";
-    i = 2;
+    i = 1;
     if (NNRPReason) {
 	snprintf(buff, sizeof(buff), "-r%s", NNRPReason);
 	argv[i++] = buff;
diff -ru inn-STABLE-20051208-orig/lib/setproctitle.c inn-STABLE-20051208/lib/setproctitle.c
--- inn-STABLE-20051208-orig/lib/setproctitle.c	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/lib/setproctitle.c	Thu Dec  8 16:14:44 2005
@@ -47,12 +47,44 @@

 static char *title_start = NULL;
 static char *title_end = NULL;
+static char **xargv = NULL;

 void
-setproctitle_init(int argc, char *argv[])
+setproctitle_init(int argc, char *argv[], char *envp[])
 {
+    int i;
+    char **xenv;
+    extern char **environ;
+
     title_start = argv[0];
     title_end = argv[argc - 1] + strlen(argv[argc - 1]) - 1;
+
+    xargv = argv;
+    if (!envp)
+        return;
+
+    if (environ) {
+        for (i=0; environ[i]; i++)
+            ;
+        xenv = malloc((i+1) * sizeof(char*));
+        if (!xenv)
+            return;
+        for (i=0; environ[i]; i++) {
+            xenv[i] = strdup(environ[i]);
+            if (!xenv[i]) {
+                for (i--; i >= 0; i--)
+                    free(xenv[i]);
+                free(xenv);
+                return;
+            }
+        }
+        xenv[i] = NULL;
+        environ = xenv;
+    }
+
+    for (i=0; envp[i]; i++)
+        title_end += strlen(envp[i]) + 1;
+
 }

 void
@@ -68,6 +100,8 @@
         return;
     }

+    xargv[1] = NULL;
+
     /* setproctitle prepends the program name to its arguments.  Our emulation
        should therefore do the same thing.  However, some operating systems
        seem to do that automatically even when we completely overwrite argv,
diff -ru inn-STABLE-20051208-orig/nnrpd/nnrpd.c inn-STABLE-20051208/nnrpd/nnrpd.c
--- inn-STABLE-20051208-orig/nnrpd/nnrpd.c	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/nnrpd/nnrpd.c	Thu Dec  8 16:14:44 2005
@@ -783,7 +783,7 @@

 /* ARGSUSED0 */
 int
-main(int argc, char *argv[])
+main(int argc, char *argv[], char *envp[])
 {
     const char *name;
     CMDENT		*cp;
@@ -829,7 +829,7 @@

     int respawn = 0;

-    setproctitle_init(argc, argv);
+    setproctitle_init(argc, argv, envp);

     /* Parse arguments.   Must xstrdup() optarg if used because setproctitle may
        clobber it! */
diff -ru inn-STABLE-20051208-orig/storage/ovdb/ovdb-private.h inn-STABLE-20051208/storage/ovdb/ovdb-private.h
--- inn-STABLE-20051208-orig/storage/ovdb/ovdb-private.h	Thu Dec  8 11:07:09 2005
+++ inn-STABLE-20051208/storage/ovdb/ovdb-private.h	Fri Dec  9 11:16:18 2005
@@ -112,7 +112,8 @@
 #define OVDB_LOCKFN "ovdb.sem"
 #define OVDB_MONITOR_PIDFILE "ovdb_monitor.pid"
 #define OVDB_SERVER_PIDFILE "ovdb_server.pid"
-#define SPACES "                "
+#define OVDB_M "ovdb_monitor "
+#define OVDB_S "ovdb_server "

 /* read server stuff */
 #define CMD_QUIT	0x01


More information about the inn-workers mailing list