X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/9155ea97b695b6eb5fca1ee79f57b334f6c4ef53..367d81afe3d72b6bc1519d2ae2187a6535370025:/fwd.h diff --git a/fwd.h b/fwd.h index 2da55a3..a900e31 100644 --- a/fwd.h +++ b/fwd.h @@ -87,6 +87,8 @@ #include #include #include +#include +#include #include #include #include @@ -104,6 +106,160 @@ extern char **environ; #endif +/*----- Resource limit names ----------------------------------------------*/ + +#if defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) +# define RLIMIT_NOFILE RLIMIT_OFILE +#endif + +/* + ;;; The resource-limit name table is very boring to type and less fun to + ;;; maintain. To make life less awful, put the names in this list and + ;;; evaluate the code to get Emacs to regenerate it. + + (let ((limits '(as core cpu data fsize locks memlock msgqueue + nice nofile nproc rss rtprio sigpending stack + vmem))) + (save-excursion + (goto-char + (point-min)) + (search-forward (concat "***" "BEGIN rlimitlist" "***")) + (beginning-of-line 2) + (delete-region (point) + (progn + (search-forward "***END***") + (beginning-of-line) + (point))) + (let ((avail (make-marker)) + (list (make-marker))) + (set-marker avail (point)) + (insert "#define RLIMITS(_)") + (set-marker list (point)) + (dolist (limit (sort (copy-list limits) #'string<)) + (let* ((name (symbol-name limit)) + (constant (concat "RLIMIT_" (upcase name))) + (have (concat "HAVE_" constant "_P"))) + (goto-char avail) + (insert-before-markers (format (concat "#ifdef %s\n" + "# define %s t\n" + "#else\n" + "# define %s nil\n" + "#endif\n") + constant have have)) + (goto-char list) + (insert-before-markers + (format " \\\n MAYBE_ITEM(_, %s, (%s, %s))" + have name constant)))) + (goto-char list) + (insert "\n")))) +*/ + +/***BEGIN rlimitlist***/ +#ifdef RLIMIT_AS +# define HAVE_RLIMIT_AS_P t +#else +# define HAVE_RLIMIT_AS_P nil +#endif +#ifdef RLIMIT_CORE +# define HAVE_RLIMIT_CORE_P t +#else +# define HAVE_RLIMIT_CORE_P nil +#endif +#ifdef RLIMIT_CPU +# define HAVE_RLIMIT_CPU_P t +#else +# define HAVE_RLIMIT_CPU_P nil +#endif +#ifdef RLIMIT_DATA +# define HAVE_RLIMIT_DATA_P t +#else +# define HAVE_RLIMIT_DATA_P nil +#endif +#ifdef RLIMIT_FSIZE +# define HAVE_RLIMIT_FSIZE_P t +#else +# define HAVE_RLIMIT_FSIZE_P nil +#endif +#ifdef RLIMIT_LOCKS +# define HAVE_RLIMIT_LOCKS_P t +#else +# define HAVE_RLIMIT_LOCKS_P nil +#endif +#ifdef RLIMIT_MEMLOCK +# define HAVE_RLIMIT_MEMLOCK_P t +#else +# define HAVE_RLIMIT_MEMLOCK_P nil +#endif +#ifdef RLIMIT_MSGQUEUE +# define HAVE_RLIMIT_MSGQUEUE_P t +#else +# define HAVE_RLIMIT_MSGQUEUE_P nil +#endif +#ifdef RLIMIT_NICE +# define HAVE_RLIMIT_NICE_P t +#else +# define HAVE_RLIMIT_NICE_P nil +#endif +#ifdef RLIMIT_NOFILE +# define HAVE_RLIMIT_NOFILE_P t +#else +# define HAVE_RLIMIT_NOFILE_P nil +#endif +#ifdef RLIMIT_NPROC +# define HAVE_RLIMIT_NPROC_P t +#else +# define HAVE_RLIMIT_NPROC_P nil +#endif +#ifdef RLIMIT_RSS +# define HAVE_RLIMIT_RSS_P t +#else +# define HAVE_RLIMIT_RSS_P nil +#endif +#ifdef RLIMIT_RTPRIO +# define HAVE_RLIMIT_RTPRIO_P t +#else +# define HAVE_RLIMIT_RTPRIO_P nil +#endif +#ifdef RLIMIT_SIGPENDING +# define HAVE_RLIMIT_SIGPENDING_P t +#else +# define HAVE_RLIMIT_SIGPENDING_P nil +#endif +#ifdef RLIMIT_STACK +# define HAVE_RLIMIT_STACK_P t +#else +# define HAVE_RLIMIT_STACK_P nil +#endif +#ifdef RLIMIT_VMEM +# define HAVE_RLIMIT_VMEM_P t +#else +# define HAVE_RLIMIT_VMEM_P nil +#endif +#define RLIMITS(_) \ + MAYBE_ITEM(_, HAVE_RLIMIT_AS_P, (as, RLIMIT_AS)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_CORE_P, (core, RLIMIT_CORE)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_CPU_P, (cpu, RLIMIT_CPU)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_DATA_P, (data, RLIMIT_DATA)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_FSIZE_P, (fsize, RLIMIT_FSIZE)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_LOCKS_P, (locks, RLIMIT_LOCKS)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_MEMLOCK_P, (memlock, RLIMIT_MEMLOCK)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_MSGQUEUE_P, (msgqueue, RLIMIT_MSGQUEUE)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_NICE_P, (nice, RLIMIT_NICE)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_NOFILE_P, (nofile, RLIMIT_NOFILE)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_NPROC_P, (nproc, RLIMIT_NPROC)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_RSS_P, (rss, RLIMIT_RSS)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_RTPRIO_P, (rtprio, RLIMIT_RTPRIO)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_SIGPENDING_P, (sigpending, RLIMIT_SIGPENDING)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_STACK_P, (stack, RLIMIT_STACK)) \ + MAYBE_ITEM(_, HAVE_RLIMIT_VMEM_P, (vmem, RLIMIT_VMEM)) +/***END***/ + +/* --- The unpleasant conditional-output machinery --- */ + +#define MAYBE_ITEM(_, emitp, args) GLUE(MAYBE_ITEM_, emitp)(_, args) +#define MAYBE_ITEM_t(_, args) _ args +#define MAYBE_ITEM_nil(_, args) + /*----- Main program ------------------------------------------------------*/ /* --- The global select state --- */ @@ -115,9 +271,13 @@ extern sel_state *sel; extern const char grammar_text[]; extern const char option_text[]; +/* --- Generally useful magic constants --- */ + +#define NOW ((time_t)-1) + /* --- @fw_log@ --- * * - * Arguments: @time_t t@ = when the connection occurred or (@-1@) + * Arguments: @time_t t@ = when the connection occurred or (@NOW@) * @const char *fmt@ = format string to fill in * @...@ = other arguments * @@ -126,7 +286,8 @@ extern const char option_text[]; * Use: Logs a connection. */ -extern void fw_log(time_t /*t*/, const char */*fmt*/, ...); +extern void PRINTF_LIKE(2, 3) + fw_log(time_t /*t*/, const char */*fmt*/, ...); /* --- @fw_inc@, @fw_dec@ --- * * @@ -153,6 +314,7 @@ typedef struct chan { unsigned base, len; /* Base and length of data */ unsigned f; /* Various interesting flags */ void (*func)(void */*p*/); /* Function to call on closure */ + int err; /* What's wrong with the channel */ void *p; /* Argument to pass function */ sel_file r, w; /* Reader and writer selectors */ char buf[CHAN_BUFSZ]; /* The actual data buffer */ @@ -373,7 +535,8 @@ extern int token(scanner */*sc*/); * Use: Reports an error at the current scanner location. */ -extern void error(scanner */*sc*/, const char */*msg*/, ...); +extern void PRINTF_LIKE(2, 3) NORETURN + error(scanner */*sc*/, const char */*msg*/, ...); /* --- @pushback@ --- * * @@ -565,6 +728,18 @@ extern int conf_prefix(scanner */*sc*/, const char */*p*/); extern void conf_name(scanner */*sc*/, char /*delim*/, dstr */*d*/); +/* --- @conf_fname@ --- * + * + * Arguments: @scanner *sc@ = pointer to scanner + * @dstr *d@ = pointer to dynamic string for output + * + * Returns: --- + * + * Use: Reads a file name from the input and stores it in @d@. + */ + +extern void conf_fname(scanner */*sc*/, dstr */*d*/); + /*----- Reference-counted file descriptors --------------------------------*/ typedef struct reffd { @@ -878,13 +1053,21 @@ extern void endpt_killall(void); * * Arguments: @endpt *a@ = pointer to first endpoint * @endpt *b@ = pointer to second endpoint + * @const char *desc@ = description of connection * * Returns: --- * - * Use: Joins two endpoints together. + * Use: Joins two endpoints together. It's OK to join endpoints + * which are already joined; in fact, the the right thing to do + * when your endpoint decides that it's not pending any more is + * to join it to its partner again. + * + * If the endpoints are already connected then the description + * string is ignored. The endpoint manager takes a copy of + * the string, so you don't need to keep it around. */ -extern void endpt_join(endpt */*a*/, endpt */*b*/); +extern void endpt_join(endpt */*a*/, endpt */*b*/, const char */*desc*/); /* --- @source_add@ --- * *