Skip to content

Commit

Permalink
Improve input preprocessor failure diagnostics (#328)
Browse files Browse the repository at this point in the history
This fixes gwsw/less issue #327.
* configure.ac: Check for sys/wait.h and for strsignal.
* edit.c: Include <sys/wait.h> if available.
(close_pipe): Always diagnose internal error with pclose.
On POSIX-compatible systems, generate better diagnostics
that distinguish between ordinary exit and signals,
and do not diagnose SIGPIPE after the user types 'q'
as that is normal and expected.
* os.c (signal_message): New function.
  • Loading branch information
eggert committed Jan 28, 2023
1 parent 4985c07 commit ccf09b6
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ AC_CHECK_LIB(termlib, tgetent, [have_termlib=yes], [have_termlib=no])
AC_SEARCH_LIBS([regcmp], [gen intl PW])

# Checks for header files.
AC_CHECK_HEADERS_ONCE([ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h linux/magic.h sys/ioctl.h sys/stream.h sys/types.h time.h wctype.h])
AC_CHECK_HEADERS_ONCE([ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h linux/magic.h sys/ioctl.h sys/stream.h sys/types.h sys/wait.h time.h wctype.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STAT
Expand Down Expand Up @@ -264,7 +264,7 @@ AC_MSG_CHECKING(for ANSI function prototypes)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[int f(int a) { return a; }]])],[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_ANSI_PROTOS)],[AC_MSG_RESULT(no)])

# Checks for library functions.
AC_CHECK_FUNCS([fchmod fsync nanosleep poll popen realpath _setjmp sigprocmask sigsetmask snprintf stat system ttyname usleep])
AC_CHECK_FUNCS([fchmod fsync nanosleep poll popen realpath _setjmp sigprocmask sigsetmask snprintf stat strsignal system ttyname usleep])

# AC_CHECK_FUNCS may not work for inline functions, so test these separately.
AC_MSG_CHECKING(for memcpy)
Expand Down
36 changes: 34 additions & 2 deletions edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#if HAVE_STAT
#include <sys/stat.h>
#endif
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#if OS2
#include <signal.h>
#endif
Expand Down Expand Up @@ -262,6 +265,7 @@ static void check_modelines(void)
static void close_pipe(FILE *pipefd)
{
int status;
PARG parg;

if (pipefd == NULL)
return;
Expand All @@ -273,9 +277,37 @@ static void close_pipe(FILE *pipefd)
kill(pipefd->_pid, SIGINT);
#endif
status = pclose(pipefd);
if (status != 0 && show_preproc_error)
if (status == -1)
{
PARG parg;
/* An internal error in 'less', not a preprocessor error. */
parg.p_string = errno_message("pclose");
error("%s", &parg);
free(parg.p_string);
return;
}
if (!show_preproc_error)
return;
#if defined WIFEXITED && defined WEXITSTATUS
if (WIFEXITED(status)) {
int s = WEXITSTATUS(status);
if (s != 0) {
parg.p_int = s;
error("Input preprocessor failed (status %d)", &parg);
}
return;
}
#endif
#if defined WIFSIGNALED && defined WTERMSIG && HAVE_STRSIGNAL
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
if (sig != SIGPIPE || ch_length() != NULL_POSITION) {
parg.p_string = signal_message(sig);
error("Input preprocessor terminated: %s", &parg);
}
return;
}
#endif
if (status != 0) {
parg.p_int = status;
error("Input preprocessor exited with status %x", &parg);
}
Expand Down
16 changes: 16 additions & 0 deletions os.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,22 @@ public char * errno_message(char *filename)
return (m);
}

/*
* Return a description of a signal.
* The return value is good until the next call to this function.
*/
public char * signal_message(int sig)
{
static char sigbuf[sizeof "signal " + INT_STRLEN_BOUND(sig)];
#if HAVE_STRSIGNAL
char *description = strsignal(sig);
if (description)
return description;
#endif
sprintf(sigbuf, "Signal %d", sig);
return sigbuf;
}

/* #define HAVE_FLOAT 0 */

static POSITION muldiv(POSITION val, POSITION num, POSITION den)
Expand Down

0 comments on commit ccf09b6

Please sign in to comment.