chiark / gitweb /
util: Provide async_linebuf_read
[secnet.git] / secnet.h
index 629851b2ac183234cf00ba8ca773c1e730183b2d..b2f6927af03ff29fd4d0c35482f84e245db25031 100644 (file)
--- a/secnet.h
+++ b/secnet.h
 #include <assert.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/poll.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -57,6 +59,10 @@ extern struct log_if *system_log;
 /* from process.c */
 extern void start_signal_handling(void);
 
+void afterfork(void);
+/* Must be called before exec in every child made after
+   start_signal_handling.  Safe to call in earlier children too. */
+
 /***** CONFIGURATION support *****/
 
 extern bool_t just_check_config; /* If True then we're going to exit after
@@ -164,8 +170,11 @@ extern uint32_t string_list_to_word(list_t *l, struct flagstr *f,
 extern char *safe_strdup(const char *string, const char *message);
 extern void *safe_malloc(size_t size, const char *message);
 extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
+extern void *safe_realloc_ary(void *p, size_t size, size_t count,
+                             const char *message);
 
 void setcloexec(int fd); /* cannot fail */
+void setnonblock(int fd); /* cannot fail */
 void pipe_cloexec(int fd[2]); /* pipe(), setcloexec() twice; cannot fail */
 
 extern int sys_cmd(const char *file, const char *argc, ...);
@@ -195,20 +204,37 @@ int32_t calculate_max_start_pad(void);
 
 /* If nfds_io is insufficient for your needs, set it to the required
    number and return ERANGE. timeout is in milliseconds; if it is too
-   high then lower it. It starts at -1 (==infinite) */
+   high then lower it. It starts at -1 (==infinite). */
+/* Note that beforepoll_fn may NOT do anything which might change the
+   fds or timeouts wanted by other registered poll loop loopers.
+   Callers should make sure of this by not making any calls into other
+   modules from the beforepoll_fn; the easiest way to ensure this is
+   for beforepoll_fn to only retreive information and not take any
+   action.
+ */
 typedef int beforepoll_fn(void *st, struct pollfd *fds, int *nfds_io,
                          int *timeout_io);
 typedef void afterpoll_fn(void *st, struct pollfd *fds, int nfds);
+  /* If beforepoll_fn returned ERANGE, afterpoll_fn gets nfds==0.
+     afterpoll_fn never gets !!(fds[].revents & POLLNVAL) - such
+     a report is detected as a fatal error by the event loop. */
+
+/* void BEFOREPOLL_WANT_FDS(int want);
+ *   Expects: int *nfds_io;
+ *   Can perform non-local exit.
+ * Checks whether there is space for want fds.  If so, sets *nfds_io.
+ * If not, sets *nfds_io and returns. */
+#define BEFOREPOLL_WANT_FDS(want) do{                          \
+    if (*nfds_io<(want)) { *nfds_io=(want); return ERANGE; }   \
+    *nfds_io=(want);                                           \
+  }while(0)
 
 /* Register interest in the main loop of the program. Before a call
    to poll() your supplied beforepoll function will be called. After
-   the call to poll() the supplied afterpoll function will be called.
-   max_nfds is a _hint_ about the maximum number of struct pollfd
-   structures you may require - you can always ask for more in
-   *nfds_io. */
-extern void register_for_poll(void *st, beforepoll_fn *before,
-                             afterpoll_fn *after, int32_t max_nfds,
-                             cstring_t desc);
+   the call to poll() the supplied afterpoll function will be called. */
+struct poll_interest *register_for_poll(void *st, beforepoll_fn *before,
+                             afterpoll_fn *after, cstring_t desc);
+void deregister_for_poll(struct poll_interest *i);
 
 /***** END of scheduling support */
 
@@ -358,7 +384,7 @@ struct comm_addr {
 };
 
 /* Return True if the packet was processed, and shouldn't be passed to
-   any other potential receivers. */
+   any other potential receivers. (buf is freed iff True returned.) */
 typedef bool_t comm_notify_fn(void *state, struct buffer_if *buf,
                              const struct comm_addr *source);
 typedef void comm_request_notify_fn(void *commst, void *nst,
@@ -567,6 +593,19 @@ extern NORETURN(fatal_status(int status, const char *message, ...))
 extern NORETURN(fatal_perror_status(int status, const char *message, ...))
        FORMAT(printf,2,3);
 
+/* Convenient nonfatal logging.  Requires message that does not end in '\n'.
+ * If class contains M_FATAL, exits (after entering PHASE_SHUTDOWN).
+ * lg, errnoval and loc may sensibly be 0.  desc must NOT be 0.
+ * lg_[v]perror save and restore errno. */
+void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc,
+               int class, int errnoval, const char *fmt, va_list al)
+    FORMAT(printf,6,0);
+void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc,
+              int class, int errnoval, const char *fmt, ...)
+    FORMAT(printf,6,7);
+void lg_exitstatus(struct log_if *lg, const char *desc, struct cloc *loc,
+                  int class, int status, const char *progname);
+
 /* The cfgfatal() family of functions require messages that end in '\n' */
 extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
                         const char *message, ...)) FORMAT(printf,3,4);