Exemplo n.º 1
0
int 
daemonize(int port, int bg)
{
	int sock = 0;
	struct sockaddr_in serv;
	int on = 1;
	int fdtty;	
	pid_t pid;
		
	if (bg) {
		pid = fork();
		if (pid < 0) {
			perror("Daemon fork");
			return (-1);
		}
		if (pid > 0)
			exit(0);
	}

	daemon_port = port;
	
	setsid();
	
#ifdef cygwin
	SetConsoleCtrlHandler(handler_routine, TRUE);
#endif

	signal(SIGTERM, &sig_term);
	signal(SIGQUIT, &sig_quit);
	signal(SIGINT, &sig_int);
	signal(SIGHUP, SIG_IGN);
	signal(SIGUSR1, &sig_usr1);
   	signal(SIGUSR2, &sig_usr2);
   	signal(SIGCHLD, SIG_IGN);
	signal(SIGPIPE, SIG_IGN);
	
   	/* open an tty as standard I/O for vpcs */
   	fdtty_pid = forkpty(&fdtty, NULL, NULL, NULL);
   	
   	if (fdtty_pid < 0) {
   		perror("Daemon fork tty\n");
   		return (-1);
	}
	
   	/* child process, the 'real' vpcs */
   	if (fdtty_pid == 0) 
   		return 0;
   	
   	/* daemon socket */
   	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock < 0) {
		perror("Daemon socket");
		goto err;
	}
	(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
	    (char *)&on, sizeof(on));

	bzero((char *) &serv, sizeof(serv));
	serv.sin_family = AF_INET;
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	serv.sin_port = htons(port);
	
	if (bind(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) {
		perror("Daemon bind port");
		goto err;
	}
	if (listen(sock, 5) < 0) {
		perror("Daemon listen");
		goto err;
	}

	daemon_proc(sock, fdtty);
err:
	if (sock >= 0)
		close(sock);

	close(fdtty);
	kill(fdtty_pid, 9);
	exit(-1);
}
Exemplo n.º 2
0
/* Get the host list from zeroconf */
int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n_slots, struct dcc_hostdef **ret_prev) {
    char host_file[PATH_MAX], lock_file[PATH_MAX], *s = NULL;
    int lock_fd = -1, host_fd = -1;
    int fork_daemon = 0;
    int r = -1;
    char *dir;
    struct stat st;

    if (get_zeroconf_dir(&dir) != 0) {
        rs_log_crit("failed to get zeroconf dir.\n");
        goto finish;
    }

    snprintf(lock_file, sizeof(lock_file), "%s/lock", dir);
    snprintf(host_file, sizeof(host_file), "%s/hosts", dir);

    /* Open lock file */
    if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) {
        rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno));
        goto finish;
    }

    /* Try to lock the lock file */
    if (generic_lock(lock_fd, 1, 1, 0) >= 0) {
        /* The lock succeeded => there's no daemon running yet! */
        fork_daemon = 1;
        generic_lock(lock_fd, 1, 0, 0);
    }

    close(lock_fd);

    /* Shall we fork a new daemon? */
    if (fork_daemon) {
        pid_t pid;

        rs_log_info("Spawning zeroconf daemon.\n");

        if ((pid = fork()) == -1) {
            rs_log_crit("fork() failed: %s\n", strerror(errno));
            goto finish;
        } else if (pid == 0) {
            int fd;
            /* Child */

            /* Close file descriptors and replace them by /dev/null */
            close(0);
            close(1);
            close(2);
            fd = open("/dev/null", O_RDWR);
            assert(fd == 0);
            fd = dup(0);
            assert(fd == 1);
            fd = dup(0);
            assert(fd == 2);

#ifdef HAVE_SETSID
            setsid();
#endif

            chdir("/");
            rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0);
            _exit(daemon_proc(host_file, lock_file, n_slots));
        }

        /* Parent */

        /* Wait some time for initial host gathering */
        usleep(1000000);         /* 1000 ms */
    }

    /* Open host list read-only */
    if ((host_fd = open(host_file, O_RDONLY)) < 0) {
        rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno));
        goto finish;
    }

    /* A read lock */
    if (generic_lock(host_fd, 0, 1, 1) < 0) {
        rs_log_crit("lock failed: %s\n", strerror(errno));
        goto finish;
    }

    /* Get file size */
    if (fstat(host_fd, &st) < 0) {
        rs_log_crit("stat() failed: %s\n", strerror(errno));
        goto finish;
    }

    if (st.st_size >= MAX_FILE_SIZE) {
        rs_log_crit("file too large.\n");
        goto finish;
    }

    /* read file data */
    s = malloc((size_t) st.st_size+1);
    assert(s);

    if (dcc_readx(host_fd, s, (size_t) st.st_size) != 0) {
        rs_log_crit("failed to read from file.\n");
        goto finish;
    }
    s[st.st_size] = 0;

    /* Parse host data */
    if (dcc_parse_hosts(s, host_file, ret_list, ret_nhosts, ret_prev) != 0) {
        rs_log_crit("failed to parse host file.\n");
        goto finish;
    }

    r = 0;

finish:
    if (host_fd >= 0) {
        generic_lock(host_fd, 0, 0, 1);
        close(host_fd);
    }

    free(s);

    return r;
}