From: Todd C. Miller Date: Mon, 13 Mar 2017 18:11:51 +0000 (-0600) Subject: Emulate pipe2() on systems without it. X-Git-Tag: SUDO_1_8_20^2~78 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7aa89c49b53b700dc504acd33bd48d3ac76eccb6;p=sudo Emulate pipe2() on systems without it. --- diff --git a/MANIFEST b/MANIFEST index bf9b19346..d2debad5b 100644 --- a/MANIFEST +++ b/MANIFEST @@ -109,6 +109,7 @@ lib/util/mksigname.h lib/util/mktemp.c lib/util/nanosleep.c lib/util/parseln.c +lib/util/pipe2.c lib/util/progname.c lib/util/pw_dup.c lib/util/reallocarray.c diff --git a/config.h.in b/config.h.in index c562be867..ef864e1aa 100644 --- a/config.h.in +++ b/config.h.in @@ -518,6 +518,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_PATHS_H +/* Define to 1 if you have the `pipe2' function. */ +#undef HAVE_PIPE2 + /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL diff --git a/configure b/configure index 7bb95850c..71783b9fa 100755 --- a/configure +++ b/configure @@ -20029,6 +20029,32 @@ esac fi +fi +done + +for ac_func in pipe2 +do : + ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" +if test "x$ac_cv_func_pipe2" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PIPE2 1 +_ACEOF + +else + + case " $LIBOBJS " in + *" pipe2.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS pipe2.$ac_objext" + ;; +esac + + + for _sym in sudo_pipe2; do + COMPAT_EXP="${COMPAT_EXP}${_sym} +" + done + + fi done diff --git a/configure.ac b/configure.ac index 75c079a27..37148dad2 100644 --- a/configure.ac +++ b/configure.ac @@ -2619,6 +2619,10 @@ AC_CHECK_FUNCS(nanosleep, [], [ SUDO_APPEND_COMPAT_EXP(sudo_nanosleep) ]) ]) +AC_CHECK_FUNCS([pipe2], [], [ + AC_LIBOBJ(pipe2) + SUDO_APPEND_COMPAT_EXP(sudo_pipe2) +]) AC_CHECK_FUNCS([pw_dup], [], [ AC_LIBOBJ(pw_dup) SUDO_APPEND_COMPAT_EXP(sudo_pw_dup) diff --git a/include/sudo_compat.h b/include/sudo_compat.h index 311c4440a..eea93b474 100644 --- a/include/sudo_compat.h +++ b/include/sudo_compat.h @@ -202,6 +202,11 @@ # endif #endif +/* For pipe2() emulation. */ +#if !defined(HAVE_PIPE2) && defined(O_NONBLOCK) && !defined(O_CLOEXEC) +# define O_CLOEXEC 0x80000000 +#endif + /* * BSD defines these in but we don't include that anymore. */ @@ -520,5 +525,10 @@ __dso_public void sudo_vsyslog(int pri, const char *fmt, va_list ap); # undef vsyslog # define vsyslog(_a, _b, _c) sudo_vsyslog((_a), (_b), (_c)) #endif /* HAVE_VSYSLOG */ +#ifndef HAVE_PIPE2 +__dso_public int sudo_pipe2(int fildes[2], int flags); +# undef pipe2 +# define pipe2(_a, _b) sudo_pipe2((_a), (_b)) +#endif /* HAVE_PIPE2 */ #endif /* SUDO_COMPAT_H */ diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index b1b24eec8..dbf6a7667 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -489,6 +489,8 @@ parseln_test.lo: $(srcdir)/regress/sudo_parseln/parseln_test.c \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/sudo_util.h $(top_builddir)/config.h $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/sudo_parseln/parseln_test.c +pipe2.lo: $(srcdir)/pipe2.c $(incdir)/sudo_compat.h $(top_builddir)/config.h + $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/pipe2.c progname.lo: $(srcdir)/progname.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \ $(top_builddir)/config.h diff --git a/lib/util/pipe2.c b/lib/util/pipe2.c new file mode 100644 index 000000000..5c6831c78 --- /dev/null +++ b/lib/util/pipe2.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef HAVE_PIPE2 + +#include + +#include +#include + +#include "sudo_compat.h" + +int +sudo_pipe2(int fildes[2], int flags) +{ + if (pipe(fildes) != 0) + return -1; + + if (ISSET(flags, O_NONBLOCK)) { + int flags = fcntl(fildes[0], F_GETFL, 0); + if (flags == -1) + goto bad; + if (fcntl(fildes[0], F_SETFL, flags | O_NONBLOCK) == -1) + goto bad; + flags = fcntl(fildes[1], F_GETFL, 0); + if (flags == -1) + goto bad; + if (fcntl(fildes[1], F_SETFL, flags | O_NONBLOCK) == -1) + goto bad; + } + if (ISSET(flags, O_CLOEXEC)) { + if (fcntl(fildes[0], F_SETFD, FD_CLOEXEC) == -1) + goto bad; + if (fcntl(fildes[1], F_SETFD, FD_CLOEXEC) == -1) + goto bad; + } + return 0; +bad: + close(fildes[0]); + close(fildes[1]); + return -1; +} + +#endif /* HAVE_PIPE2 */ diff --git a/mkdep.pl b/mkdep.pl index 3f94c069b..67a596096 100755 --- a/mkdep.pl +++ b/mkdep.pl @@ -71,7 +71,7 @@ sub mkdep { # XXX - fill in AUTH_OBJS from contents of the auth dir instead $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:; $makefile =~ s:\@FILEDIGEST\@:filedigest.lo filedigest_openssl.lo filedigest_gcrypt.lo:; - $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo:; + $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo pipe2.lo:; # Parse OBJS lines my %objs;