Exemple #1
0
void    acl_master_status_init(ACL_MASTER_SERV *serv)
{
	const char *myname = "acl_master_status_init";

	/*
	 * Sanity checks.
	 */
	if (serv->status_fd[0] >= 0 || serv->status_fd[1] >= 0)
		acl_msg_panic("%s: status events already enabled", myname);
	if (acl_msg_verbose)
		acl_msg_info("%s: %s", myname, serv->name);

	/*
	 * Make the read end of this service's status pipe non-blocking so that
	 * we can detect partial writes on the child side. We use a duplex pipe
	 * so that the child side becomes readable when the master goes away.
	 */
	if (acl_duplex_pipe(serv->status_fd) < 0)
		acl_msg_fatal("pipe: %s", strerror(errno));
	acl_non_blocking(serv->status_fd[0], ACL_BLOCKING);
	acl_close_on_exec(serv->status_fd[0], ACL_CLOSE_ON_EXEC);
	acl_close_on_exec(serv->status_fd[1], ACL_CLOSE_ON_EXEC);
	serv->status_read_stream = acl_vstream_fdopen(serv->status_fd[0],
		O_RDWR, acl_var_master_buf_size,
		acl_var_master_rw_timeout, ACL_VSTREAM_TYPE_SOCK);

	if (acl_msg_verbose)
		acl_msg_info("%s(%d)->%s: call acl_event_enable_read, "
			"status_fd = %d", __FILE__, __LINE__,
			myname, serv->status_fd[0]);

	acl_event_enable_read(acl_var_master_global_event,
		serv->status_read_stream, 0, master_status_event,
		(void *) serv);
}
Exemple #2
0
void    acl_master_flow_init(void)
{
    char   *myname = "acl_master_flow_init";

    if (pipe(acl_var_master_flow_pipe) < 0)
	acl_msg_fatal("%s(%d)->%s: pipe: %s",
			__FILE__, __LINE__, myname, strerror(errno));

    acl_non_blocking(acl_var_master_flow_pipe[0], ACL_NON_BLOCKING);
    acl_non_blocking(acl_var_master_flow_pipe[1], ACL_NON_BLOCKING);

    acl_close_on_exec(acl_var_master_flow_pipe[0], ACL_CLOSE_ON_EXEC);
    acl_close_on_exec(acl_var_master_flow_pipe[1], ACL_CLOSE_ON_EXEC);
}
Exemple #3
0
int acl_unix_trigger(ACL_EVENT *event, const char *service,
	const char *buf, int len, int timeout)
{
	const char *myname = "acl_unix_trigger";
	struct ACL_UNIX_TRIGGER *up;
	ACL_SOCKET fd;

	if (acl_msg_verbose > 0)
		acl_msg_info("%s: service %s", myname, service);

	/*
	 * Connect...
	 */
	if ((fd = acl_unix_connect(service, ACL_BLOCKING, timeout)) < 0) {
		if (acl_msg_verbose)
			acl_msg_warn("%s: connect to %s: %s",
				myname, service, strerror(errno));
		return -1;
	}
	acl_close_on_exec(fd, ACL_CLOSE_ON_EXEC);

	/*
	 * Stash away context.
	 */
	up = (struct ACL_UNIX_TRIGGER *) acl_mymalloc(sizeof(*up));
	up->service = acl_mystrdup(service);
	up->stream = acl_vstream_fdopen(fd, O_RDWR, 4096,
			timeout, ACL_VSTREAM_TYPE_LISTEN_UNIX);

	/*
	 * Write the request...
	 */
	if (acl_vstream_writen(up->stream, buf, len) < 0
		|| acl_vstream_writen(up->stream, "", 1) < 0)
	{
		if (acl_msg_verbose)
			acl_msg_warn("%s: write to %s: %s",
				myname, service, strerror(errno));
	}

	/*
	 * Wakeup when the peer disconnects, or when we lose patience.
	 */
#ifdef	__USE_TIMER
	if (timeout > 0)
		acl_event_request_timer(event, acl_unix_trigger_timer,
			(void *) up, (timeout + 100) * 1000000);
	acl_event_enable_read(event, up->stream, 0,
		acl_unix_trigger_event, (void *) up);
#else
	if (timeout > 0)
		acl_event_enable_read(event, up->stream, timeout + 100,
			acl_unix_trigger_event, (void *) up);
	else
		acl_event_enable_read(event, up->stream, 0,
			acl_unix_trigger_event, (void *) up);
#endif

	return 0;
}
Exemple #4
0
int acl_inet_trigger(ACL_EVENT *eventp, const char *service,
	const char *buf, int len, int timeout)
{
	const char *myname = "acl_inet_trigger";
	struct ACL_INET_TRIGGER *ip;
	int     fd;

	if (acl_msg_verbose > 1)
		acl_msg_info("%s: service %s", myname, service);

	/*
	 * Connect...
	 */
	if ((fd = acl_inet_connect(service, ACL_BLOCKING, timeout)) < 0) {
		if (acl_msg_verbose)
			acl_msg_warn("%s: connect to %s: %s",
				myname, service, strerror(errno));
		return (-1);
	}
	acl_close_on_exec(fd, ACL_CLOSE_ON_EXEC);

	/*
	 * Stash away context.
	 */
	ip = (struct ACL_INET_TRIGGER *) acl_mymalloc(sizeof(*ip));
	ip->fd = fd;
	ip->service = acl_mystrdup(service);
	ip->stream = acl_vstream_fdopen(fd, O_RDWR, 4096,
		timeout, ACL_VSTREAM_TYPE_LISTEN_INET);
	ip->eventp = eventp;

	/*
	 * Write the request...
	 */
	if (acl_write_buf(fd, buf, len, timeout) < 0
		|| acl_write_buf(fd, "", 1, timeout) < 0)
	{
		if (acl_msg_verbose)
			acl_msg_warn("%s: write to %s: %s",
				myname, service, strerror(errno));
	}

	/*
	 * Wakeup when the peer disconnects, or when we lose patience.
	 */

	if (timeout > 0)
		acl_event_enable_read(ip->eventp, ip->stream, timeout + 100,
			acl_inet_trigger_event, (void *) ip);
	else
		acl_event_enable_read(ip->eventp, ip->stream, 0,
			acl_inet_trigger_event, (void *) ip);

	return (0);
}
Exemple #5
0
static void notify_thread(void *arg)
{
	const char *myname = "notify_thread";
	WARN_INFO *info = (WARN_INFO*) arg;
	ACL_VSTREAM *client;
	ACL_VSTRING *buf;
	int   ret;

	buf = acl_vstring_alloc(256);
	acl_vstring_sprintf(buf, "PROC=%s|PID=%d|RCPT=%s|info=%s\r\n",
		info->path, info->pid, info->notify_recipients, info->desc);

	client = acl_vstream_connect(info->notify_addr,
		ACL_BLOCKING, 60, 60, 1024);
	if (client == NULL) {
		acl_msg_error("%s(%d): connect %s error, info(%s)", myname,
			__LINE__, info->notify_addr, acl_vstring_str(buf));
		acl_vstring_free(buf);
		warn_info_free(info);
		return;
	}

	/* 禁止将该句柄传递给子进程 */
	acl_close_on_exec(ACL_VSTREAM_SOCK(client), ACL_CLOSE_ON_EXEC);

	ret = acl_vstream_writen(client, acl_vstring_str(buf),
		ACL_VSTRING_LEN(buf));
	if (ret == ACL_VSTREAM_EOF)
		acl_msg_error("%s(%d): write to notify server error, info(%s)",
			myname, __LINE__, acl_vstring_str(buf));
	else
		acl_msg_info("%s(%d): notify ok!", myname, __LINE__);

	acl_vstream_close(client);
	acl_vstring_free(buf);
	warn_info_free(info);
}
Exemple #6
0
void    acl_master_sigsetup(void)
{
	char   *myname = "acl_master_sigsetup";
	struct sigaction action;
	static int sigs[] = {
		SIGINT, SIGQUIT, SIGILL, SIGBUS, /* SIGSEGV, only for test */ SIGTERM,
	};
	unsigned i;

	sigemptyset(&action.sa_mask);
	action.sa_flags = 0;

	/*
	 * Prepare to kill our children
	 * when we receive any of the above signals.
	 */
	action.sa_handler = master_sigdeath;
	for (i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
		if (sigaction(sigs[i], &action, (struct sigaction *) 0) < 0)
			acl_msg_fatal("%s: sigaction(%d): %s",
				myname, sigs[i], strerror(errno));


#ifdef USE_SIG_PIPE
	if (pipe(acl_master_sig_pipe))
		acl_msg_fatal("pipe: %s", strerror(errno));
	acl_non_blocking(ACL_SIG_PIPE_WRITE_FD, ACL_NON_BLOCKING);
	acl_non_blocking(ACL_SIG_PIPE_READ_FD, ACL_NON_BLOCKING);
	acl_close_on_exec(ACL_SIG_PIPE_WRITE_FD, ACL_CLOSE_ON_EXEC);
	acl_close_on_exec(ACL_SIG_PIPE_READ_FD, ACL_CLOSE_ON_EXEC);

	ACL_SIG_PIPE_READ_STREAM = acl_vstream_fdopen(ACL_SIG_PIPE_READ_FD,
			O_RDONLY, acl_var_master_buf_size,
			acl_var_master_rw_timeout, ACL_VSTREAM_TYPE_SOCK);
	if (ACL_SIG_PIPE_READ_STREAM == NULL)
		acl_msg_fatal("%s(%d)->%s: acl_vstream_fdopen error=%s",
			__FILE__, __LINE__, myname, strerror(errno));

	if (acl_msg_verbose)
		acl_msg_info("%s(%d)->%s: call acl_event_enable_read, "
			"SIG_PIPE_READ_FD = %d", __FILE__, __LINE__, myname,
			ACL_SIG_PIPE_READ_FD);
	acl_event_enable_read(acl_var_master_global_event,
		ACL_SIG_PIPE_READ_STREAM, 0, master_sig_event, (void *) 0);
#endif

	/*
	 * Intercept SIGHUP (re-read config file) and SIGCHLD (child exit).
	 */
#ifdef SA_RESTART
	action.sa_flags |= SA_RESTART;
#endif
	action.sa_handler = master_sighup;
	if (sigaction(SIGHUP, &action, (struct sigaction *) 0) < 0)
		acl_msg_fatal("%s: sigaction(%d): %s",
			myname, SIGHUP, strerror(errno));

	action.sa_flags |= SA_NOCLDSTOP;
	action.sa_handler = master_sigchld;
	if (sigaction(SIGCHLD, &action, (struct sigaction *) 0) < 0)
		acl_msg_fatal("%s: sigaction(%d): %s",
			myname, SIGCHLD, strerror(errno));
}