All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Generate signal names at runtime
@ 2024-04-21 20:46 Henrik Lindström
  2024-04-27 11:47 ` Herbert Xu
  0 siblings, 1 reply; 5+ messages in thread
From: Henrik Lindström @ 2024-04-21 20:46 UTC (permalink / raw)
  To: dash; +Cc: Henrik Lindström

They were previously generated at buildtime by mksignames.c, but that
approach had two flaws:
1. The signal names were generated for the host system rather than the
   target system, resulting in broken cross-compiled builds.
2. The SIGRTMIN and SIGRTMAX macros are usually implemented as
   function calls and can only be surely known at runtime.

The new implementation has been tested to generate identical signal names
as before on these systems:
* Debian 12 (glibc, odd number of realtime signals)
* Alpine 3.18 (musl, even number of realtime signals)
* FreeBSD 14

Signed-off-by: Henrik Lindström <henrik@lxm.se>
---
 COPYING          |  24 ---
 src/.gitignore   |   2 -
 src/Makefile.am  |  17 +-
 src/TOUR         |   1 -
 src/jobs.c       |   6 +-
 src/mksignames.c | 415 -----------------------------------------------
 src/signalname.c | 150 +++++++++++++++++
 src/signalname.h |   4 +
 src/trap.c       |   7 +-
 9 files changed, 167 insertions(+), 459 deletions(-)
 delete mode 100644 src/mksignames.c
 create mode 100644 src/signalname.c
 create mode 100644 src/signalname.h

diff --git a/COPYING b/COPYING
index 37f8189..c591477 100644
--- a/COPYING
+++ b/COPYING
@@ -30,27 +30,3 @@ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
-
-mksignames.c:
-
-This file is not directly linked with dash.  However, its output is.
-
-Copyright (C) 1992 Free Software Foundation, Inc.
-
-This file is part of GNU Bash, the Bourne Again SHell.
-
-Bash 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, or (at your option) any later
-version.
-
-Bash 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 with
-your Debian GNU/Linux system, in /usr/share/common-licenses/GPL, or with the
-Debian GNU/Linux hello source package as the file COPYING.  If not,
-write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-Boston, MA 02111 USA.
diff --git a/src/.gitignore b/src/.gitignore
index 644eccb..660bbdd 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -5,9 +5,7 @@ dash
 init.c
 mkinit
 mknodes
-mksignames
 mksyntax
 nodes.[ch]
-signames.c
 syntax.[ch]
 token.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 1732465..8d1dc37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,20 +6,20 @@ COMMON_CPPFLAGS = \
 
 AM_CFLAGS = $(COMMON_CFLAGS)
 AM_CPPFLAGS = -include $(top_builddir)/config.h $(COMMON_CPPFLAGS)
-AM_CFLAGS_FOR_BUILD = -g -O2 $(COMMON_CFLAGS) 
+AM_CFLAGS_FOR_BUILD = -g -O2 $(COMMON_CFLAGS)
 AM_CPPFLAGS_FOR_BUILD = $(COMMON_CPPFLAGS)
 
 COMPILE_FOR_BUILD = \
 	$(CC_FOR_BUILD) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS_FOR_BUILD) \
 	$(CPPFLAGS_FOR_BUILD) \
-	$(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) 
+	$(AM_CFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
 
 bin_PROGRAMS = dash
 
 dash_CFILES = \
 	alias.c arith_yacc.c arith_yylex.c cd.c error.c eval.c exec.c expand.c \
 	histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \
-	mystring.c options.c parser.c redir.c show.c trap.c output.c \
+	mystring.c options.c parser.c redir.c show.c signalname.c trap.c output.c \
 	bltin/printf.c system.c bltin/test.c bltin/times.c var.c
 dash_SOURCES = \
 	$(dash_CFILES) \
@@ -27,10 +27,10 @@ dash_SOURCES = \
 	expand.h \
 	init.h input.h jobs.h machdep.h mail.h main.h memalloc.h miscbltin.h \
 	myhistedit.h mystring.h options.h output.h parser.h redir.h shell.h \
-	show.h system.h trap.h var.h
-dash_LDADD = builtins.o init.o nodes.o signames.o syntax.o
+	show.h signalname.h system.h trap.h var.h
+dash_LDADD = builtins.o init.o nodes.o syntax.o
 
-HELPERS = mkinit mksyntax mknodes mksignames
+HELPERS = mkinit mksyntax mknodes
 
 BUILT_SOURCES = builtins.h nodes.h syntax.h token.h token_vars.h
 CLEANFILES = \
@@ -41,7 +41,7 @@ man_MANS = dash.1
 EXTRA_DIST = \
 	$(man_MANS) \
 	mktokens mkbuiltins builtins.def.in mkinit.c \
-	mknodes.c nodetypes nodes.c.pat mksyntax.c mksignames.c
+	mknodes.c nodetypes nodes.c.pat mksyntax.c
 
 token.h token_vars.h: mktokens
 	$(AM_V_GEN)$(SHELL) $^
@@ -61,9 +61,6 @@ nodes.c nodes.h: mknodes nodetypes nodes.c.pat
 syntax.c syntax.h: mksyntax
 	$(AM_V_GEN)./$^
 
-signames.c: mksignames
-	$(AM_V_GEN)./$^
-
 mksyntax: token.h
 
 $(HELPERS): %: %.c
diff --git a/src/TOUR b/src/TOUR
index e30836e..b554f13 100644
--- a/src/TOUR
+++ b/src/TOUR
@@ -26,7 +26,6 @@ programs is:
         mkbuiltins      builtins            builtins.h builtins.c
         mkinit          *.c                 init.c
         mknodes         nodetypes           nodes.h nodes.c
-        mksignames          -               signames.h signames.c
         mksyntax            -               syntax.h syntax.c
         mktokens            -               token.h
         bltin/mkexpr    unary_op binary_op  operators.h operators.c
diff --git a/src/jobs.c b/src/jobs.c
index 2a2fe22..6430cb3 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -71,6 +71,7 @@
 #include "error.h"
 #include "mystring.h"
 #include "system.h"
+#include "signalname.h"
 
 /* mode flags for set_curjob */
 #define CUR_DELETE 2
@@ -262,7 +263,6 @@ out:
 
 int killcmd(int argc, char **argv)
 {
-	extern char *signal_names[];
 	int signo = -1;
 	int list = 0;
 	int i;
@@ -320,7 +320,7 @@ usage:
 		if (!*argv) {
 			outstr("0\n", out);
 			for (i = 1; i < NSIG; i++) {
-				outfmt(out, snlfmt, signal_names[i]);
+				outfmt(out, snlfmt, signalname(i));
 			}
 			return 0;
 		}
@@ -328,7 +328,7 @@ usage:
 		if (signo > 128)
 			signo -= 128;
 		if (0 < signo && signo < NSIG)
-			outfmt(out, snlfmt, signal_names[signo]);
+			outfmt(out, snlfmt, signalname(signo));
 		else
 			sh_error("invalid signal number or exit status: %s",
 				 *argv);
diff --git a/src/mksignames.c b/src/mksignames.c
deleted file mode 100644
index 192728b..0000000
--- a/src/mksignames.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/* signames.c -- Create and write `signames.c', which contains an array of
-   signal names. */
-
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-
-   This file is part of GNU Bash, the Bourne Again SHell.
-
-   Bash 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, or (at your option) any later
-   version.
-
-   Bash 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 Bash; see the file COPYING.  If not, write to the Free Software
-   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <stdlib.h>
-
-#if !defined (NSIG)
-#  define NSIG 64
-#endif
-
-/*
- * Special traps:
- *	EXIT == 0
- */
-#define LASTSIG NSIG-1
-
-char *signal_names[2 * NSIG + 3];
-
-#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0]))
-
-char *progname;
-
-/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively.
-   I don't want to allocate so much unused space for the intervening signal
-   numbers, so we just punt if SIGRTMAX is past the bounds of the
-   signal_names array (handled in configure). */
-#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS)
-#  undef SIGRTMAX
-#  undef SIGRTMIN
-#endif
-
-#if defined (SIGRTMAX) || defined (SIGRTMIN)
-#  define RTLEN 14
-#  define RTLIM 256
-#endif
-
-void
-initialize_signames ()
-{
-  register int i;
-#if defined (SIGRTMAX) || defined (SIGRTMIN)
-  int rtmin, rtmax, rtcnt;
-#endif
-
-  for (i = 1; i < signal_names_size; i++)
-    signal_names[i] = (char *)NULL;
-
-  /* `signal' 0 is what we do on exit. */
-  signal_names[0] = "EXIT";
-
-  /* Place signal names which can be aliases for more common signal
-     names first.  This allows (for example) SIGABRT to overwrite SIGLOST. */
-
-  /* POSIX 1003.1b-1993 real time signals, but take care of incomplete
-     implementations. Acoording to the standard, both, SIGRTMIN and
-     SIGRTMAX must be defined, SIGRTMIN must be stricly less than
-     SIGRTMAX, and the difference must be at least 7, that is, there
-     must be at least eight distinct real time signals. */
-
-  /* The generated signal names are SIGRTMIN, SIGRTMIN+1, ...,
-     SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number
-     of RT signals is odd, there is an extra SIGRTMIN+(x+1).
-     These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */
-
-#if defined (SIGRTMIN)
-  rtmin = SIGRTMIN;
-  signal_names[rtmin] = "RTMIN";
-#endif
-
-#if defined (SIGRTMAX)
-  rtmax = SIGRTMAX;
-  signal_names[rtmax] = "RTMAX";
-#endif
-
-#if defined (SIGRTMAX) && defined (SIGRTMIN)
-  if (rtmax > rtmin)
-    {
-      rtcnt = (rtmax - rtmin - 1) / 2;
-      /* croak if there are too many RT signals */
-      if (rtcnt >= RTLIM/2)
-	{
-	  rtcnt = RTLIM/2-1;
-	  fprintf(stderr, "%s: error: more than %i real time signals, fix `%s'\n",
-		  progname, RTLIM, progname);
-	}
-
-      for (i = 1; i <= rtcnt; i++)
-	{
-	  signal_names[rtmin+i] = (char *)malloc(RTLEN);
-	  if (signal_names[rtmin+i])
-	    sprintf (signal_names[rtmin+i], "RTMIN+%d", i);
-	  signal_names[rtmax-i] = (char *)malloc(RTLEN);
-	  if (signal_names[rtmax-i])
-	    sprintf (signal_names[rtmax-i], "RTMAX-%d", i);
-	}
-
-      if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2)
-	{
-	  /* Need an extra RTMIN signal */
-	  signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN);
-	  if (signal_names[rtmin+rtcnt+1])
-	    sprintf (signal_names[rtmin+rtcnt+1], "RTMIN+%d", rtcnt+1);
-	}
-    }
-#endif /* SIGRTMIN && SIGRTMAX */
-
-/* AIX */
-#if defined (SIGLOST)	/* resource lost (eg, record-lock lost) */
-  signal_names[SIGLOST] = "LOST";
-#endif
-
-#if defined (SIGMSG)	/* HFT input data pending */
-  signal_names[SIGMSG] = "MSG";
-#endif
-
-#if defined (SIGDANGER)	/* system crash imminent */
-  signal_names[SIGDANGER] = "DANGER";
-#endif
-
-#if defined (SIGMIGRATE) /* migrate process to another CPU */
-  signal_names[SIGMIGRATE] = "MIGRATE";
-#endif
-
-#if defined (SIGPRE)	/* programming error */
-  signal_names[SIGPRE] = "PRE";
-#endif
-
-#if defined (SIGVIRT)	/* AIX virtual time alarm */
-  signal_names[SIGVIRT] = "VIRT";
-#endif
-
-#if defined (SIGALRM1)	/* m:n condition variables */
-  signal_names[SIGALRM1] = "ALRM1";
-#endif
-
-#if defined (SIGWAITING)	/* m:n scheduling */
-  signal_names[SIGWAITING] = "WAITING";
-#endif
-
-#if defined (SIGGRANT)	/* HFT monitor mode granted */
-  signal_names[SIGGRANT] = "GRANT";
-#endif
-
-#if defined (SIGKAP)	/* keep alive poll from native keyboard */
-  signal_names[SIGKAP] = "KAP";
-#endif
-
-#if defined (SIGRETRACT) /* HFT monitor mode retracted */
-  signal_names[SIGRETRACT] = "RETRACT";
-#endif
-
-#if defined (SIGSOUND)	/* HFT sound sequence has completed */
-  signal_names[SIGSOUND] = "SOUND";
-#endif
-
-#if defined (SIGSAK)	/* Secure Attention Key */
-  signal_names[SIGSAK] = "SAK";
-#endif
-
-/* SunOS5 */
-#if defined (SIGLWP)	/* special signal used by thread library */
-  signal_names[SIGLWP] = "LWP";
-#endif
-
-#if defined (SIGFREEZE)	/* special signal used by CPR */
-  signal_names[SIGFREEZE] = "FREEZE";
-#endif
-
-#if defined (SIGTHAW)	/* special signal used by CPR */
-  signal_names[SIGTHAW] = "THAW";
-#endif
-
-#if defined (SIGCANCEL)	/* thread cancellation signal used by libthread */
-  signal_names[SIGCANCEL] = "CANCEL";
-#endif
-
-/* HP-UX */
-#if defined (SIGDIL)	/* DIL signal (?) */
-  signal_names[SIGDIL] = "DIL";
-#endif
-
-/* System V */
-#if defined (SIGCLD)	/* Like SIGCHLD.  */
-  signal_names[SIGCLD] = "CLD";
-#endif
-
-#if defined (SIGPWR)	/* power state indication */
-  signal_names[SIGPWR] = "PWR";
-#endif
-
-#if defined (SIGPOLL)	/* Pollable event (for streams)  */
-  signal_names[SIGPOLL] = "POLL";
-#endif
-
-/* Unknown */
-#if defined (SIGWINDOW)
-  signal_names[SIGWINDOW] = "WINDOW";
-#endif
-
-/* Common */
-#if defined (SIGHUP)	/* hangup */
-  signal_names[SIGHUP] = "HUP";
-#endif
-
-#if defined (SIGINT)	/* interrupt */
-  signal_names[SIGINT] = "INT";
-#endif
-
-#if defined (SIGQUIT)	/* quit */
-  signal_names[SIGQUIT] = "QUIT";
-#endif
-
-#if defined (SIGILL)	/* illegal instruction (not reset when caught) */
-  signal_names[SIGILL] = "ILL";
-#endif
-
-#if defined (SIGTRAP)	/* trace trap (not reset when caught) */
-  signal_names[SIGTRAP] = "TRAP";
-#endif
-
-#if defined (SIGIOT)	/* IOT instruction */
-  signal_names[SIGIOT] = "IOT";
-#endif
-
-#if defined (SIGABRT)	/* Cause current process to dump core. */
-  signal_names[SIGABRT] = "ABRT";
-#endif
-
-#if defined (SIGEMT)	/* EMT instruction */
-  signal_names[SIGEMT] = "EMT";
-#endif
-
-#if defined (SIGFPE)	/* floating point exception */
-  signal_names[SIGFPE] = "FPE";
-#endif
-
-#if defined (SIGKILL)	/* kill (cannot be caught or ignored) */
-  signal_names[SIGKILL] = "KILL";
-#endif
-
-#if defined (SIGBUS)	/* bus error */
-  signal_names[SIGBUS] = "BUS";
-#endif
-
-#if defined (SIGSEGV)	/* segmentation violation */
-  signal_names[SIGSEGV] = "SEGV";
-#endif
-
-#if defined (SIGSYS)	/* bad argument to system call */
-  signal_names[SIGSYS] = "SYS";
-#endif
-
-#if defined (SIGPIPE)	/* write on a pipe with no one to read it */
-  signal_names[SIGPIPE] = "PIPE";
-#endif
-
-#if defined (SIGALRM)	/* alarm clock */
-  signal_names[SIGALRM] = "ALRM";
-#endif
-
-#if defined (SIGTERM)	/* software termination signal from kill */
-  signal_names[SIGTERM] = "TERM";
-#endif
-
-#if defined (SIGURG)	/* urgent condition on IO channel */
-  signal_names[SIGURG] = "URG";
-#endif
-
-#if defined (SIGSTOP)	/* sendable stop signal not from tty */
-  signal_names[SIGSTOP] = "STOP";
-#endif
-
-#if defined (SIGTSTP)	/* stop signal from tty */
-  signal_names[SIGTSTP] = "TSTP";
-#endif
-
-#if defined (SIGCONT)	/* continue a stopped process */
-  signal_names[SIGCONT] = "CONT";
-#endif
-
-#if defined (SIGCHLD)	/* to parent on child stop or exit */
-  signal_names[SIGCHLD] = "CHLD";
-#endif
-
-#if defined (SIGTTIN)	/* to readers pgrp upon background tty read */
-  signal_names[SIGTTIN] = "TTIN";
-#endif
-
-#if defined (SIGTTOU)	/* like TTIN for output if (tp->t_local&LTOSTOP) */
-  signal_names[SIGTTOU] = "TTOU";
-#endif
-
-#if defined (SIGIO)	/* input/output possible signal */
-  signal_names[SIGIO] = "IO";
-#endif
-
-#if defined (SIGXCPU)	/* exceeded CPU time limit */
-  signal_names[SIGXCPU] = "XCPU";
-#endif
-
-#if defined (SIGXFSZ)	/* exceeded file size limit */
-  signal_names[SIGXFSZ] = "XFSZ";
-#endif
-
-#if defined (SIGVTALRM)	/* virtual time alarm */
-  signal_names[SIGVTALRM] = "VTALRM";
-#endif
-
-#if defined (SIGPROF)	/* profiling time alarm */
-  signal_names[SIGPROF] = "PROF";
-#endif
-
-#if defined (SIGWINCH)	/* window changed */
-  signal_names[SIGWINCH] = "WINCH";
-#endif
-
-/* 4.4 BSD */
-#if defined (SIGINFO) && !defined (_SEQUENT_)	/* information request */
-  signal_names[SIGINFO] = "INFO";
-#endif
-
-#if defined (SIGUSR1)	/* user defined signal 1 */
-  signal_names[SIGUSR1] = "USR1";
-#endif
-
-#if defined (SIGUSR2)	/* user defined signal 2 */
-  signal_names[SIGUSR2] = "USR2";
-#endif
-
-#if defined (SIGKILLTHR)	/* BeOS: Kill Thread */
-  signal_names[SIGKILLTHR] = "KILLTHR";
-#endif
-
-  for (i = 0; i < NSIG; i++)
-    if (signal_names[i] == (char *)NULL)
-      {
-	signal_names[i] = (char *)malloc (18);
-	if (signal_names[i])
-	  sprintf (signal_names[i], "%d", i);
-      }
-}
-
-void write_signames(FILE *stream)
-{
-  register int i;
-
-  fprintf (stream, "/* This file was automatically created by %s.\n",
-	   progname);
-  fprintf (stream, "   Do not edit.  Edit support/mksignames.c instead. */\n\n");
-  fprintf (stream, "#include <signal.h>\n\n");
-  fprintf (stream,
-	   "/* A translation list so we can be polite to our users. */\n");
-  fprintf (stream, "const char *const signal_names[NSIG + 1] = {\n");
-
-  for (i = 0; i <= LASTSIG; i++)
-    fprintf (stream, "    \"%s\",\n", signal_names[i]);
-
-  fprintf (stream, "    (char *)0x0\n");
-  fprintf (stream, "};\n");
-}
-
-int
-main(int argc, char **argv)
-{
-  char *stream_name;
-  FILE *stream;
-
-  progname = argv[0];
-
-  if (argc == 1)
-    {
-      stream_name = "signames.c";
-    }
-  else if (argc == 2)
-    {
-      stream_name = argv[1];
-    }
-  else
-    {
-      fprintf (stderr, "Usage: %s [output-file]\n", progname);
-      exit (1);
-    }
-
-  stream = fopen (stream_name, "w");
-  if (!stream)
-    {
-      fprintf (stderr, "%s: %s: cannot open for writing\n",
-	       progname, stream_name);
-      exit (2);
-    }
-
-  initialize_signames ();
-  write_signames (stream);
-  exit (0);
-}
diff --git a/src/signalname.c b/src/signalname.c
new file mode 100644
index 0000000..437e07c
--- /dev/null
+++ b/src/signalname.c
@@ -0,0 +1,150 @@
+// This file is in the Public Domain.
+#include <signal.h>
+
+#include "shell.h"
+#include "output.h"
+#include "signalname.h"
+
+MKINIT char *signal_names[NSIG] = {0};
+#if defined(SIGRTMIN) && defined(SIGRTMAX)
+MKINIT int sigrtmin;
+MKINIT int sigrtmax;
+#endif
+
+char *signalname(int signo) {
+	static char buf[16];
+
+	if ((unsigned)signo < NSIG && signal_names[signo])
+		return signal_names[signo];
+
+#if defined(SIGRTMIN) && defined(SIGRTMAX)
+	if (signo > sigrtmin && signo < sigrtmax) {
+		int last_rtmin_signo = sigrtmin + (sigrtmax - sigrtmin) / 2;
+		if (signo <= last_rtmin_signo)
+			fmtstr(buf, sizeof(buf), "RTMIN+%d", signo - sigrtmin);
+		else
+			fmtstr(buf, sizeof(buf), "RTMAX-%d", sigrtmax - signo);
+		return buf;
+	}
+#endif
+
+	fmtstr(buf, sizeof(buf), "%d", signo);
+	return buf;
+}
+
+#ifdef mkinit
+INIT {
+#define set_name(signo, name) if (signo < NSIG) signal_names[signo] = name
+	// 0 is no signal, but the trap command needs this to parse EXIT as 0.
+	set_name(0, "EXIT");
+
+	// Posix signals
+#if defined(SIGRTMIN) && defined(SIGRTMAX)
+	sigrtmin = SIGRTMIN;
+	set_name(sigrtmin, "RTMIN");
+	sigrtmax = SIGRTMAX;
+	set_name(sigrtmax, "RTMAX");
+#endif
+#ifdef SIGABRT
+	set_name(SIGABRT, "ABRT");
+#endif
+#ifdef SIGALRM
+	set_name(SIGALRM, "ALRM");
+#endif
+#ifdef SIGBUS
+	set_name(SIGBUS, "BUS");
+#endif
+#ifdef SIGCHLD
+	set_name(SIGCHLD, "CHLD");
+#endif
+#ifdef SIGCONT
+	set_name(SIGCONT, "CONT");
+#endif
+#ifdef SIGFPE
+	set_name(SIGFPE, "FPE");
+#endif
+#ifdef SIGHUP
+	set_name(SIGHUP, "HUP");
+#endif
+#ifdef SIGILL
+	set_name(SIGILL, "ILL");
+#endif
+#ifdef SIGINT
+	set_name(SIGINT, "INT");
+#endif
+#ifdef SIGKILL
+	set_name(SIGKILL, "KILL");
+#endif
+#ifdef SIGPIPE
+	set_name(SIGPIPE, "PIPE");
+#endif
+#ifdef SIGQUIT
+	set_name(SIGQUIT, "QUIT");
+#endif
+#ifdef SIGSEGV
+	set_name(SIGSEGV, "SEGV");
+#endif
+#ifdef SIGSTOP
+	set_name(SIGSTOP, "STOP");
+#endif
+#ifdef SIGTERM
+	set_name(SIGTERM, "TERM");
+#endif
+#ifdef SIGTSTP
+	set_name(SIGTSTP, "TSTP");
+#endif
+#ifdef SIGTTIN
+	set_name(SIGTTIN, "TTIN");
+#endif
+#ifdef SIGTTOU
+	set_name(SIGTTOU, "TTOU");
+#endif
+#ifdef SIGUSR1
+	set_name(SIGUSR1, "USR1");
+#endif
+#ifdef SIGUSR2
+	set_name(SIGUSR2, "USR2");
+#endif
+#ifdef SIGPOLL
+	set_name(SIGPOLL, "POLL");
+#endif
+#ifdef SIGPROF
+	set_name(SIGPROF, "PROF");
+#endif
+#ifdef SIGSYS
+	set_name(SIGSYS, "SYS");
+#endif
+#ifdef SIGTRAP
+	set_name(SIGTRAP, "TRAP");
+#endif
+#ifdef SIGURG
+	set_name(SIGURG, "URG");
+#endif
+#ifdef SIGVTALRM
+	set_name(SIGVTALRM, "VTALRM");
+#endif
+#ifdef SIGXCPU
+	set_name(SIGXCPU, "XCPU");
+#endif
+#ifdef SIGXFSZ
+	set_name(SIGXFSZ, "XFSZ");
+#endif
+
+	// Non-posix signals
+#ifdef SIGIO
+	set_name(SIGIO, "IO");
+#endif
+#ifdef SIGWINCH
+	set_name(SIGWINCH, "WINCH");
+#endif
+#ifdef SIGPWR
+	set_name(SIGPWR, "PWR");
+#endif
+#ifdef SIGINFO
+	set_name(SIGINFO, "INFO");
+#endif
+#ifdef SIGEMT
+	set_name(SIGEMT, "EMT");
+#endif
+}
+#endif
diff --git a/src/signalname.h b/src/signalname.h
new file mode 100644
index 0000000..1d8e238
--- /dev/null
+++ b/src/signalname.h
@@ -0,0 +1,4 @@
+// This file is in the Public Domain.
+
+// Returned string is valid until the next call to signalname.
+char *signalname(int signo);
diff --git a/src/trap.c b/src/trap.c
index cd84814..9f6bdb3 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -51,6 +51,7 @@
 #include "error.h"
 #include "trap.h"
 #include "mystring.h"
