View | Details | Raw Unified | Return to bug 656104
Collapse All | Expand All

(-) (-1 / +80 lines)
Line  Link Here
-- startproc.c
Lines 66-71 static void sig_chld(int nsig) Link Here
66
    seconds = 0;
66
    seconds = 0;
67
}
67
}
68
68
69
#ifndef SD_LISTEN_FDS_START
70
#define SD_LISTEN_FDS_START 3
71
#endif
72
73
static int get_sd_listen_fds()
74
{
75
	const char *e;
76
	char *p = NULL;
77
	unsigned long l;
78
79
	if (!(e = getenv("LISTEN_PID")))
80
	    return 0;
81
	
82
	errno = 0;
83
	l = strtoul(e, &p, 10);
84
	if (errno != 0)
85
	    return -errno;
86
	
87
	if (!p || *p || l <= 0)
88
	    return -EINVAL;
89
	
90
	if (getpid() != (pid_t) l)
91
	    return 0;
92
	
93
	if (!(e = getenv("LISTEN_FDS")))
94
	    return 0;
95
	
96
	errno = 0;
97
	l = strtoul(e, &p, 10);
98
	if (errno != 0)
99
	    return -errno;
100
101
	if (!p || *p)
102
	    return -EINVAL;
103
	else
104
	    return (int) l;
105
}
106
107
static void fwd_sd_listen_pid(void)
108
{
109
    const char *e;
110
    char buf[24] = { '\0' };
111
    char *p = NULL;
112
    unsigned long l;
113
114
    /*
115
     * fork & systemd socket activation:
116
     * fetch listen pid and update to ours,
117
     *  when it is set to pid of our parent.
118
     */
119
    if ( (e = getenv("LISTEN_PID"))) {
120
	errno = 0;
121
	l = strtoul(e, &p, 10);
122
	if (errno ==  0 && l > 0 && (!p || !*p)) {
123
	    if (getppid() == (pid_t)l) {
124
		snprintf(buf, sizeof(buf), "%d", getpid());
125
		setenv("LISTEN_PID", buf, 1);
126
	    }
127
	}
128
    }
129
}
130
69
int main(int argc, char **argv)
131
int main(int argc, char **argv)
70
{
132
{
71
    struct stat st;
133
    struct stat st;
Lines 430-435 static int do_start(const char *inname, Link Here
430
    fflush(stderr);		/* flush stdout and especially stderr */
492
    fflush(stderr);		/* flush stdout and especially stderr */
431
    errno = 0;
493
    errno = 0;
432
494
495
    /*
496
     * when used to start service in the init script,
497
     * update the init script pid to ours first ...
498
     */
499
    fwd_sd_listen_pid();
500
433
    if (sdaemon)
501
    if (sdaemon)
434
	pid = 0;
502
	pid = 0;
435
    else {
503
    else {
Lines 438-444 static int do_start(const char *inname, Link Here
438
	    (void)signal(SIGCHLD, sig_chld);
506
	    (void)signal(SIGCHLD, sig_chld);
439
	else
507
	else
440
	    (void)signal(SIGCHLD, SIG_DFL);
508
	    (void)signal(SIGCHLD, SIG_DFL);
509
441
    	pid = fork();
510
    	pid = fork();
511
	if(pid == 0) {
512
	    /*
513
	     * update again to point to the child pid
514
	     */
515
	    fwd_sd_listen_pid();
516
	}
442
    }
517
    }
443
518
444
    switch (pid) {
519
    switch (pid) {
Lines 498-503 static int do_start(const char *inname, Link Here
498
	}
573
	}
499
	/*
574
	/*
500
	 * Close all above stdin, stdout, stderr ... but not fileno(tmp)
575
	 * Close all above stdin, stdout, stderr ... but not fileno(tmp)
576
	 * or the systemd activated sockets
501
	 */
577
	 */
502
	closefds(tmp);
578
	closefds(tmp);
503
579
Lines 687-692 static void closefds(FILE *not) Link Here
687
    struct dirent *fdd;
763
    struct dirent *fdd;
688
    DIR *fds;
764
    DIR *fds;
689
    int ret;
765
    int ret;
766
    int sd_fds = get_sd_listen_fds();
690
767
691
    if (((ret = snprintf(dir, sizeof(dir), "/proc/%ld/fd", (long)getpid())) < 0) ||
768
    if (((ret = snprintf(dir, sizeof(dir), "/proc/%ld/fd", (long)getpid())) < 0) ||
692
	(ret == sizeof(dir)))
769
	(ret == sizeof(dir)))
Lines 702-707 static void closefds(FILE *not) Link Here
702
	    continue;
779
	    continue;
703
	if (fd == fdnot)
780
	if (fd == fdnot)
704
	    continue;
781
	    continue;
782
	if (sd_fds > 0 && fd >= SD_LISTEN_FDS_START &&
783
	                  fd <  SD_LISTEN_FDS_START + sd_fds)
784
	    continue;
705
	if (isatty(fd)) {
785
	if (isatty(fd)) {
706
	    close(fd);
786
	    close(fd);
707
	    continue;
787
	    continue;

Return to bug 656104