A clone of btpd with my configuration changes.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

181 líneas
4.4 KiB

  1. /* $OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
  2. /*
  3. * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include <sys/types.h>
  32. #ifdef HAVE_SYS_TIME_H
  33. #include <sys/time.h>
  34. #else
  35. #include <sys/_time.h>
  36. #endif
  37. #include <sys/queue.h>
  38. #include <sys/socket.h>
  39. #include <signal.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <unistd.h>
  44. #include <errno.h>
  45. #ifdef HAVE_FCNTL_H
  46. #include <fcntl.h>
  47. #endif
  48. #include "event.h"
  49. #include "evsignal.h"
  50. #include "log.h"
  51. extern struct event_list signalqueue;
  52. static sig_atomic_t evsigcaught[NSIG];
  53. volatile sig_atomic_t evsignal_caught = 0;
  54. static struct event ev_signal;
  55. static int ev_signal_pair[2];
  56. static int ev_signal_added;
  57. static void evsignal_handler(int sig);
  58. /* Callback for when the signal handler write a byte to our signaling socket */
  59. static void
  60. evsignal_cb(int fd, short what, void *arg)
  61. {
  62. static char signals[100];
  63. struct event *ev = arg;
  64. ssize_t n;
  65. n = read(fd, signals, sizeof(signals));
  66. if (n == -1)
  67. event_err(1, "%s: read", __func__);
  68. event_add(ev, NULL);
  69. }
  70. #ifdef HAVE_SETFD
  71. #define FD_CLOSEONEXEC(x) do { \
  72. if (fcntl(x, F_SETFD, 1) == -1) \
  73. event_warn("fcntl(%d, F_SETFD)", x); \
  74. } while (0)
  75. #else
  76. #define FD_CLOSEONEXEC(x)
  77. #endif
  78. void
  79. evsignal_init(void)
  80. {
  81. /*
  82. * Our signal handler is going to write to one end of the socket
  83. * pair to wake up our event loop. The event loop then scans for
  84. * signals that got delivered.
  85. */
  86. if (socketpair(AF_UNIX, SOCK_STREAM, 0, ev_signal_pair) == -1)
  87. event_err(1, "%s: socketpair", __func__);
  88. FD_CLOSEONEXEC(ev_signal_pair[0]);
  89. FD_CLOSEONEXEC(ev_signal_pair[1]);
  90. fcntl(ev_signal_pair[0], F_SETFL, O_NONBLOCK);
  91. event_set(&ev_signal, ev_signal_pair[1], EV_READ,
  92. evsignal_cb, &ev_signal);
  93. ev_signal.ev_flags |= EVLIST_INTERNAL;
  94. }
  95. int
  96. evsignal_add(struct event *ev)
  97. {
  98. int evsignal;
  99. struct sigaction sa;
  100. if (ev->ev_events & (EV_READ|EV_WRITE))
  101. event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
  102. evsignal = EVENT_SIGNAL(ev);
  103. memset(&sa, 0, sizeof(sa));
  104. sa.sa_handler = evsignal_handler;
  105. sigfillset(&sa.sa_mask);
  106. sa.sa_flags |= SA_RESTART;
  107. if (sigaction(evsignal, &sa, NULL) == -1)
  108. return (-1);
  109. if (!ev_signal_added) {
  110. ev_signal_added = 1;
  111. event_add(&ev_signal, NULL);
  112. }
  113. return (0);
  114. }
  115. /*
  116. * Nothing to be done here.
  117. */
  118. int
  119. evsignal_del(struct event *ev)
  120. {
  121. int evsignal;
  122. evsignal = EVENT_SIGNAL(ev);
  123. return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
  124. }
  125. static void
  126. evsignal_handler(int sig)
  127. {
  128. int save_errno = errno;
  129. evsigcaught[sig]++;
  130. evsignal_caught = 1;
  131. /* Wake up our notification mechanism */
  132. write(ev_signal_pair[0], "a", 1);
  133. errno = save_errno;
  134. }
  135. void
  136. evsignal_process(void)
  137. {
  138. struct event *ev;
  139. sig_atomic_t ncalls;
  140. evsignal_caught = 0;
  141. TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  142. ncalls = evsigcaught[EVENT_SIGNAL(ev)];
  143. if (ncalls) {
  144. if (!(ev->ev_events & EV_PERSIST))
  145. event_del(ev);
  146. event_active(ev, EV_SIGNAL, ncalls);
  147. evsigcaught[EVENT_SIGNAL(ev)] = 0;
  148. }
  149. }
  150. }