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);