Ejemplo n.º 1
0
/**********************************************************************
* %FUNCTION: SetupPipes (static)
* %ARGUMENTS:
*  es -- event selector
* %RETURNS:
*  0 on success; -1 on failure
* %DESCRIPTION:
*  Sets up pipes with an event handler to handle IPC from a signal handler
***********************************************************************/
static int
SetupPipes(EventSelector *es)
{
    /* If already done, do nothing */
    if (PipeHandler) return 0;

    /* Initialize the child-process hash table */
    hash_init(&child_process_table,
	      offsetof(struct ChildEntry, hash),
	      child_hash,
	      child_compare);

    /* Open pipe to self */
    if (pipe(Pipe) < 0) {
	return -1;
    }

    PipeHandler = Event_AddHandler(es, Pipe[0],
				   EVENT_FLAG_READABLE, DoPipe, NULL);
    if (!PipeHandler) {
	int old_errno = errno;
	close(Pipe[0]);
	close(Pipe[1]);
	errno = old_errno;
	return -1;
    }
    return 0;
}
Ejemplo n.º 2
0
static int
SetupPipes(EventSelector *es)
{
    
    if (PipeHandler) return 0;

    
    hash_init(&child_process_table,
	      offsetof(struct ChildEntry, hash),
	      child_hash,
	      child_compare);

    
    if (pipe(Pipe) < 0) {
	return -1;
    }

    PipeHandler = Event_AddHandler(es, Pipe[0],
				   EVENT_FLAG_READABLE, DoPipe, NULL);
    if (!PipeHandler) {
	int old_errno = errno;
	close(Pipe[0]);
	close(Pipe[1]);
	errno = old_errno;
	return -1;
    }
    return 0;
}
/**********************************************************************
* %FUNCTION: Event_AddHandlerWithTimeout
* %ARGUMENTS:
*  es -- event selector
*  fd -- file descriptor to watch
*  flags -- combination of EVENT_FLAG_READABLE and EVENT_FLAG_WRITEABLE
*  t -- Timeout after which to call handler, even if not readable/writable.
*       If t.tv_sec < 0, calls normal Event_AddHandler with no timeout.
*  fn -- callback function to call when event is triggered
*  data -- extra data to pass to callback function
* %RETURNS:
*  A newly-allocated EventHandler, or NULL.
***********************************************************************/
EventHandler *
Event_AddHandlerWithTimeout(EventSelector *es,
			    int fd,
			    unsigned int flags,
			    struct timeval t,
			    EventCallbackFunc fn,
			    void *data)
{
    EventHandler *eh;
    struct timeval now;

    /* If timeout is negative, just do normal non-timing-out event */
    if (t.tv_sec < 0 || t.tv_usec < 0) {
	return Event_AddHandler(es, fd, flags, fn, data);
    }

    /* Specifically disable timer and deleted flags */
    flags &= (~(EVENT_FLAG_TIMER | EVENT_FLAG_DELETED));
    flags |= EVENT_FLAG_TIMEOUT;

    /* Bad file descriptor? */
    if (fd < 0) {
	errno = EBADF;
	return NULL;
    }

    /* Bad timeout? */
    if (t.tv_usec >= 1000000) {
	errno = EINVAL;
	return NULL;
    }

    eh = malloc(sizeof(EventHandler));
    if (!eh) return NULL;

    /* Convert time interval to absolute time */
    gettimeofday(&now, NULL);

    t.tv_sec += now.tv_sec;
    t.tv_usec += now.tv_usec;
    if (t.tv_usec >= 1000000) {
	t.tv_usec -= 1000000;
	t.tv_sec++;
    }

    eh->fd = fd;
    eh->flags = flags;
    eh->tmout = t;
    eh->fn = fn;
    eh->data = data;

    /* Add immediately.  This is safe even if we are in a handler. */
    eh->next = es->handlers;
    es->handlers = eh;

    EVENT_DEBUG(("Event_AddHandlerWithTimeout(es=%p, fd=%d, flags=%u, t=%d/%d) -> %p\n", es, fd, flags, t.tv_sec, t.tv_usec, eh));
    return eh;
}
Ejemplo n.º 4
0
/**********************************************************************
* %FUNCTION: SetupPipes (static)
* %ARGUMENTS:
*  es -- event selector
* %RETURNS:
*  0 on success; -1 on failure
* %DESCRIPTION:
*  Sets up pipes with an event handler to handle IPC from a signal handler
***********************************************************************/
static int
SetupPipes(EventSelector *es)
{
    int flags;
    int i;

    /* If already done, do nothing */
    if (PipeHandler) return 0;

    MyPid = getpid();

    /* Initialize the child-process hash table */
    hash_init(&child_process_table,
	      offsetof(struct ChildEntry, hash),
	      child_hash,
	      child_compare);

    /* Open pipe to self */
    if (pipe(Pipe) < 0) {
	return -1;
    }

    /* Make pipes non-blocking */
    for (i=0; i<=1; i++) {
	flags = fcntl(Pipe[i], F_GETFL, 0);
	if (flags != -1) {
	    flags = fcntl(Pipe[i], F_SETFL, flags | O_NONBLOCK);
	}
	if (flags == -1) {
	    close(Pipe[0]);
	    close(Pipe[1]);
	    return -1;
	}
    }

    PipeHandler = Event_AddHandler(es, Pipe[0],
				   EVENT_FLAG_READABLE, DoPipe, NULL);
    if (!PipeHandler) {
	int old_errno = errno;
	close(Pipe[0]);
	close(Pipe[1]);
	errno = old_errno;
	return -1;
    }
    return 0;
}
Ejemplo n.º 5
0
/**********************************************************************
* %FUNCTION: network_init
* %ARGUMENTS:
*  es -- an event selector
* %RETURNS:
*  >= 0 if all is OK, <0 if not
* %DESCRIPTION:
*  Initializes network; opens socket on UDP port 1701; sets up
*  event handler for incoming packets.
***********************************************************************/
int
l2tp_network_init(EventSelector *es)
{
    struct sockaddr_in me;
    int flags;

    gethostname(Hostname, sizeof(Hostname));
    Hostname[sizeof(Hostname)-1] = 0;

    Event_HandleSignal(es, SIGINT, sigint_handler);
    if (Sock >= 0) {
	if (NetworkReadHandler) {
	    Event_DelHandler(es, NetworkReadHandler);
	    NetworkReadHandler = NULL;
	}
	close(Sock);
	Sock = -1;
    }
    Sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (Sock < 0) {
	l2tp_set_errmsg("network_init: socket: %s", strerror(errno));
	return -1;
    }

    me.sin_family = AF_INET;
    me.sin_addr = Settings.listen_addr;
    me.sin_port = htons((uint16_t) Settings.listen_port);
    if (bind(Sock, (struct sockaddr *) &me, sizeof(me)) < 0) {
	l2tp_set_errmsg("network_init: bind: %s", strerror(errno));
	close(Sock);
	Sock = -1;
	return -1;
    }

    /* Set socket non-blocking */
    flags = fcntl(Sock, F_GETFL);
    flags |= O_NONBLOCK;
    fcntl(Sock, F_SETFL, flags);

    /* Set up the network read handler */
    Event_AddHandler(es, Sock, EVENT_FLAG_READABLE,
		     network_readable, NULL);
    return Sock;
}
Ejemplo n.º 6
0
/**********************************************************************
* %FUNCTION: EventTcp_CreateAcceptor
* %ARGUMENTS:
*  es -- event selector
*  socket -- listening socket
*  f -- function to call when a connection is accepted
*  data -- extra data to pass to f.
* %RETURNS:
*  An event handler on success, NULL on failure.
* %DESCRIPTION:
*  Sets up an accepting socket and calls "f" whenever a new
*  connection arrives.
***********************************************************************/
EventHandler *
EventTcp_CreateAcceptor(EventSelector *es,
			int socket,
			EventTcpAcceptFunc f)
{
    int flags;

    EVENT_DEBUG(("EventTcp_CreateAcceptor(es=%p, socket=%d)\n", es, socket));
    /* Make sure socket is non-blocking */
    flags = fcntl(socket, F_GETFL, 0);
    if (flags == -1) {
	return NULL;
    }
    if (fcntl(socket, F_SETFL, flags | O_NONBLOCK) == -1) {
	return NULL;
    }

    return Event_AddHandler(es, socket, EVENT_FLAG_READABLE,
			    handle_accept, (void *) f);

}