--- checkproc.c +++ checkproc.c 2011-02-08 18:49:40.991925970 +0000 @@ -210,6 +210,8 @@ int main(int argc, char **argv) if (pid_file) { /* The case of having a pid file */ if (verify_pidfile(pid_file,fullname,root,flags,false) < 0) exit(LSB_STATUS_PROOFX); + if (iargc) + clear_pids(); } if (list_empty(&remember)) { /* No process found with pid file */ if (pid_forced) --- libinit.c +++ libinit.c 2011-02-09 08:12:47.703926223 +0000 @@ -314,9 +314,42 @@ static void init_mounts(void) join(&save, &mounts); } +static MNTINFO *find_prefix(const char * path, const dev_t dev) +{ + const size_t nlen = strlen(path); + list_t *ptr; + + list_for_each(ptr, &mounts) { + MNTINFO *m = list_entry(ptr, MNTINFO); + if (m->dev != dev) + continue; + if (nlen < m->nlen) + continue; + if (m->nlen == 1) /* root fs is the last entry */ + return m; + if (strncmp(path, m->point, m->nlen)) + continue; + return m; + } + return (MNTINFO*)0; +} + static int find_mount(const char * path, MNTINFO *s) { - return (strncmp(path, s->point, s->nlen) == 0); + const size_t nlen = strlen(path); + list_t *ptr; + + list_for_each(ptr, &mounts) { + MNTINFO *m = list_entry(ptr, MNTINFO); + if (nlen < m->nlen) + continue; + if (m->nlen == 1) /* root fs is the last entry */ + return (m == s); + if (strncmp(path, m->point, m->nlen)) + continue; + return (m == s); + } + return 0; } extern inline char * handl_buf(char *restrict buf) @@ -661,17 +694,8 @@ int pidof (const char * inname, const ch } realname = expandpath(fullname); if (realname) { - list_t *ptr; init_mounts(); - list_for_each(ptr, &mounts) { - MNTINFO *m = list_entry(ptr, MNTINFO); - if (m->dev != full_st.st_dev) - continue; - if (strncmp(realname, m->point, m->nlen) != 0) - continue; - prefix = m; - break; - } + prefix = find_prefix(realname, full_st.st_dev); } } --- libinit.h +++ libinit.h 2011-02-10 12:00:34.378714740 +0000 @@ -249,6 +249,12 @@ static inline void set_newenv(const char else addnewenv("SHELL","/bin/sh"); + if ( (tmp = getenv("LISTEN_PID")) != (char*)0 ) + addnewenv("LISTEN_PID",tmp); + + if ( (tmp = getenv("LISTEN_FDS")) != (char*)0 ) + addnewenv("LISTEN_FDS",tmp); + if ( (tmp = getenv("RUNLEVEL")) != (char*)0 ) addnewenv("RUNLEVEL",tmp); --- mkill.c +++ mkill.c 2011-02-09 09:21:58.369993020 +0000 @@ -172,7 +172,7 @@ int main(int argc, char* argv[]) const size_t alen = strlen(argv[num]); char * astr = argv[num]; - if (alen == 0) + if (alen <= 1) continue; if (*(astr+(alen-1)) == '/') @@ -192,8 +192,9 @@ int main(int argc, char* argv[]) char line[BUFSIZ+1]; char path[256]; char * slash; + char * pline; ssize_t len; - FILE * maps; + FILE * file; DIR * fdir; int order; int dffd; @@ -222,6 +223,16 @@ int main(int argc, char* argv[]) slash = &path[len]; *slash = '\0'; + strcat(slash, "/statm"); + + if ((file = fopenat(dfd, path)) == (FILE*)0) + continue; + pline = fgets(line, BUFSIZ, file); + fclose(file); + if (!pline || line[0] == '0') + continue; + + *slash = '\0'; strcat(slash, "/root"); errno = 0; @@ -262,9 +273,9 @@ int main(int argc, char* argv[]) *slash = '\0'; strcat(slash, "/maps"); - if ((maps = fopenat(dfd, path)) == (FILE*)0) + if ((file = fopenat(dfd, path)) == (FILE*)0) continue; - while (fgets(line, BUFSIZ, maps)) { + while (fgets(line, BUFSIZ, file)) { if (sscanf(line, "%*s %*s %*s %*x:%*x %*d %s", name) == 1) { if (name[0] == '\0' || name[0] == '[') @@ -277,7 +288,7 @@ int main(int argc, char* argv[]) } if (found) break; } - (void)fclose(maps); + (void)fclose(file); if (found) { add_proc(curr, order); @@ -469,7 +480,6 @@ static void init_mnt(int argc, char* arg return; } - if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0) error(100, "cannot open /proc/mounts: %s\n", strerror(errno)); @@ -619,6 +629,13 @@ static int check(const char *restrict na mntent_t *p = list_entry(ptr, mntent_t); if (nlen < p->nlen) continue; + if (p->nlen == 1) { + if (nlen == 1) + return p->order; + if (shadow(&p->shadow.this, name, nlen)) + continue; + return p->order; + } if (name[p->nlen] != '\0' && name[p->nlen] != '/') continue; if (strncmp(name, p->name, p->nlen) == 0) { --- startproc.8 +++ startproc.8 2011-02-10 12:57:47.399926287 +0000 @@ -138,7 +138,7 @@ Only root is allowed to set negative nic .TP .B \-e Bequeath only a minimal set of environment variables to the new process: -.BR HOME ", " PATH ", " SHELL ", " RUNLEVEL ", and " PREVLEVEL . +.BR HOME ", " PATH ", " SHELL ", " LISTEN_PID ", " LISTEN_FDS ", " RUNLEVEL ", and " PREVLEVEL . .TP .BI \-p " pid_file" (Former option --- startproc.c +++ startproc.c 2011-02-10 12:55:27.763925713 +0000 @@ -29,6 +29,10 @@ #include #include +#ifndef SD_LISTEN_FDS_START +# define SD_LISTEN_FDS_START 3 +#endif + #define USAGE "Usage:\n"\ " %s [-f] [-L] [[-n ]+/-] [-s] [-t sec|-T sec] [-u uid] [-g gid] [-v] [-e] \\\n"\ " [-l log|-q|-d] [-p pid_file] [-i ignore_file] [-c root] [-w|-W list] /path/to/executable [args]\n" @@ -40,6 +44,8 @@ static int do_start(const char *name, ch const int nicelvl, const int env, const char* root, unsigned short flags); static void closefds(FILE *not); static void waiton(const char *list); +static int get_sd_listen_fds(void); +static void fwd_sd_listen_pid(void); static int quiet = true, supprmsg = false, sess = false, seconds = false; static int sigchld = false, force = false, dialog = false; @@ -430,6 +436,12 @@ static int do_start(const char *inname, fflush(stderr); /* flush stdout and especially stderr */ errno = 0; + /* + * When used to start service in the init script, update the init + * script pid to ours first ... + */ + fwd_sd_listen_pid(); + if (sdaemon) pid = 0; else { @@ -438,7 +450,10 @@ static int do_start(const char *inname, (void)signal(SIGCHLD, sig_chld); else (void)signal(SIGCHLD, SIG_DFL); - pid = fork(); + if ((pid = fork()) == 0) { + /* Update again to point to the child pid */ + fwd_sd_listen_pid(); + } } switch (pid) { @@ -683,6 +698,7 @@ static void closefds(FILE *not) { const int fdnot = not ? fileno(not) : -1; const int fderr = fileno(stderr); + const int sdfds = get_sd_listen_fds(); char dir[128]; struct dirent *fdd; DIR *fds; @@ -702,6 +718,9 @@ static void closefds(FILE *not) continue; if (fd == fdnot) continue; + if (sdfds > 0 && fd >= SD_LISTEN_FDS_START + && fd < SD_LISTEN_FDS_START + sdfds) + continue; if (isatty(fd)) { close(fd); continue; @@ -819,3 +838,74 @@ static void waiton(const char *list) close(fd); } + +static int get_sd_listen_fds() +{ + const char *env; + char *ptr = (char*)0; + long l; + + if ((env = getenv("LISTEN_PID")) == (const char*)0) + return 0; + + errno = 0; + l = strtol(env, &ptr, 10); + if (errno != 0) + return -errno; + if (ptr == env) + return -EINVAL; + if (*ptr != '\0') + return -EINVAL; + if (l < 0) + return -EINVAL; + + if (getpid() != (pid_t)l) + return 0; + + if ((env = getenv("LISTEN_FDS")) == (const char*)0) + return 0; + + errno = 0; + l = strtol(env, &ptr, 10); + if (errno != 0) + return -errno; + if (ptr == env) + return -EINVAL; + if (*ptr != '\0') + return -EINVAL; + if (l < 0) + return -EINVAL; + + return (int)l; +} + +static void fwd_sd_listen_pid(void) +{ + const char *env; + + /* + * fork & systemd socket activation: + * fetch listen pid and update to ours, + * when it is set to pid of our parent. + */ + if ((env = getenv("LISTEN_PID"))) { + char *ptr; + long l; + + errno = 0; + l = strtol(env, &ptr, 10); + if (errno != 0) + return; + if (ptr == env) + return; + if (*ptr != '\0') + return; + if (l < 0) + return; + if (getppid() == (pid_t)l) { + char buf[24]; + snprintf(buf, sizeof(buf), "%d", getpid()); + setenv("LISTEN_PID", buf, 1); + } + } +}