Check-in [82653deb02]
Overview
Comment:Added support for becoming a daemon
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:82653deb02f5d6c7d6c70a4cd00936b195ac68b7
User & Date: rkeene on 2014-02-07 21:44:25
Other Links: manifest | tags
Context
2014-02-07
21:51
Updated wiki HTML page check-in: e7fa8416e1 user: rkeene tags: trunk
21:44
Added support for becoming a daemon check-in: 82653deb02 user: rkeene tags: trunk
21:12
Normalized macro names check-in: 25c96dfee9 user: rkeene tags: trunk
Changes

Modified filed.1 from [fae93fba37] to [88912a76e0].

     2      2   .TH FILED 1 "06 Feb 14" "filed 1.0"
     3      3   .SH NAME
     4      4   filed \- serve files over HTTP
     5      5   .SH SYNOPSIS
     6      6   .ll +10
     7      7   .B filed
     8      8   .RB [{ \-h | \-\-help }]
            9  +.RB [{ \-d | \-\-daemon }]
     9     10   .RB [{ \-b | \-\-bind }
    10     11   .IR address ]
    11     12   .RB [{ \-p | \-\-port }
    12     13   .IR port ]
    13     14   .RB [{ \-t | \-\-threads }
    14     15   .IR count ]
    15     16   .RB [{ \-c | \-\-cache }
................................................................................
    25     26   serves files over HTTP as minimally as possible.  Only static files (i.e., files that never change or are replaced) are supported.
    26     27   
    27     28   .SH OPTIONS
    28     29   .TP
    29     30   .B -h (or --help)
    30     31   Prints detailed usage information
    31     32   
           33  +.TP
           34  +.B -d (or --daemon)
           35  +Instructs filed to become a daemon after initializing
           36  +the listening TCP socket and log files.
           37  +
    32     38   .TP
    33     39   .B -b (or --bind)
    34     40   Specifies the address to listen for incoming HTTP
    35     41   requests on.
    36     42   
    37     43   .TP
    38     44   .B -p (or --port)

Modified filed.c from [f6d6d04c13] to [5138c920c1].

     1      1   #include <sys/sendfile.h>
     2      2   #include <sys/socket.h>
     3      3   #include <sys/types.h>
     4      4   #include <arpa/inet.h>
     5      5   #include <sys/mman.h>
     6      6   #include <sys/stat.h>
            7  +#include <sys/wait.h>
     7      8   #include <pthread.h>
     8      9   #include <strings.h>
     9     10   #include <signal.h>
    10     11   #include <stdlib.h>
    11     12   #include <unistd.h>
    12     13   #include <string.h>
    13     14   #include <getopt.h>
................................................................................
   684    685   	if (extra) {
   685    686   		fprintf(output, "%s\n", extra);
   686    687   	}
   687    688   
   688    689   	fprintf(output, "Usage: filed [<options>]\n");
   689    690   	fprintf(output, "  Options:\n");
   690    691   	fprintf(output, "      -h, --help\n");
          692  +	fprintf(output, "      -d, --daemon\n");
   691    693   	fprintf(output, "      -b <address>, --bind <address>\n");
   692    694   	fprintf(output, "      -p <port>, --port <port>\n");
   693    695   	fprintf(output, "      -t <count>, --threads <count>\n");
   694    696   	fprintf(output, "      -c <entries>, --cache <entries>\n");
   695    697   	fprintf(output, "      -u <user>, --user <user>\n");
   696    698   	fprintf(output, "      -r <directory>, --root <directory>\n");
   697    699   
   698    700   	if (long_help) {
   699    701   		fprintf(output, "\n");
   700    702   		fprintf(output, "  Usage:\n");
   701    703   		fprintf(output, "      -h (or --help) prints this usage information\n");
          704  +		fprintf(output, "\n");
          705  +		fprintf(output, "      -d (or --daemon) instructs filed to become a daemon after initializing\n");
          706  +		fprintf(output, "                       the listening TCP socket and log files.\n");
   702    707   		fprintf(output, "\n");
   703    708   		fprintf(output, "      -b (or --bind) specifies the address to listen for incoming HTTP\n");
   704    709   		fprintf(output, "                     requests on.  The default value is \"%s\".\n", BIND_ADDR);
   705    710   		fprintf(output, "\n");
   706    711   		fprintf(output, "      -p (or --port) specifies the TCP port number to listen for incoming HTTP\n");
   707    712   		fprintf(output, "                     requests on.  The default is %u.\n", (unsigned int) PORT);
   708    713   		fprintf(output, "\n");
................................................................................
   767    772   		return(1);
   768    773   	}
   769    774   
   770    775   	*user_id = user_id_check;
   771    776   
   772    777   	return(0);
   773    778   }
          779  +
          780  +/* Daemonize */
          781  +static int filed_daemonize(void) {
          782  +	pid_t setsid_ret, fork_ret;
          783  +	int chdir_ret, dup2_ret;
          784  +	int fd_in, fd_out;
          785  +
          786  +	chdir_ret = chdir("/");
          787  +	if (chdir_ret != 0) {
          788  +		return(1);
          789  +	}
          790  +
          791  +	fork_ret = fork();
          792  +	if (fork_ret < 0) {
          793  +		return(1);
          794  +	}
          795  +
          796  +	if (fork_ret > 0) {
          797  +		/* Parent */
          798  +		waitpid(fork_ret, NULL, 0);
          799  +
          800  +		exit(EXIT_SUCCESS);
          801  +	}
          802  +
          803  +	/* Child */
          804  +	if (fork() != 0) {
          805  +		/* Child */
          806  +		exit(EXIT_SUCCESS);
          807  +	}
          808  +
          809  +	/* Grand child */
          810  +	setsid_ret = setsid();
          811  +	if (setsid_ret == ((pid_t) -1)) {
          812  +		return(1);
          813  +	}
          814  +
          815  +	fd_in = open("/dev/null", O_RDONLY);
          816  +	fd_out = open("/dev/null", O_WRONLY);
          817  +	if (fd_in < 0 || fd_out < 0) {
          818  +		return(1);
          819  +	}
          820  +
          821  +	dup2_ret = dup2(fd_in, STDIN_FILENO);
          822  +	if (dup2_ret != STDIN_FILENO) {
          823  +		return(1);
          824  +	}
          825  +
          826  +	dup2_ret = dup2(fd_out, STDOUT_FILENO);
          827  +	if (dup2_ret != STDOUT_FILENO) {
          828  +		return(1);
          829  +	}
          830  +
          831  +	dup2_ret = dup2(fd_out, STDERR_FILENO);
          832  +	if (dup2_ret != STDERR_FILENO) {
          833  +		return(1);
          834  +	}
          835  +
          836  +	close(fd_in);
          837  +	close(fd_out);
          838  +
          839  +	return(0);
          840  +}
   774    841   
   775    842   /* Run process */
   776    843   int main(int argc, char **argv) {
   777         -	struct option options[8];
          844  +	struct option options[9];
   778    845   	const char *bind_addr = BIND_ADDR, *newroot = NULL;
   779    846   	uid_t user = 0;
   780    847   	int port = PORT, thread_count = THREAD_COUNT;
   781    848   	int cache_size = CACHE_SIZE;
   782    849   	int init_ret, chroot_ret, setuid_ret, lookup_ret, chdir_ret;
   783         -	int setuid_enabled = 0;
          850  +	int setuid_enabled = 0, daemon_enabled = 0;
   784    851   	int ch;
   785    852   	int fd;
   786    853   
   787    854   	/* Process arguments */
   788    855   	filed_getopt_long_setopt(&options[0], "port", required_argument, 'p');
   789    856   	filed_getopt_long_setopt(&options[1], "threads", required_argument, 't');
   790    857   	filed_getopt_long_setopt(&options[2], "cache", required_argument, 'c');
   791    858   	filed_getopt_long_setopt(&options[3], "bind", required_argument, 'b');
   792    859   	filed_getopt_long_setopt(&options[4], "user", required_argument, 'u');
   793    860   	filed_getopt_long_setopt(&options[5], "root", required_argument, 'r');
   794    861   	filed_getopt_long_setopt(&options[6], "help", no_argument, 'h');
   795         -	filed_getopt_long_setopt(&options[7], NULL, 0, 0);
   796         -	while ((ch = getopt_long(argc, argv, "p:t:c:b:u:r:h", options, NULL)) != -1) {
          862  +	filed_getopt_long_setopt(&options[7], "daemon", no_argument, 'd');
          863  +	filed_getopt_long_setopt(&options[8], NULL, 0, 0);
          864  +	while ((ch = getopt_long(argc, argv, "p:t:c:b:u:r:hd", options, NULL)) != -1) {
   797    865   		switch(ch) {
   798    866   			case 'p':
   799    867   				port = atoi(optarg);
   800    868   				break;
   801    869   			case 't':
   802    870   				thread_count = atoi(optarg);
   803    871   				break;
................................................................................
   815    883   
   816    884   					return(1);
   817    885   				}
   818    886   				break;
   819    887   			case 'r':
   820    888   				newroot = strdup(optarg);
   821    889   				break;
          890  +			case 'd':
          891  +				daemon_enabled = 1;
          892  +				break;
   822    893   			case '?':
   823    894   			case ':':
   824    895   				filed_print_help(stderr, 0, NULL);
   825    896   
   826    897   				return(1);
   827    898   			case 'h':
   828    899   				filed_print_help(stdout, 1, NULL);
................................................................................
   863    934   			perror("setuid");
   864    935   
   865    936   			return(1);
   866    937   		}
   867    938   	}
   868    939   
   869    940   	/* Become a daemon */
   870         -	/* XXX:TODO: Become a daemon */
          941  +	if (daemon_enabled) {
          942  +		filed_daemonize();
          943  +	}
   871    944   
   872    945   	/* Initialize */
   873    946   	init_ret = filed_init(cache_size);
   874    947   	if (init_ret != 0) {
   875    948   		perror("filed_init");
   876    949   
   877    950   		return(3);