예제 #1
0
/*
 * Deal with signals.
 *
 * LOCKING: acquires and releases configlock.
 */
void *
signal_thread(void *arg)
{
	int		err, signo;

	for (;;) {
		err = sigwait(&mask, &signo);
		if (err != 0)
			log_quit("sigwait failed: %s", strerror(err));
		switch (signo) {
		case SIGHUP:
			/*
			 * Schedule to re-read the configuration file.
			 */
			pthread_mutex_lock(&configlock);
			reread = 1;
			pthread_mutex_unlock(&configlock);
			break;

		case SIGTERM:
			kill_workers();
			log_msg("terminate with signal %s", strsignal(signo));
			exit(0);

		default:
			kill_workers();
			log_quit("unexpected signal %d", signo);
		}
	}
}
예제 #2
0
파일: dialfile.c 프로젝트: crazyleen/apue
int
dial_next(Dialers *dialptr)	/* pointers in structure are filled in */
{
	if (fpdial == NULL) {
		if ( (fpdial = fopen(DIALERS, "r")) == NULL)
			log_sys("can't open %s", DIALERS);
		diallineno = 0;
	}

again:
	if (fgets(dialline, MAXLINE, fpdial) == NULL)
		return(-1);		/* EOF */
	diallineno++;

	if ( (dialptr->dialer = strtok(dialline, WHITE)) == NULL) {
		if (dialline[0] == '\n')
			goto again;		/* ignore empty line */
		log_quit("missing `dialer' in Dialers file, line %d", diallineno);
	}
	if (dialptr->dialer[0] == '#')
		goto again;			/* ignore comment line */

	if ( (dialptr->sub = strtok(NULL, WHITE)) == NULL)
		log_quit("missing `sub' in Dialers file, line %d", diallineno);

	if ( (dialptr->expsend = strtok(NULL, "\n")) == NULL)
		log_quit("missing `expsend' in Dialers file, line %d", diallineno);

	return(0);
}
예제 #3
0
파일: main.c 프로젝트: jiayuehua/apue.2e
int
main(int argc, char *argv[])
{
	int		c;

	log_open("calld", LOG_PID, LOG_USER);

	opterr = 0;		/* don't want getopt() writing to stderr */
	while ((c = getopt(argc, argv, "d")) != EOF) {
		switch (c) {
		case 'd':		/* debug */
			log_to_stderr = 1;
			break;

		case '?':
			log_quit("unrecognized option: -%c", optopt);
		}
	}

	if (log_to_stderr == 0)
		daemonize("calld");

	loop();		/* never returns */
  return 0;
}
예제 #4
0
파일: scheduler.c 프로젝트: koodaamo/yadifa
int
scheduler_init()
{
    if(g_read_fd != CLEARED_SOCKET)
    {
        return -2;
    }
    
    /* convention : 0: read 1: write */

    int sv[2];

    if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1)
    {
        int err = ERRNO_ERROR;
        log_quit("scheduler: socketpair error %r", err);
        return err;
    }

    g_read_fd = sv[0];
    g_write_fd = sv[1];

    threaded_queue_init(&scheduler_queue, SCHEDULER_MAX_TASKS);

    return g_read_fd;
}
예제 #5
0
파일: editor.c 프로젝트: anzzik/editor
void ed_quit(Context_t *ctx)
{
	buf_free(ctx->c_buffer);
	buf_free(ctx->cmd_buffer);
	ncs_close(ctx->scr);
	ncs_quit();
	log_quit();
}
예제 #6
0
파일: client.c 프로젝트: crazyleen/apue
void
client_sigchld(pid_t pid, int stat)
{
	int		i;

	for (i = 0; i < client_size; i++) {
		if (client[i].pid == pid) {
			client[i].childdone = stat;	/* child's exit() status +1 */
			return;
		}
	}
	log_quit("can't find client entry for pid %d", pid);
}
예제 #7
0
파일: client.c 프로젝트: crazyleen/apue
void
client_del(int fd)
{
	int		i;

	for (i = 0; i < client_size; i++) {
		if (client[i].fd == fd) {
			client[i].fd = -1;
			return;
		}
	}
	log_quit("can't find client entry for fd %d", fd);
}
예제 #8
0
파일: scheduler.c 프로젝트: koodaamo/yadifa
void
scheduler_process()
{
    scheduler_packet *packet;

    if(g_read_fd < 0)
    {
        return;
    }
    
    MALLOC_OR_DIE(scheduler_packet*, packet, sizeof (scheduler_packet), SCHDPAKT_TAG);

    int len = SCHEDULER_PACKET_LEN;
    u8* p = (u8*)packet;
    
    do
    {
        int n = read(g_read_fd, p, len);

        if(n < 0)
        {
            int err = errno;

            if(err == EINTR)
            {
                continue;
            }

            log_quit("scheduler: read error: %r", ERRNO_ERROR);
            
            free(packet);
            
            return;
        }

        len -= n;
        p += n;
    }
    while(len > 0);

    /* packet is the native-order pointer to the scheduler_task to add to the queue */

    threaded_queue_enqueue(&scheduler_queue, packet);
}
예제 #9
0
파일: scheduler.c 프로젝트: koodaamo/yadifa
void
scheduler_schedule_task(scheduler_task_callback* function, void* args)
{
    scheduler_packet packet;
    u8* p = (u8*) & packet;
    ssize_t len = sizeof (scheduler_packet);
    ssize_t n;
/*
#ifndef NDEBUG
    log_debug("scheduler: scheduler_schedule_task(%P,%p)'", function, args);
#endif
  */
    packet.task = function;
    packet.args = args;
    
    if(g_write_fd < 0)
    {
        return;
    }

    do
    {
        n = write(g_write_fd, p, len);

        if(n <= 0)
        {
            int err = errno;

            if(err == EINTR)
            {
                continue;
            }

            log_quit("scheduler: write error: %r", err, ERRNO_ERROR);
            
            break;
        }

        len -= n;
        p += n;
    }
    while(len > 0);
}
예제 #10
0
/*
 * Initialize the job ID file. Use a record lock to prevent
 * more than one printer daemon from running at a time.
 *
 * LOCKING: none, except for record-lock on job ID file.
 */