+#include "signalname.h"
 
 /*
  * Sigmode records the current value of the signal handlers for the various
@@ -78,8 +79,6 @@ volatile sig_atomic_t pending_sig;
 /* received SIGCHLD */
 volatile sig_atomic_t gotsigchld;
 
-extern char *signal_names[];
-
 static int decode_signum(const char *);
 
 #ifdef mkinit
@@ -127,7 +126,7 @@ trapcmd(int argc, char **argv)
 				out1fmt(
 					"trap -- %s %s\n",
 					single_quote(trap[signo]),
-					signal_names[signo]
+					signalname(signo)
 				);
 			}
 		}
@@ -429,7 +428,7 @@ int decode_signal(const char *string, int minsig)
 		return signo;
 
 	for (signo = minsig; signo < NSIG; signo++) {
-		if (!strcasecmp(string, signal_names[signo])) {
+		if (!strcasecmp(string, signalname(signo))) {
 			return signo;
 		}
 	}
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] Generate signal names at runtime
  2024-04-21 20:46 [PATCH] Generate signal names at runtime Henrik Lindström
@ 2024-04-27 11:47 ` Herbert Xu
  2024-04-27 19:44   ` Steffen Nurpmeso
  2024-04-29 16:28   ` Henrik Lindström
  0 siblings, 2 replies; 5+ messages in thread
From: Herbert Xu @ 2024-04-27 11:47 UTC (permalink / raw)
  To: Henrik Lindström; +Cc: dash, henrik

Henrik Lindström <henrik@lxm.se> wrote:
> They were previously generated at buildtime by mksignames.c, but that
> approach had two flaws:
> 1. The signal names were generated for the host system rather than the
>   target system, resulting in broken cross-compiled builds.
> 2. The SIGRTMIN and SIGRTMAX macros are usually implemented as
>   function calls and can only be surely known at runtime.
> 
> The new implementation has been tested to generate identical signal names
> as before on these systems:
> * Debian 12 (glibc, odd number of realtime signals)
> * Alpine 3.18 (musl, even number of realtime signals)
> * FreeBSD 14
> 
> Signed-off-by: Henrik Lindström <henrik@lxm.se>

Now that glibc has sigabbrev_np we should switch to using that
on Linux, perhaps with the existing code as a fallback.  BSD
has always had ways of getting the signal name, though it may
not be very portable so we'd need different flavours if people
cared enough to add them.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Generate signal names at runtime
  2024-04-27 11:47 ` Herbert Xu
