From 8ec37440dd82c1ddceae2f7be6a42084e596439d Mon Sep 17 00:00:00 2001 From: JinWang An Date: Thu, 23 Dec 2021 14:11:07 +0900 Subject: [PATCH] Imported Upstream version 1.5.0 --- ChangeLog | 36 ++++++++++++++++++++++++++++++++++++ NEWS | 5 +++++ README | 2 +- configure | 20 ++++++++++---------- configure.ac | 4 ++-- lib/Makefile.am | 4 ++-- lib/Makefile.in | 2 +- lib/pipeline-private.h | 5 ++++- lib/pipeline.c | 38 +++++++++++++++++++++++++++++++++++--- lib/pipeline.h | 21 ++++++++++++++++++++- man/Makefile.am | 3 ++- man/Makefile.in | 1 + man/libpipeline.3 | 25 ++++++++++++++++++++++++- tests/basic.c | 22 +++++++++++++++++++++- tests/read.c | 2 +- 15 files changed, 165 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index db52fc4..bbd0f47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,39 @@ +2017-11-14 Colin Watson + + Version: 1.5.0. + + * lib/Makefile.am (libpipeline_la_LDFLAGS): Bump -version-info to 6:0:5. + +2017-11-14 Colin Watson + + Add pipecmd_pre_exec function + + * lib/pipeline-private.h (struct pipecmd): Add pre_exec_func, + pre_exec_free_func, and pre_exec_data. + * lib/pipeline.c (pipecmd_new, pipecmd_new_function, + pipecmd_new_sequencev): Initialise cmd->pre_exec_func, + cmd->pre_exec_free_func, and cmd->pre_exec_data. + (pipecmd_dup): Copy cmd->pre_exec_func, cmd->pre_exec_free_func, and + cmd->pre_exec_data if necessary. + (pipecmd_pre_exec): New function. + (pipecmd_exec): If cmd->pre_exec_func is set, call it immediately before + calling execvp or cmd->func. + * lib/pipeline.h (pipecmd_pre_exec): Add prototype. + (pipeline_install_post_fork): Cross-reference pipecmd_pre_exec in + comment. + * man/Makefile.am (FUNCTIONS): Add pipecmd_pre_exec. + * man/libpipeline.3 (Functions to build individual commands): Document + pipecmd_pre_exec. + (Functions to run pipelines and handle signals): Cross-reference + pipecmd_pre_exec from pipeline_install_post_fork. + * tests/basic.c (test_basic_pre_exec): Test pipecmd_pre_exec. + * NEWS: Document this. + * README: Update copyright years. + +2017-07-10 Colin Watson + + tests/read.c: Update program_name + 2017-07-10 Colin Watson Version: 1.4.2. diff --git a/NEWS b/NEWS index c799245..2acddd3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +libpipeline 1.5.0 (14 November 2017) +==================================== + +Add `pipecmd_pre_exec' to install a pre-exec handler for a single command. + libpipeline 1.4.2 (10 July 2017) ================================ diff --git a/README b/README index e882aa2..d8ffd94 100644 --- a/README +++ b/README @@ -59,7 +59,7 @@ Copyright (C) 1994 Markus Armbruster. Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. -Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Colin Watson. +Copyright (C) 2003-2017 Colin Watson. libpipeline is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/configure b/configure index a02fe26..a006ee0 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libpipeline 1.4.2. +# Generated by GNU Autoconf 2.69 for libpipeline 1.5.0. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libpipeline' PACKAGE_TARNAME='libpipeline' -PACKAGE_VERSION='1.4.2' -PACKAGE_STRING='libpipeline 1.4.2' +PACKAGE_VERSION='1.5.0' +PACKAGE_STRING='libpipeline 1.5.0' PACKAGE_BUGREPORT='cjwatson@debian.org' PACKAGE_URL='' @@ -2019,7 +2019,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libpipeline 1.4.2 to adapt to many kinds of systems. +\`configure' configures libpipeline 1.5.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -2090,7 +2090,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libpipeline 1.4.2:";; + short | recursive ) echo "Configuration of libpipeline 1.5.0:";; esac cat <<\_ACEOF @@ -2221,7 +2221,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libpipeline configure 1.4.2 +libpipeline configure 1.5.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2930,7 +2930,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libpipeline $as_me 1.4.2, which was +It was created by libpipeline $as_me 1.5.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3817,7 +3817,7 @@ fi # Define the identity of the package. PACKAGE='libpipeline' - VERSION='1.4.2' + VERSION='1.5.0' cat >>confdefs.h <<_ACEOF @@ -27501,7 +27501,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libpipeline $as_me 1.4.2, which was +This file was extended by libpipeline $as_me 1.5.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -27567,7 +27567,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libpipeline config.status 1.4.2 +libpipeline config.status 1.5.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 8db9149..ca6ace5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -# Copyright (C) 2010, 2011, 2012, 2013 Colin Watson. +# Copyright (C) 2010-2017 Colin Watson. # # This file is part of libpipeline. # @@ -22,7 +22,7 @@ dnl Process this file with autoconf to produce a configure script. m4_pattern_forbid([^PIPELINE_]) # Initialise and check we're in the correct directory. -AC_INIT([libpipeline], [1.4.2], [cjwatson@debian.org]) +AC_INIT([libpipeline], [1.5.0], [cjwatson@debian.org]) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([1.10 -Wall -Werror foreign]) AM_MAINTAINER_MODE diff --git a/lib/Makefile.am b/lib/Makefile.am index eb65f6a..b595ad1 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -## Copyright (C) 2010 Colin Watson. +## Copyright (C) 2010-2017 Colin Watson. ## ## This file is part of libpipeline. ## @@ -40,7 +40,7 @@ libpipeline_la_LIBADD = ../gnulib/lib/libgnu.la $(LTLIBOBJS) libpipeline_la_LDFLAGS = \ -export-symbols-regex '^(pipecmd|pipeline)_' \ -no-undefined \ - -version-info 5:2:4 + -version-info 6:0:5 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpipeline.pc diff --git a/lib/Makefile.in b/lib/Makefile.in index 5d4625e..2943237 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -1098,7 +1098,7 @@ libpipeline_la_LIBADD = ../gnulib/lib/libgnu.la $(LTLIBOBJS) libpipeline_la_LDFLAGS = \ -export-symbols-regex '^(pipecmd|pipeline)_' \ -no-undefined \ - -version-info 5:2:4 + -version-info 6:0:5 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpipeline.pc diff --git a/lib/pipeline-private.h b/lib/pipeline-private.h index 940346e..346b6bc 100644 --- a/lib/pipeline-private.h +++ b/lib/pipeline-private.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001, 2002, 2005, 2007, 2009, 2010 Colin Watson. + * Copyright (C) 2001-2017 Colin Watson. * * This file is part of libpipeline. * @@ -61,6 +61,9 @@ struct pipecmd { int nenv; int env_max; /* size of allocated array */ struct pipecmd_env *env; + pipecmd_function_type *pre_exec_func; + pipecmd_function_type *pre_exec_free_func; + void *pre_exec_data; union { struct pipecmd_process { int argc; diff --git a/lib/pipeline.c b/lib/pipeline.c index dcd2f27..fec0721 100644 --- a/lib/pipeline.c +++ b/lib/pipeline.c @@ -1,6 +1,6 @@ /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003 * Free Software Foundation, Inc. - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Colin Watson. + * Copyright (C) 2003-2017 Colin Watson. * Written for groff by James Clark (jjc@jclark.com) * Heavily adapted and extended for man-db by Colin Watson. * @@ -110,6 +110,10 @@ pipecmd *pipecmd_new (const char *name) cmd->env_max = 4; cmd->env = xnmalloc (cmd->env_max, sizeof *cmd->env); + cmd->pre_exec_func = NULL; + cmd->pre_exec_free_func = NULL; + cmd->pre_exec_data = NULL; + cmdp = &cmd->u.process; cmdp->argc = 0; @@ -306,6 +310,10 @@ pipecmd *pipecmd_new_function (const char *name, cmd->env_max = 4; cmd->env = xnmalloc (cmd->env_max, sizeof *cmd->env); + cmd->pre_exec_func = NULL; + cmd->pre_exec_free_func = NULL; + cmd->pre_exec_data = NULL; + cmdf = &cmd->u.function; cmdf->func = func; @@ -332,6 +340,10 @@ pipecmd *pipecmd_new_sequencev (const char *name, va_list cmdv) cmd->env_max = 4; cmd->env = xnmalloc (cmd->env_max, sizeof *cmd->env); + cmd->pre_exec_func = NULL; + cmd->pre_exec_free_func = NULL; + cmd->pre_exec_data = NULL; + cmds = &cmd->u.sequence; cmds->ncommands = 0; @@ -396,6 +408,10 @@ pipecmd *pipecmd_dup (pipecmd *cmd) assert (newcmd->nenv <= newcmd->env_max); newcmd->env = xmalloc (newcmd->env_max * sizeof *newcmd->env); + newcmd->pre_exec_func = cmd->pre_exec_func; + newcmd->pre_exec_free_func = cmd->pre_exec_free_func; + newcmd->pre_exec_data = cmd->pre_exec_data; + for (i = 0; i < cmd->nenv; ++i) { newcmd->env[i].name = cmd->env[i].name ? xstrdup (cmd->env[i].name) : NULL; @@ -589,6 +605,16 @@ void pipecmd_clearenv (pipecmd *cmd) ++cmd->nenv; } +void pipecmd_pre_exec (pipecmd *cmd, + pipecmd_function_type *func, + pipecmd_function_free_type *free_func, + void *data) +{ + cmd->pre_exec_func = func; + cmd->pre_exec_free_func = free_func; + cmd->pre_exec_data = data; +} + void pipecmd_sequence_command (pipecmd *cmd, pipecmd *child) { struct pipecmd_sequence *cmds; @@ -772,6 +798,8 @@ void pipecmd_exec (pipecmd *cmd) switch (cmd->tag) { case PIPECMD_PROCESS: { struct pipecmd_process *cmdp = &cmd->u.process; + if (cmd->pre_exec_func) + cmd->pre_exec_func (cmd->pre_exec_data); execvp (cmd->name, cmdp->argv); break; } @@ -782,10 +810,14 @@ void pipecmd_exec (pipecmd *cmd) */ case PIPECMD_FUNCTION: { struct pipecmd_function *cmdf = &cmd->u.function; - (*cmdf->func) (cmdf->data); + if (cmd->pre_exec_func) + cmd->pre_exec_func (cmd->pre_exec_data); + cmdf->func (cmdf->data); /* pacify valgrind et al */ if (cmdf->free_func) - (*cmdf->free_func) (cmdf->data); + cmdf->free_func (cmdf->data); + if (cmd->pre_exec_free_func) + cmd->pre_exec_free_func (cmd->pre_exec_data); exit (0); } diff --git a/lib/pipeline.h b/lib/pipeline.h index f20a493..bd49cbc 100644 --- a/lib/pipeline.h +++ b/lib/pipeline.h @@ -1,6 +1,6 @@ /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2002 * Free Software Foundation, Inc. - * Copyright (C) 2003, 2004, 2005, 2007, 2008 Colin Watson. + * Copyright (C) 2003-2017 Colin Watson. * Written for groff by James Clark (jjc@jclark.com) * Adapted for man-db by Colin Watson. * @@ -196,6 +196,22 @@ void pipecmd_unsetenv (pipecmd *cmd, const char *name); */ void pipecmd_clearenv (pipecmd *cmd); +/* Install a pre-exec handler. This will be run immediately before + * executing the command's payload (process or function). Pass NULL to + * clear any existing pre-exec handler. The data argument is passed as the + * function's only argument, and will be freed before returning using + * free_func (if non-NULL). + * + * This is similar to pipeline_install_post_fork, except that is specific to + * a single command rather than installing a global handler, and it runs + * slightly later (immediately before exec rather than immediately after + * fork). + */ +void pipecmd_pre_exec (pipecmd *cmd, + pipecmd_function_type *func, + pipecmd_function_free_type *free_func, + void *data); + /* Add a command to a sequence. */ void pipecmd_sequence_command (pipecmd *cmd, pipecmd *child); @@ -358,6 +374,9 @@ typedef void pipeline_post_fork_fn (void); * immediately after it is forked. For instance, this may be used for * cleaning up application-specific signal handlers. Pass NULL to clear any * existing post-fork handler. + * + * See pipecmd_pre_exec for a similar facility limited to a single command + * rather than global to the calling process. */ void pipeline_install_post_fork (pipeline_post_fork_fn *fn); diff --git a/man/Makefile.am b/man/Makefile.am index 6c8d95f..ae3f689 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -## Copyright (C) 2010 Colin Watson. +## Copyright (C) 2010-2017 Colin Watson. ## ## This file is part of libpipeline. ## @@ -44,6 +44,7 @@ FUNCTIONS = \ pipecmd_setenv \ pipecmd_unsetenv \ pipecmd_clearenv \ + pipecmd_pre_exec \ pipecmd_sequence_command \ pipecmd_dump \ pipecmd_tostring \ diff --git a/man/Makefile.in b/man/Makefile.in index 07a25e5..fd13158 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -1047,6 +1047,7 @@ FUNCTIONS = \ pipecmd_setenv \ pipecmd_unsetenv \ pipecmd_clearenv \ + pipecmd_pre_exec \ pipecmd_sequence_command \ pipecmd_dump \ pipecmd_tostring \ diff --git a/man/libpipeline.3 b/man/libpipeline.3 index cb1533a..9d95fda 100644 --- a/man/libpipeline.3 +++ b/man/libpipeline.3 @@ -1,4 +1,4 @@ -.\" Copyright (C) 2010 Colin Watson. +.\" Copyright (C) 2010-2017 Colin Watson. .\" .\" This file is part of libpipeline. .\" @@ -243,6 +243,26 @@ Beware that this may cause unexpected failures, for example if some of the contents of the environment are necessary to execute programs at all (say, .Li PATH ) . .Pp +.It Xo Ft void +.Fo pipecmd_pre_exec +.Fa "pipecmd *cmd" +.Fa "pipecmd_function_type *func" +.Fa "pipecmd_function_free_type *free_func" +.Fa "void *data" +.Fc +.Xc +.Pp +Install a pre-exec handler. +This will be run immediately before executing the command's payload (process +or function). +Pass NULL to clear any existing pre-exec handler. +The data argument is passed as the function's only argument, and will be +freed before returning using free_func (if non-NULL). +.Pp +This is similar to pipeline_install_post_fork, except that is specific to a +single command rather than installing a global handler, and it runs slightly +later (immediately before exec rather than immediately after fork). +.Pp .It Ft void Fn pipecmd_sequence_command "pipecmd *cmd" "pipecmd *child" .Pp Add a command to a sequence created using @@ -514,6 +534,9 @@ Pass .Li NULL to clear any existing post-fork handler. .Pp +See pipecmd_pre_exec for a similar facility limited to a single command +rather than global to the calling process. +.Pp .It Ft void Fn pipeline_start "pipeline *p" .Pp Start the processes in a pipeline. diff --git a/tests/basic.c b/tests/basic.c index bba5a30..97c8d52 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Colin Watson. + * Copyright (C) 2010-2017 Colin Watson. * * This file is part of libpipeline. * @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -296,6 +297,24 @@ START_TEST (test_basic_fchdir) } END_TEST +/* This is of course better done using pipecmd_setenv, but setting an + * environment variable makes for an easy test. + */ +static void pre_exec (void *data PIPELINE_ATTR_UNUSED) +{ + setenv ("TEST1", "10", 1); +} + +START_TEST (test_basic_pre_exec) +{ + pipeline *p; + + p = pipeline_new_command_args (SHELL, "-c", "exit $TEST1", NULL); + pipecmd_pre_exec (pipeline_get_command (p, 0), pre_exec, NULL, NULL); + fail_unless (pipeline_run (p) == 10, "TEST1 not set properly"); +} +END_TEST + START_TEST (test_basic_sequence) { pipeline *p; @@ -330,6 +349,7 @@ Suite *basic_suite (void) TEST_CASE (s, basic, setenv); TEST_CASE (s, basic, unsetenv); TEST_CASE (s, basic, clearenv); + TEST_CASE (s, basic, pre_exec); TEST_CASE_WITH_FIXTURE (s, basic, chdir, temp_dir_setup, temp_dir_teardown); TEST_CASE_WITH_FIXTURE (s, basic, fchdir, diff --git a/tests/read.c b/tests/read.c index 1c574d8..886624b 100644 --- a/tests/read.c +++ b/tests/read.c @@ -33,7 +33,7 @@ #include "common.h" -const char *program_name = "reading_long_line"; +const char *program_name = "read"; /* Must be 8194 or bigger */ #define RANDOM_STR_LEN 9000 -- 2.34.1