diff options
author | delphij <delphij@FreeBSD.org> | 2015-07-15 19:21:26 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2015-07-15 19:21:26 +0000 |
commit | 2a25cee78ab1d37e7d2bc40ae675646974d99f56 (patch) | |
tree | b0302ac4be59e104f4e1e54014561a1389397192 /contrib/ntp/sntp/libopts/pgusage.c | |
parent | a0741a75537b2e0514472ac3b28afc55a7846c30 (diff) | |
download | FreeBSD-src-2a25cee78ab1d37e7d2bc40ae675646974d99f56.zip FreeBSD-src-2a25cee78ab1d37e7d2bc40ae675646974d99f56.tar.gz |
MFC r280849,280915-280916,281015-281016,282097,282408,282415,283542,
284864,285169-285170,285435:
ntp 4.2.8p3.
Relnotes: yes
Approved by: re (?)
Diffstat (limited to 'contrib/ntp/sntp/libopts/pgusage.c')
-rw-r--r-- | contrib/ntp/sntp/libopts/pgusage.c | 208 |
1 files changed, 119 insertions, 89 deletions
diff --git a/contrib/ntp/sntp/libopts/pgusage.c b/contrib/ntp/sntp/libopts/pgusage.c index c417c63..3d229c1 100644 --- a/contrib/ntp/sntp/libopts/pgusage.c +++ b/contrib/ntp/sntp/libopts/pgusage.c @@ -1,78 +1,122 @@ -/* - * $Id: pgusage.c,v 4.12 2007/04/28 22:19:23 bkorb Exp $ - * Time-stamp: "2006-07-16 08:13:26 bkorb" +/** + * \file pgusage.c * * Automated Options Paged Usage module. * - * This routine will run run-on options through a pager so the - * user may examine, print or edit them at their leisure. + * @addtogroup autoopts + * @{ */ - /* - * Automated Options copyright 1992-2007 Bruce Korb - * - * Automated Options is free software. - * You may 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. - * - * Automated Options 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. + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. * - * You should have received a copy of the GNU General Public License - * along with Automated Options. See the file "COPYING". If not, - * write to: The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved * - * As a special exception, Bruce Korb gives permission for additional - * uses of the text contained in his release of AutoOpts. + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. * - * The exception is that, if you link the AutoOpts library with other - * files to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the AutoOpts library code into it. + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" * - * This exception applies only to the code released by Bruce Korb under - * the name AutoOpts. If you copy code from other sources under the - * General Public License into a copy of AutoOpts, as the General Public - * License permits, the exception does not apply to the code that you add - * in this way. To avoid misleading anyone as to the status of such - * modified files, you must delete this exception notice from them. + * These files have the following sha256 sums: * - * If you write modifications of your own for AutoOpts, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd */ -tePagerState pagerState = PAGER_STATE_INITIAL; +#if defined(HAVE_WORKING_FORK) +static inline FILE * +open_tmp_usage(char ** buf) +{ + char * bf; + size_t bfsz; + + { + unsigned int my_pid = (unsigned int)getpid(); + char const * tmpdir = getenv(TMPDIR); + if (tmpdir == NULL) + tmpdir = tmp_dir; + bfsz = TMP_FILE_FMT_LEN + strlen(tmpdir) + 10; + bf = AGALOC(bfsz, "tmp fil"); + snprintf(bf, bfsz, TMP_FILE_FMT, tmpdir, my_pid); + } + + { + static mode_t const cmask = S_IRWXO | S_IRWXG; + mode_t svmsk = umask(cmask); + int fd = mkstemp(bf); + (void)umask(svmsk); + + if (fd < 0) { + AGFREE(bf); + return NULL; + } + *buf = bf; + return fdopen(fd, "w"); + } +} + +static inline char * +mk_pager_cmd(char const * fname) +{ + /* + * Page the file and remove it when done. For shell script processing, + * we must redirect the output to the current stderr, otherwise stdout. + */ + fclose(option_usage_fp); + option_usage_fp = NULL; + + { + char const * pager = (char const *)getenv(PAGER_NAME); + size_t bfsz; + char * res; + + /* + * Use the "more(1)" program if "PAGER" has not been defined + */ + if (pager == NULL) + pager = MORE_STR; + + bfsz = 2 * strlen(fname) + strlen(pager) + PAGE_USAGE_FMT_LEN; + res = AGALOC(bfsz, "more cmd"); + snprintf(res, bfsz, PAGE_USAGE_FMT, pager, fname); + AGFREE(fname); + return res; + } +} +#endif /*=export_func optionPagedUsage * private: * - * what: Decipher a boolean value - * arg: + tOptions* + pOpts + program options descriptor + - * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * what: emit help text and pass through a pager program. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + * * doc: * Run the usage output through a pager. * This is very handy if it is very long. + * This is disabled on platforms without a working fork() function. =*/ void -optionPagedUsage( tOptions* pOptions, tOptDesc* pOD ) +optionPagedUsage(tOptions * opts, tOptDesc * od) { -#if defined(__windows__) && !defined(__CYGWIN__) - (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS ); +#if ! defined(HAVE_WORKING_FORK) + if ((od->fOptState & OPTST_RESET) != 0) + return; + + (*opts->pUsageProc)(opts, EXIT_SUCCESS); #else - static pid_t my_pid; - char zPageUsage[ 1024 ]; + static bool sv_print_exit = false; + static char * fil_name = NULL; /* * IF we are being called after the usage proc is done @@ -82,62 +126,47 @@ optionPagedUsage( tOptions* pOptions, tOptDesc* pOD ) switch (pagerState) { case PAGER_STATE_INITIAL: { - my_pid = getpid(); -#ifdef HAVE_SNPRINTF - snprintf(zPageUsage, sizeof(zPageUsage), "/tmp/use.%lu", (tAoUL)my_pid); -#else - sprintf( zPageUsage, "/tmp/use.%lu", (tAoUL)my_pid ); -#endif - unlink( zPageUsage ); - - /* - * Set usage output to this temporary file - */ - option_usage_fp = fopen( zPageUsage, "w" FOPEN_BINARY_FLAG ); + if ((od->fOptState & OPTST_RESET) != 0) + return; + option_usage_fp = open_tmp_usage(&fil_name); if (option_usage_fp == NULL) - _exit( EXIT_FAILURE ); + (*opts->pUsageProc)(opts, EXIT_SUCCESS); - pagerState = PAGER_STATE_READY; + pagerState = PAGER_STATE_READY; + sv_print_exit = print_exit; /* * Set up so this routine gets called during the exit logic */ - atexit( (void(*)(void))optionPagedUsage ); + atexit((void(*)(void))optionPagedUsage); /* * The usage procedure will now put the usage information into - * the temporary file we created above. + * the temporary file we created above. Keep any shell commands + * out of the result. */ - (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS ); + print_exit = false; + (*opts->pUsageProc)(opts, EXIT_SUCCESS); - /*NOTREACHED*/ - _exit( EXIT_FAILURE ); + /* NOTREACHED */ + _exit(EXIT_FAILURE); } case PAGER_STATE_READY: - { - tSCC zPage[] = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu"; - tCC* pzPager = (tCC*)getenv( "PAGER" ); + fil_name = mk_pager_cmd(fil_name); - /* - * Use the "more(1)" program if "PAGER" has not been defined - */ - if (pzPager == NULL) - pzPager = "more"; + if (sv_print_exit) { + fputs("\nexit 0\n", stdout); + fclose(stdout); + dup2(STDERR_FILENO, STDOUT_FILENO); - /* - * Page the file and remove it when done. - */ -#ifdef HAVE_SNPRINTF - snprintf(zPageUsage, sizeof(zPageUsage), zPage, pzPager, (tAoUL)my_pid); -#else - sprintf( zPageUsage, zPage, pzPager, (tAoUL)my_pid ); -#endif - fclose( stderr ); - dup2( STDOUT_FILENO, STDERR_FILENO ); + } else { + fclose(stderr); + dup2(STDOUT_FILENO, STDERR_FILENO); + } - (void)system( zPageUsage ); - } + ignore_val( system( fil_name)); + AGFREE(fil_name); case PAGER_STATE_CHILD: /* @@ -148,7 +177,8 @@ optionPagedUsage( tOptions* pOptions, tOptDesc* pOD ) #endif } -/* +/** @} + * * Local Variables: * mode: C * c-file-style: "stroustrup" |