@ 2024-04-27 19:44   ` Steffen Nurpmeso
  2024-04-29 16:28   ` Henrik Lindström
  1 sibling, 0 replies; 5+ messages in thread
From: Steffen Nurpmeso @ 2024-04-27 19:44 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Henrik Lindström, dash

[-- Attachment #1: Type: text/plain, Size: 1852 bytes --]

Just in case of interest..

Herbert Xu wrote in
 <Zizl53et9J5Hg2D5@gondor.apana.org.au>:
 |Henrik Lindström <henrik@lxm.se> wrote:
 |> They were previously generated at buildtime by mksignames.c, but that
 |> approach had two flaws:
 |> 1. The signal names were generated for the host system rather than the
 |>   target system, resulting in broken cross-compiled builds.
 |> 2. The SIGRTMIN and SIGRTMAX macros are usually implemented as
 |>   function calls and can only be surely known at runtime.
 |> 
 |> The new implementation has been tested to generate identical signal names
 |> as before on these systems:
 |> * Debian 12 (glibc, odd number of realtime signals)
 |> * Alpine 3.18 (musl, even number of realtime signals)
 |> * FreeBSD 14
 |> 
 |> Signed-off-by: Henrik Lindström <henrik@lxm.se>
 |
 |Now that glibc has sigabbrev_np we should switch to using that
 |on Linux, perhaps with the existing code as a fallback.  BSD
 |has always had ways of getting the signal name, though it may
 |not be very portable so we'd need different flavours if people
 |cared enough to add them.

I can only offer a script of mine again which does this for me.
It does more as my MUA can do things like "echo $^ERRDOC-42" ->
"No message of desired type", "echo $^ERRNAME-42" -> "NOMSG",
"echo $^ERR-NOMSG" -> "42", etc, but is a solid foundation base
for whatever dash would need.
It needs perl (tarball time) and $CC and $awk at compile time.
It is portable (Linux, BSD, SunOS/Solaris [with right sh(1) and
awk(1)]).  What you want is likely a variation of

  TARGET=/tmp/errlist sh mk/su-make-signals.sh compile_time

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

[-- Attachment #2: su-make-signals.sh --]
[-- Type: text/x-shellscript, Size: 12821 bytes --]

#!/bin/sh -
#@ Either create src/su/gen-signals.h, or, at compile time, the OS<>SU map.
#
# Public Domain

IN="${SRCDIR}"su/gen-signals.h
XOUT=src/su/gen-signals.h

# We use `csop' for hashing
MAILX='LC_ALL=C s-nail -#:/'

# Acceptable "longest distance" from hash-modulo-index to key
MAXDISTANCE_PENALTY=6

# Generate a more verbose output.  Not for shipout versions.
VERB=1

##

LC_ALL=C
export LC_ALL MAXDISTANCE_PENALTY VERB MAILX IN XOUT

: ${awk:=awk}
# Compile-time only
: ${rm:=rm}
: ${sort:=sort}

# The set of signals we support {{{
SIGNALS="
	NONE='No signal' \
	ABRT='Abort signal' \
	ALRM='Timer signal' \
	BUS='Bus error (bad memory access)' \
	CHLD='Child stopped or terminated' \
	CLD='Child stopped or terminated' \
	CONT='Continue process if stopped' \
	EMT='Emulator trap' \
	FPE='Floating-point exception' \
	HUP='Hangup of controlling terminal, or death of controlling process' \
	ILL='Illegal instruction' \
	INFO='Power failure' \
	INT='Interrupt from keyboard' \
	IO='I/O now possible' \
	IOT='IOT trap / abort signal' \
	KILL='Kill signal' \
	LOST='File lock lost' \
	PIPE='Broken pipe: write to pipe with no readers' \
	POLL='Pollable event' \
	PROF='Profiling timer expired' \
	PWR='Power failure' \
	QUIT='Quit from keyboard' \
	SEGV='Segementation violation: invalid memory reference' \
	STKFLT='Stack fault on coprocessor' \
	STOP='Stop process' \
	TSTP='Stop from terminal' \
	SYS='Bad system call' \
	TERM='Termination signal' \
	TRAP='Trace or breakpoint trap' \
	TTIN='Terminal input for background process' \
	TTOU='Terminal output from background process' \
	UNUSED='Bad system call' \
	URG='Urgent condition on socket' \
	USR1='User-defined signal 1' \
	USR2='User-defined signal 2' \
	VTALRM='Virtual alarm clock' \
	XCPU='CPU time limit exceeded' \
	XFSZ='File size limit exceeded' \
	WINCH='Window resize signal' \
"
export SIGNALS
# }}}

signal_parse() {
	j=\'
	${awk} -v dodoc="${1}" -v incnone="${2}" -v input="${SIGNALS}" '
		BEGIN{
			for(i = 0;;){
				voff = match(input, /[0-9a-zA-Z_]+(='${j}'[^'${j}']+)?/)
				if(voff == 0)
					break
				v = substr(input, voff, RLENGTH)
				input = substr(input, voff + RLENGTH)
				doff = index(v, "=")
				if(doff > 0){
					d = substr(v, doff + 2, length(v) - doff - 1)
					v = substr(v, 1, doff - 1)
				}
				if(!incnone && v == "NONE")
					continue
				print dodoc ? d : v
			}
		}
	'
}

compile_time() { # {{{
	[ -n "${TARGET}" ] || {
		echo >&2 'Invalid usage'
		exit 1
	}
	set -e
	pipefail=
	( set -o pipefail ) >/dev/null 2>&1 && pipefail=y
	[ -n "${pipefail}" ] && set -o pipefail

	{
		printf '#include <signal.h>\nsu_SIGNAL_START\n'
		for n in $(signal_parse 0 0); do
			printf '#ifdef SIG%s\nSIG%s "%s"\n#else\n-1 "%s"\n#endif\n' $n $n $n $n
		done
	} > "${TARGET}".c

	# The problem is that at least (some versions of) gcc mangle output.
	# Ensure we get both arguments on one line.
	# While here sort numerically.
	${CC} -E "${TARGET}".c |
		${awk} '
			function stripsym(sym){
				sym = substr(sym, 2)
				sym = substr(sym, 1, length(sym) - 1)
				return sym
			}
			BEGIN{hot=0; conti=0}
			/^[	 ]*$/{next}
			/^[	 ]*#/{next}
			/^su_SIGNAL_START$/{hot=1; next}
			{
				if(!hot)
					next
				i = conti ? stripsym($1) "\n" : $1 " "
				printf i
				if(conti)
					conti = 0
				else if($2 != "")
					printf "%s\n", stripsym($2)
				else
					conti = 1
			}
		' |
		${sort} -n > "${TARGET}".txt

	# EBCDIC/ASCII: we use \134 for reverse solidus \
	j=\'
	${awk} -v verb="${VERB}" -v input="${SIGNALS}" -v dat="${TARGET}.txt" '
		BEGIN{
			verb = (verb != 0) ? "	" : ""

			# Read in our OS data

			unavail = 0
			max = 0
			oscnt = 0
			while((getline dl < dat) > 0){
				split(dl, ia)

				++oscnt
				osnoa[oscnt] = ia[1]
				osnaa[oscnt] = ia[2]

				if(ia[1] < 0)
					++unavail
				else{
					if(ia[1] > max)
						max = ia[1]
				}
			}
			close(dat)

			# Maximum signal number defines the datatype to use.
			# we warp all non-available errors to numbers too high
			# to be regular errors, counting backwards

			i = max + unavail + 1
			if(i >= 65535){
				t = "u32"
				max = "0xFFFFFFFFu"
			}else if(i >= 255){
				t = "u16"
				max = "0xFFFFu"
			}else{
				t = "u8"
				max = "0xFFu"
			}
			print "#define su__SIG_NUMBER_TYPE " t
			print "#define su__SIG_NUMBER_MAX " max

			# Dump C table

			cnt = 0
			print "#define su__SIG_NUMBER_ENUM_C \134"

			print verb "su_SIG_NONE = 0,\134"
			++cnt

			# Since our final table is searched with binary sort,
			# place the non-available backward counting once last
			unavail = j = k = 0
			for(i = 1; i <= oscnt; ++i){
				if(osnoa[i] >= 0){
					map[osnaa[i]] = osnoa[i]
					print verb "su_SIG_" osnaa[i] " = " osnoa[i] ",\134"
					++cnt
				}else{
					++unavail
					the_unavail[unavail] = "su_SIG_" osnaa[i] " = " "(su__SIG_NUMBER_MAX - " unavail ")"
				}
			}
			for(i = unavail; i >= 1; --i){
				print verb the_unavail[i] ",\134"
				++cnt
			}

			print verb "su__SIG_NUMBER = " cnt

			# The C++ mapping table

			print "#ifdef __cplusplus"
			print "# define su__CXX_SIG_NUMBER_ENUM \134"
			print verb "none = su_SIG_NONE,\134"

			unavail = 0
			for(i = 1; i <= oscnt; ++i){
				cxxn = tolower(osnaa[i])
				if(cxxn !~ "^[_[:alpha:]]")
					cxxn = "s" cxxn
				if(osnoa[i] >= 0)
					print verb cxxn " = su_SIG_" osnaa[i] ",\134"
				else{
					++unavail
					the_unavail[unavail] = cxxn " = su_SIG_" osnaa[i]
				}
			}
			for(i = unavail; i >= 1; --i){
				print verb the_unavail[i] ",\134"
				++cnt
			}
			print verb "s__number = su__SIG_NUMBER"

			print "#endif /* __cplusplus */"

			# And our OS signal -> name map offset table
			# (This "OS" however includes the unavail ones)

			voidoff = 0
			for(mapoff = 0;; ++mapoff){
				voff = match(input, /[0-9a-zA-Z_]+(='${j}'[^'${j}']+)?/)
				if(voff == 0)
					break

				v = substr(input, voff, RLENGTH)
				input = substr(input, voff + RLENGTH)
				doff = index(v, "=")
				if(doff > 0){
					d = substr(v, doff + 2, length(v) - doff - 1)
					v = substr(v, 1, doff - 1)
				}
				mapo[v] = mapoff
				if(v == "UNUSED")
					voidoff = mapoff
			}

			uniq = 0
			print "#define su__SIG_NUMBER_VOIDOFF " voidoff
			print "#define su__SIG_NUMBER_TO_MAPOFF \134"

			print verb "a_X(0, 0) \134"
			++uniq

			unavail = 0
			mapdups[0] = 1
			for(i = 1; i <= oscnt; ++i){
				if(osnoa[i] < 0){
					the_unavail[++unavail] = i
					continue
				}
				if(mapdups[osnoa[i]])
					continue
				mapdups[osnoa[i]] = 1
				print verb "a_X(" osnoa[i] ", " mapo[osnaa[i]] ") \134"
				++uniq
			}

			for(i = unavail; i >= 1; --i){
				print verb "a_X(" "su__SIG_NUMBER_MAX - " i ", " mapo[osnaa[the_unavail[i]]] ")\134"
				++uniq
			}

			print verb "a_X(su__SIG_NUMBER_MAX, su__SIG_NUMBER_VOIDOFF) \134"
			++uniq
			print verb "/* " uniq " unique members */"
		}
	' >> "${TARGET}"

	${rm} "${TARGET}".*
	exit 0
} # }}}

if [ ${#} -ne 0 ]; then
	if [ "${1}" = noverbose ]; then
		shift
		VERB=0
		export VERB
	fi
fi

if [ ${#} -eq 1 ]; then
	[ "${1}" = compile_time ] && compile_time
elif [ ${#} -eq 0 ]; then
	# Now start perl(1) without PERL5OPT set to avoid multibyte sequence errors
	PERL5OPT= PERL5LIB= exec perl -x "${0}"
fi
echo >&2 'Invalid usage'
exit 1

#' PERL {{{
# Thanks to perl(5) and its -x / #! perl / __END__ mechanism!
# Why can env(1) not be used for such easy things in #!?
#!perl

use strict;
use warnings;

use FileHandle;
use IPC::Open2;

use sigtrap qw(handler cleanup normal-signals);

my ($S, @ENTS, $CTOOL, $CTOOL_EXE) = ($ENV{VERB} ? '	' : '');

sub main_fun{
	create_ents();

	create_c_tool();

	hash_em();

	dump_map(); # Starts output file

	reverser(); # Ends output file

	cleanup(undef);
	exit 0
}

sub cleanup{
	die "$CTOOL_EXE: couldn't unlink: $^E" if $CTOOL_EXE && -f $CTOOL_EXE && 1 != unlink $CTOOL_EXE;
	die "$CTOOL: couldn't unlink: $^E" if $CTOOL && -f $CTOOL && 1 != unlink $CTOOL;
	die "Terminating due to signal $_[0]" if $_[0]
}

sub basen{
	my $n = $_[0];
	$n =~ s/^(.*\/)?([^\/]+)$/$2/;
	$n
}

sub create_ents{
	my $input = $ENV{SIGNALS};
	while($input =~ /([[:alnum:]_]+)='([^']+)'(.*)/){
		$input = $3;
		my %vals;
		$vals{name} = $1;
		$vals{doc} = $2;
		push @ENTS, \%vals
	}
}

sub create_c_tool{
	$CTOOL = './tmp-signals-tool-' . $$ . '.c';
	$CTOOL_EXE = $CTOOL . '.exe';

	die "$CTOOL: open: $^E" unless open F, '>', $CTOOL;
	print F '#define MAX_DISTANCE_PENALTY ', $ENV{MAXDISTANCE_PENALTY}, "\n";
# >>>>>>>>>>>>>>>>>>>
	print F <<'_EOT';
#define __CREATE_SIGNALS_SH
#define su_SOURCE
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define su_NELEM(A) (sizeof(A) / sizeof((A)[0]))

#define u32 uint32_t
#define s32 int32_t
#define u16 uint16_t
#define u8 uint8_t

struct a_corsig_map{
	u32 csm_hash; /* Hash of name */
	u32 csm_nameoff; /* Into a_corsig_names[] */
	u32 csm_docoff; /* Into a_corsig_docs[] */
	s32 csm_errno;	 /* OS signal value for this one */
};

_EOT

	print F '#include "', $ENV{XOUT}, "\"\n\n";

	print F <<'_EOT';
static u8 seen_wraparound;
static size_t longest_distance;

static size_t
next_prime(size_t no){ /* blush (brute force) */
jredo:
	++no;
	for(size_t i = 3; i < no; i += 2)
		if(no % i == 0)
			goto jredo;
	return no;
}

static size_t *
reversy(size_t size){
	struct a_corsig_map const *csmp = a_corsig_map, *csmaxp = csmp + su_NELEM(a_corsig_map);
	size_t ldist = 0, *arr;

	arr = (size_t*)malloc(sizeof *arr * size);
	for(size_t i = 0; i < size; ++i)
		arr[i] = su_NELEM(a_corsig_map);

	seen_wraparound = 0;
	longest_distance = 0;

	while(csmp < csmaxp){
		u32 hash = csmp->csm_hash, i = hash % size, l;

		for(l = 0; arr[i] != su_NELEM(a_corsig_map); ++l)
			if(++i == size){
				seen_wraparound = 1;
				i = 0;
			}
		if(l > longest_distance)
			longest_distance = l;
		arr[i] = (size_t)(csmp++ - a_corsig_map);
	}
	return arr;
}

int
main(int argc, char **argv){
	size_t *arr, size = su_NELEM(a_corsig_map);

	fprintf(stderr, "Starting reversy, okeys=%zu\n", size);
	for(;;){
		arr = reversy(size = next_prime(size));
		fprintf(stderr, " - size=%zu longest_distance=%zu seen_wraparound=%d\n",
			size, longest_distance, seen_wraparound);
		if(longest_distance <= MAX_DISTANCE_PENALTY)
			break;
		free(arr);
	}

	printf(
		"#ifdef su_SOURCE /* Lock-out compile-time-tools */\n"
		"# define a_CORSIG_REV_ILL %zuu\n"
		"# define a_CORSIG_REV_PRIME %zuu\n"
		"# define a_CORSIG_REV_LONGEST %zuu\n"
		"# define a_CORSIG_REV_WRAPAROUND %d\n"
		"static %s const a_corsig_revmap[a_CORSIG_REV_PRIME] = {\n%s",
		su_NELEM(a_corsig_map), size, longest_distance, seen_wraparound,
		argv[1], (argc > 2 ? "	" : ""));
	for(size_t i = 0; i < size; ++i)
		printf("%s%zuu", (i == 0 ? "" : (i % 10 == 0 ? (argc > 2 ? ",\n	" : ",\n") : (argc > 2 ? ", " : ","))),
			arr[i]);
	printf("\n};\n#endif /* su_SOURCE */\n");
	return 0;
}
_EOT
# <<<<<<<<<<<<<<<<<<<
	close F
}

sub hash_em{
	die "hash_em: open: $^E" unless my $pid = open2 *RFD, *WFD, $ENV{MAILX};
	foreach my $e (@ENTS){
		print WFD "csop hash32?case $e->{name}\n";
		my $h = <RFD>;
		chomp $h;
		$e->{hash} = $h
	}
	print WFD "x\n";
	waitpid $pid, 0;
}

sub dump_map{
	my ($i, $alen);

	die "$ENV{XOUT}: open: $^E" unless open F, '>', $ENV{XOUT};
	print F '/*@ ', scalar basen($ENV{XOUT}), ', generated by ', scalar basen($0),
		".\n *@ See core-signals.c for more */\n\n";

	($i, $alen) = (0, 0);
	print F '#ifdef su_SOURCE', "\n", 'static char const a_corsig_names[] = {', "\n";
	($i, $alen) = (0, 0);
	foreach my $e (@ENTS){
		$e->{nameoff} = $alen;
		my $k = $e->{name};
		my $l = length $k;
		my $a = join '\',\'', split(//, $k);
		my (@fa);
		print F "${S}/* $i. [$alen]+$l $k */\n" if $ENV{VERB};
		print F "${S}'$a','\\0',\n";
		++$i;
		$alen += $l + 1
	}
	print F '};', "\n\n";

	print F '# undef a_X', "\n", '# define a_X(X)', "\n";
	print F 'static char const a_corsig_docs[] = {', "\n";
	($i, $alen) = (0, 0);
	foreach my $e (@ENTS){
		$e->{docoff} = $alen;
		my $k = $e->{doc};
		my $l = length $k;
		my $a = join '\',\'', split(//, $k);
		my (@fa);
		print F "${S}/* $i. [$alen]+$l $e->{name} */ ", "a_X(N_(\"$e->{doc}\"))\n" if $ENV{VERB};
		print F "${S}'$a','\\0',\n";
		++$i;
		$alen += $l + 1
	}
	print F '};', "\n# undef a_X\n\n";

	print F <<_EOT;
# undef a_X
# ifndef __CREATE_SIGNALS_SH
#  define a_X(X) X
# else
#  define a_X(X) 0
# endif
static struct a_corsig_map const a_corsig_map[] = {
_EOT
	foreach my $e (@ENTS){
		print F "${S}{$e->{hash}u, $e->{nameoff}u, $e->{docoff}u, a_X(su_SIG_$e->{name})},\n"
	}
	print F '};', "\n", '# undef a_X', "\n",
		'#endif /* su_SOURCE */', "\n\n";

	die "$ENV{XOUT}: close: $^E" unless close F
}

sub reverser{
	my $argv2 = $ENV{VERB} ? ' verb' : '';
	system("\$CC -I. -o $CTOOL_EXE $CTOOL");
	my $t = (@ENTS < 0xFF ? 'u8' : (@ENTS < 0xFFFF ? 'u16' : 'u32'));
	`$CTOOL_EXE $t$argv2 >> $ENV{XOUT}`
}

{package main; main_fun()}
# }}}

# s-itt-mode

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Generate signal names at runtime
  2024-04-27 11:47 ` Herbert Xu
  2024-04-27 19:44   ` Steffen Nurpmeso
@ 2024-04-29 16:28   ` Henrik Lindström
  2024-04-29 17:17     ` Steffen Nurpmeso
  1 sibling, 1 reply; 5+ messages in thread
From: Henrik Lindström @ 2024-04-29 16:28 UTC (permalink / raw)
  To: Herbert Xu; +Cc: dash

Getting the names from libc sounds ideal, but i don't think there's any way
to do that with musl, which is what i'm trying to cross compile to. That's
why i attempted a more universal solution in my patch, but perhaps there
would be interest in musl to add sigabbrev_np instead.

As for a fallback, shouldn't the goal be something more similar to my
attempt rather than the existing code? Silently building a broken version
of dash when cross compiling isn't ideal.

Thanks
Henrik

On 2024-04-27 13:47, Herbert Xu wrote:
> Henrik Lindström <henrik@lxm.se> wrote:
>> They were previously generated at buildtime by mksignames.c, but that
>> approach had two flaws:
>> 1. The signal names were generated for the host system rather than the
>>   target system, resulting in broken cross-compiled builds.
>> 2. The SIGRTMIN and SIGRTMAX macros are usually implemented as
>>   function calls and can only be surely known at runtime.
>>
>> The new implementation has been tested to generate identical signal names
>> as before on these systems:
>> * Debian 12 (glibc, odd number of realtime signals)
>> * Alpine 3.18 (musl, even number of realtime signals)
>> * FreeBSD 14
>>
>> Signed-off-by: Henrik Lindström <henrik@lxm.se>
> 
> Now that glibc has sigabbrev_np we should switch to using that
> on Linux, perhaps with the existing code as a fallback.  BSD
> has always had ways of getting the signal name, though it may
> not be very portable so we'd need different flavours if people
> cared enough to add them.
> 
> Thanks,

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Generate signal names at runtime
  2024-04-29 16:28   ` Henrik Lindström
@ 2024-04-29 17:17     ` Steffen Nurpmeso
  0 siblings, 0 replies; 5+ messages in thread
From: Steffen Nurpmeso @ 2024-04-29 17:17 UTC (permalink / raw)
  To: Henrik Lindström; +Cc: Herbert Xu, dash

Henrik Lindström wrote in
 <d28c0015-3fff-412a-bdb2-39cae101e57f@lxm.se>:
 |Getting the names from libc sounds ideal, but i don't think there's any way
 |to do that with musl, which is what i'm trying to cross compile to. That's
 |why i attempted a more universal solution in my patch, but perhaps there
 |would be interest in musl to add sigabbrev_np instead.
 |
 |As for a fallback, shouldn't the goal be something more similar to my
 |attempt rather than the existing code? Silently building a broken version
 |of dash when cross compiling isn't ideal.

People, adjust that fucking if that is possible on an american
list script of mine (or take it as-is), it requires nothing but
a C compiler (preprocessor) and POSIX (Solaris: xpg4) tools, and
it generates a superset of exactly what you want.  Bug reports
welcome.  I have the same for errno values, too.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-04-29 17:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-21 20:46 [PATCH] Generate signal names at runtime Henrik Lindström
2024-04-27 11:47 ` Herbert Xu
2024-04-27 19:44   ` Steffen Nurpmeso
2024-04-29 16:28   ` Henrik Lindström
2024-04-29 17:17     ` Steffen Nurpmeso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.