Bug#1108971: bash: computes wrong PIPESIZE during some cross builds
Source: bash
Version: 5.2.37-2
Tags: patch upstream
User: helmutg@debian.org
Usertags: rebootstrap
X-Debbugs-Cc: sthibault@debian.org, debian-cross@lists.debian.org
bash has a weired way to compute PIPESIZE. It's a property of the
kernel, but it is not being checked for during ./configure. Instead the
builtins/Makefile.in compiles a builtins/psize.c (using CC_FOR_BUILD)
and runs a builtins/psize.sh to create a pipesize.h #defining PIPESIZE.
It even has a comment noting that this gets the value for the build
architecture while it should be getting it from the host.
Turns out if you cross build bash for hurd on linux you get the wrong
value in such a way that it practically doesn't work. It would be good
if we could preseed this value rather than having it use something bad.
I argue that it really should be a configure time check with a proper
autoconf cache variable allowing overriding and that's exactly what the
attached patch does. What do you think about it?
Of course this is not trixie material.
Helmut and Samuel
--- bash-5.2.37.orig/aclocal.m4
+++ bash-5.2.37/aclocal.m4
@@ -2265,3 +2265,87 @@
fi
AC_DEFINE_UNQUOTED([FNMATCH_EQUIV_FALLBACK], [$bash_cv_fnmatch_equiv_value], [Whether fnmatch can be used for bracket equivalence classes])
])
+AC_DEFUN(BASH_PIPESIZE,
+[AC_CACHE_CHECK([for PIPESIZE], bash_cv_pipesize,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+/* Write output in 128-byte chunks until we get a sigpipe or write gets an
+ EPIPE. Then report how many bytes we wrote. We assume that this is the
+ pipe size. */
+#if defined (HAVE_UNISTD_H)
+# ifndef _MINIX
+# include <unistd.h>
+# endif
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <signal.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+FILE *output;
+int nw;
+
+void sigpipe (int sig)
+{
+ fprintf (output, "%d\n", nw);
+ fclose (output);
+ exit (0);
+}
+
+int main (int argc, char **argv)
+{
+ char buf[128];
+ int pipes[2];
+ int pid;
+ register int i;
+
+ if (pipe(pipes) < 0)
+ return (1);
+
+ output = fopen("conftest.val", "w");
+
+ if (output == NULL)
+ return (1);
+
+ for (i = 0; i < 128; i++)
+ buf[i] = ' ';
+
+ pid = fork();
+ if (pid < 0)
+ return (1);
+ if (pid == 0)
+ {
+ close(pipes[1]);
+ sleep(3);
+ return 0;
+ }
+ close(pipes[0]);
+
+ signal (SIGPIPE, sigpipe);
+
+ nw = 0;
+ for (;;)
+ {
+ int n;
+ n = write (pipes[1], buf, 128);
+ nw += n;
+ }
+ return (1);
+}
+]])],
+[
+ bash_cv_pipesize=`cat conftest.val`
+ test "x$bash_cv_pipesize" = x && bash_cv_pipesize=error
+],
+[bash_cv_pipesize=failed],
+[bash_cv_pipesize=cross]
+)
+])
+AS_IF([test "$bash_cv_pipesize" = failed || test "$bash_cv_pipesize" = cross || test "$bash_cv_pipesize" = error],[PIPESIZE=512],[PIPESIZE=$bash_cv_pipesize])
+AC_SUBST(PIPESIZE)
+])
--- bash-5.2.37.orig/configure.ac
+++ bash-5.2.37/configure.ac
@@ -1125,6 +1125,7 @@
BASH_CHECK_DEV_FD
BASH_CHECK_DEV_STDIN
BASH_SYS_DEFAULT_MAIL_DIR
+BASH_PIPESIZE
if test "$bash_cv_job_control_missing" = missing; then
opt_job_control=no
--- bash-5.2.37.orig/Makefile.in
+++ bash-5.2.37/Makefile.in
@@ -761,9 +761,6 @@
${DEFDIR}/builtext.h: $(BUILTIN_DEFS)
@(cd $(DEFDIR) && $(MAKE) $(MFLAGS) builtext.h ) || exit 1
-${DEFDIR}/pipesize.h: ${BUILTINS_LIBRARY}
- @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) pipesize.h ) || exit 1
-
$(SDIR)/man2html$(EXEEXT): ${SUPPORT_SRC}/man2html.c
@(cd $(SDIR) && $(MAKE) $(MFLAGS) all ) || exit 1
@@ -1169,7 +1166,6 @@
redir.o: general.h xmalloc.h variables.h arrayfunc.h conftypes.h array.h hashlib.h quit.h ${BASHINCDIR}/maxpath.h unwind_prot.h
redir.o: dispose_cmd.h make_cmd.h subst.h sig.h pathnames.h externs.h
redir.o: flags.h execute_cmd.h redir.h input.h
-redir.o: ${DEFDIR}/pipesize.h
redir.o: trap.h assoc.h $(BASHINCDIR)/ocache.h $(BASHINCDIR)/chartypes.h
shell.o: config.h bashtypes.h ${BASHINCDIR}/posixstat.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/filecntl.h
shell.o: shell.h syntax.h config.h bashjmp.h ${BASHINCDIR}/posixjmp.h command.h ${BASHINCDIR}/stdc.h error.h
--- bash-5.2.37.orig/builtins/Makefile.in
+++ bash-5.2.37/builtins/Makefile.in
@@ -158,7 +158,7 @@
suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o
-CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h tmpbuiltins.c \
+CREATED_FILES = builtext.h builtins.c tmpbuiltins.c \
tmpbuiltins.h
CREATED_OBJECTS = tmpbuiltins.o gen-helpfiles.o mkbuiltins.o
@@ -237,16 +237,6 @@
tmpbuiltins.o: tmpbuiltins.c
gen-helpfiles.o: gen-helpfiles.c
-ulimit.o: pipesize.h
-
-pipesize.h: psize.aux
- $(SHELL) $(srcdir)/psize.sh > $@
-
-# Technically this is wrong; the pipe size should be for the target system,
-# not the build host.
-psize.aux: psize.c
- $(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) ${LDFLAGS_FOR_BUILD} -o $@ $(srcdir)/psize.c
-
documentation: builtins.texi
builtins.texi: $(MKBUILTINS)
--- bash-5.2.37.orig/builtins/psize.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* psize.c - Find pipe size. */
-
-/* Copyright (C) 1987, 1991 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Write output in 128-byte chunks until we get a sigpipe or write gets an
- EPIPE. Then report how many bytes we wrote. We assume that this is the
- pipe size. */
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-# ifdef _MINIX
-# include <sys/types.h>
-# endif
-# include <unistd.h>
-#endif
-
-#include <stdio.h>
-#ifndef _MINIX
-#include "../bashtypes.h"
-#endif
-#include <signal.h>
-#include <errno.h>
-
-#include "../command.h"
-#include "../general.h"
-#include "../sig.h"
-
-#ifndef errno
-extern int errno;
-#endif
-
-int nw;
-
-sighandler
-sigpipe (sig)
- int sig;
-{
- fprintf (stderr, "%d\n", nw);
- exit (0);
-}
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- char buf[128];
- register int i;
-
- for (i = 0; i < 128; i++)
- buf[i] = ' ';
-
- signal (SIGPIPE, sigpipe);
-
- nw = 0;
- for (;;)
- {
- int n;
- n = write (1, buf, 128);
- nw += n;
- }
- return (0);
-}
--- bash-5.2.37.orig/builtins/ulimit.def
+++ bash-5.2.37/builtins/ulimit.def
@@ -92,7 +92,6 @@
#include "../shell.h"
#include "common.h"
#include "bashgetopt.h"
-#include "pipesize.h"
#if !defined (errno)
extern int errno;
--- bash-5.2.37.orig/config.h.in
+++ bash-5.2.37/config.h.in
@@ -243,6 +243,9 @@
#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail"
+/* The amount of bytes one can write to a pipe(2) before it blocks. */
+#undef PIPESIZE
+
/* Characteristics of the system's header files and libraries that affect
the compilation environment. */
--- bash-5.2.37.orig/redir.c
+++ bash-5.2.37/redir.c
@@ -58,8 +58,6 @@
# include "input.h"
#endif
-#include "builtins/pipesize.h"
-
/* FreeBSD 13 can reliably handle atomic writes at this capacity without
hanging. */
#if __FreeBSD__ && !defined (HEREDOC_PIPESIZE)
--- bash-5.2.37.orig/builtins/psize.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /bin/sh
-#
-# psize.sh -- determine this system's pipe size, and write a define to
-# pipesize.h so ulimit.c can use it.
-
-: ${TMPDIR:=/tmp}
-# try to use mktemp(1) if the system supports it
-{ TMPFILE="`mktemp $TMPDIR/pipsize.XXXXXX 2>/dev/null`"; } 2>/dev/null
-used_mktemp=true
-
-if [ -z "$TMPFILE" ]; then
- TMPNAME=pipsize.$$
- TMPFILE=$TMPDIR/$TMPNAME
- used_mktemp=false
-fi
-
-trap 'rm -f "$TMPFILE" ; exit 1' 1 2 3 6 15
-trap 'rm -f "$TMPFILE"' 0
-
-echo "/*"
-echo " * pipesize.h"
-echo " *"
-echo " * This file is automatically generated by psize.sh"
-echo " * Do not edit!"
-echo " */"
-echo ""
-
-#
-# Try to avoid tempfile races. We can't really check for the file's
-# existence before we run psize.aux, because `test -e' is not portable,
-# `test -h' (test for symlinks) is not portable, and `test -f' only
-# checks for regular files. If we used mktemp(1), we're ahead of the
-# game.
-#
-$used_mktemp || rm -f "$TMPFILE"
-
-./psize.aux 2>"$TMPFILE" | sleep 3
-
-if [ -s "$TMPFILE" ]; then
- echo "#define PIPESIZE `cat "$TMPFILE"`"
-else
- echo "#define PIPESIZE 512"
-fi
-
-exit 0
Reply to: