From 1cd4a3bfdaf82f0bc0691671954b239dccb003fb Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 29 Jun 2013 14:56:57 +0100 Subject: [PATCH] Eliminate the `rlimits.h' header using scary macros. The `rlimits.h' header is a bit of a hack, which was thought necessary because if must assemble a list of things conditionally. This patch eliminates this unpleasantness by replacing it with a different hack which is at least as nasty. Associate with each potential limit name a macro whose value is either `t' or `nil', indicating whether the limit is known. This can be done using lots of `#ifdef ... #else ... #endif' blocks. Finally, assemble a list macro of all of the names, whether they're known or not (because we can't tell at this point). The trick is that, instead of just calling `_(...)' for each item, we call `MAYBE_CALL(_, HAVE_???_P, (...))', and the latter uses token-pasting to dispatch on the `HAVE_???_P' flag and conditionally invoke `_(...)'. Thus callers can work with this as a conventional list macro. Of course, building all of this is monumentally tedious, so we get Emacs to do it for us. --- Makefile.am | 1 - exec.c | 11 +++-- fwd.h | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rlimits.h | 88 ---------------------------------- 4 files changed, 161 insertions(+), 93 deletions(-) delete mode 100644 rlimits.h diff --git a/Makefile.am b/Makefile.am index 44fba7a..dfc03ad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,7 +90,6 @@ fwd_SOURCES += file.c ## Executables. fwd_SOURCES += exec.c -fwd_SOURCES += rlimits.h ## Documentation. fwd_SOURCES += mantext.c diff --git a/exec.c b/exec.c index 9b7e87b..92c0b26 100644 --- a/exec.c +++ b/exec.c @@ -33,8 +33,9 @@ #ifdef HAVE_SETRLIMIT typedef struct xlimit { -#define R(r, n) struct rlimit n; -#include "rlimits.h" +#define XLIMIT_ENTRY(name, constant) struct rlimit name; + RLIMITS(XLIMIT_ENTRY) +#undef XLIMIT_ENTRY } xlimit; #endif @@ -138,8 +139,10 @@ typedef struct rlimit_ent { } rlimit_ent; static rlimit_ent rlimits[] = { -#define R(r, n) { #n, #r, r, offsetof(xlimit, n) }, -#include "rlimits.h" +#define TABLE_ENTRY(name, constant) \ + { #name, #constant, constant, offsetof(xlimit, name) }, + RLIMITS(TABLE_ENTRY) +#undef TABLE_ENTRY { 0, 0, 0, 0 } }; diff --git a/fwd.h b/fwd.h index 2d139e4..5868fda 100644 --- a/fwd.h +++ b/fwd.h @@ -105,6 +105,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 --- */ diff --git a/rlimits.h b/rlimits.h deleted file mode 100644 index f3f2769..0000000 --- a/rlimits.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*-c-*- - * - * List of resource limits known to mankind - * - * (c) 1999 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of the `fwd' port forwarder. - * - * `fwd' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `fwd' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `fwd'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Magic -------------------------------------------------------------*/ - -#ifndef R -# error "Don't try including rlimits.h unless you know what you're doing" -#endif - -#if defined(RLIMIT_OFILE) && !defined(RLIMIT_NOFILE) -# define RLIMIT_NOFILE RLIMIT_OFILE -#endif - -#ifdef RLIMIT_AS - R(RLIMIT_AS, as) -#endif -#ifdef RLIMIT_CORE - R(RLIMIT_CORE, core) -#endif -#ifdef RLIMIT_CPU - R(RLIMIT_CPU, cpu) -#endif -#ifdef RLIMIT_DATA - R(RLIMIT_DATA, data) -#endif -#ifdef RLIMIT_FSIZE - R(RLIMIT_FSIZE, fsize) -#endif -#ifdef RLIMIT_LOCKS - R(RLIMIT_LOCKS, locks) -#endif -#ifdef RLIMIT_MEMLOCK - R(RLIMIT_MEMLOCK, memlock) -#endif -#ifdef RLIMIT_MSGQUEUE - R(RLIMIT_MSGQUEUE, msgqueue) -#endif -#ifdef RLIMIT_NICE - R(RLIMIT_NICE, nice) -#endif -#ifdef RLIMIT_NOFILE - R(RLIMIT_NOFILE, nofile) -#endif -#ifdef RLIMIT_NPROC - R(RLIMIT_NPROC, nproc) -#endif -#ifdef RLIMIT_RSS - R(RLIMIT_RSS, rss) -#endif -#ifdef RLIMIT_RTPRIO - R(RLIMIT_RTPRIO, rtprio) -#endif -#ifdef RLIMIT_SIGPENDING - R(RLIMIT_SIGPENDING, sigpending) -#endif -#ifdef RLIMIT_STACK - R(RLIMIT_STACK, stack) -#endif -#ifdef RLIMIT_VMEM - R(RLIMIT_VMEM, vmem) -#endif - -#undef R - -/*----- That's all, folks -------------------------------------------------*/ -- 2.11.0