void init_request(void)
{
    int n;
    char name[FILENMSZ];

    sprintf(name, "%s/%s", SPOOLDIR, JOBFILE);
    jobfd = open(name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    if (write_lock(jobfd, 0, SEEK_SET, 0) < 0)
        log_quit("daemon already running");

    /*
     * Reuse the name buffer for the job counter.
     */
    if ((n = read(jobfd, name, FILENMSZ)) < 0)
        log_sys("can't read job file");
    if (n == 0)
        nextjob = 1;
    else
        nextjob = atol(name);
}
예제 #11
0
파일: xdaemon.c 프로젝트: iawes/daemon
int main(int argc, char *argv[])
{
	int err;
	pthread_t tid;
	struct sigaction sa;
	char *cmd;

	if(NULL == (cmd = strrchr(argv[0], '/')))
		cmd = argv[0];
	else
		cmd ++;
	syslog(LOG_ERR, "main thread id is %u.\n", (unsigned)pthread_self());

//	daemonize(cmd);
	daemon(0, 0);
	if(already_running())
	{
		syslog(LOG_ERR, "xdaemon already running.\n");
		exit(1);
	}
	syslog(LOG_ERR, "main thread 2 id is %u.\n", (unsigned)pthread_self());

//	/*
	sa.sa_handler = SIG_DFL;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if(sigaction(SIGHUP, &sa, NULL) < 0)
		log_quit("can't restore SIGHUP default");
	sigfillset(&mask);
	if((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
			log_exit(err, "SIG_BLOCK error");

	err = pthread_create(&tid, NULL, thread_func, 0);
	if(err != 0)
		log_exit(err, "can't create thread");

//*/
	test_func();

	exit(0);
}
예제 #12
0
/*
 * Main print server thread.  Accepts connect requests from
 * clients and spawns additional threads to service requests.
 *
 * LOCKING: none.
 */
int
main(int argc, char *argv[])
{
	pthread_t			tid;
	struct addrinfo		*ailist, *aip;
	int					sockfd, err, i, n, maxfd;
	char				*host;
	fd_set				rendezvous, rset;
	struct sigaction	sa;
	struct passwd		*pwdp;

	if (argc != 1)
		err_quit("usage: printd");
	daemonize("printd");

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &sa, NULL) < 0)
		log_sys("sigaction failed");
	sigemptyset(&mask);
	sigaddset(&mask, SIGHUP);
	sigaddset(&mask, SIGTERM);
	if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
		log_sys("pthread_sigmask failed");

	n = sysconf(_SC_HOST_NAME_MAX);
	if (n < 0)	/* best guess */
		n = HOST_NAME_MAX;
	if ((host = malloc(n)) == NULL)
		log_sys("malloc error");
	if (gethostname(host, n) < 0)
		log_sys("gethostname error");

	if ((err = getaddrlist(host, "print", &ailist)) != 0) {
		log_quit("getaddrinfo error: %s", gai_strerror(err));
		exit(1);
	}
	FD_ZERO(&rendezvous);
	maxfd = -1;
	for (aip = ailist; aip != NULL; aip = aip->ai_next) {
		if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr,
		  aip->ai_addrlen, QLEN)) >= 0) {
			FD_SET(sockfd, &rendezvous);
			if (sockfd > maxfd)
				maxfd = sockfd;
		}
	}
	if (maxfd == -1)
		log_quit("service not enabled");

	pwdp = getpwnam(LPNAME);
	if (pwdp == NULL)
		log_sys("can't find user %s", LPNAME);
	if (pwdp->pw_uid == 0)
		log_quit("user %s is privileged", LPNAME);
	if (setgid(pwdp->pw_gid) < 0 || setuid(pwdp->pw_uid) < 0)
		log_sys("can't change IDs to user %s", LPNAME);

	init_request();
	init_printer();

	err = pthread_create(&tid, NULL, printer_thread, NULL);
	if (err == 0)
		err = pthread_create(&tid, NULL, signal_thread, NULL);
	if (err != 0)
		log_exit(err, "can't create thread");
	build_qonstart();

	log_msg("daemon initialized");

	for (;;) {
		rset = rendezvous;
		if (select(maxfd+1, &rset, NULL, NULL, NULL) < 0)
			log_sys("select failed");
		for (i = 0; i <= maxfd; i++) {
			if (FD_ISSET(i, &rset)) {
				/*
				 * Accept the connection and handle the request.
				 */
				if ((sockfd = accept(i, NULL, NULL)) < 0)
					log_ret("accept failed");
				pthread_create(&tid, NULL, client_thread,
				  (void *)((long)sockfd));
			}
		}
	}
	exit(1);
}
예제 #13
0
파일: xdaemon.c 프로젝트: iawes/daemon
void daemonize(const char *cmd)
{
	int				i, fd0, fd1, fd2;
	pid_t			pid;
	struct rlimit	rl;
	struct sigaction	sa;

	/*
	 * Clear file creation mask.
	 */
	umask(0);

	/*
	 * Get maximum number of file descriptors.
	 */
	if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
		log_quit("%s:cannot get file limit", cmd);

	/*
	 * Become a session leader tro lose controlling TTY.
	 */
	if ((pid = fork()) < 0)
		log_quit("%s:cannot fork", cmd);
	else if(pid != 0) /* parent */
		exit(0);
	
	setsid();

	/*
	 * Ensure future opens won't allocate controlling TTYs.
	 */
	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if(sigaction(SIGHUP, &sa, NULL) < 0)
		log_quit("%s:cannot igore SIGHUP", cmd);
	
	if((pid = fork()) < 0)
		log_quit("%s:cannot fork", cmd);
	else if(pid != 0) /* parent */
		exit(0);

	/*
	 * Change the current working directory to the root so
	 * we won't jprevernt file systems from being unmounted
	 */
	if(chdir("/") < 0)
		log_quit("%s:can't chare dirctory to /", cmd);

	/*
	 * Close all open file descriptions
	 */
	if(rl.rlim_max == RLIM_INFINITY)
		rl.rlim_max = 1024;
	for(i = 0; i < rl.rlim_max; i++)
		close(i);

	/*
	 * Attach file descriptions 0, 1, and 2 to /dev/null.
	 */
	fd0 = open("/dev/null", O_RDWR);
	fd1 = dup(0);
	fd2 = dup(0);

	/*
	 *Initialize the log file.
	 */
	openlog(cmd, LOG_CONS, LOG_DAEMON);
	if(fd0 != 0 || fd1 != 1 || fd2 != 2)
	{
		syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2);
		exit(1);
	}
}