1/* $NetBSD$ */ 2 3 4/** 5 * \file pgusage.c 6 * 7 * Time-stamp: "2011-03-25 17:54:41 bkorb" 8 * 9 * Automated Options Paged Usage module. 10 * 11 * This routine will run run-on options through a pager so the 12 * user may examine, print or edit them at their leisure. 13 * 14 * This file is part of AutoOpts, a companion to AutoGen. 15 * AutoOpts is free software. 16 * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved 17 * 18 * AutoOpts is available under any one of two licenses. The license 19 * in use must be one of these two and the choice is under the control 20 * of the user of the license. 21 * 22 * The GNU Lesser General Public License, version 3 or later 23 * See the files "COPYING.lgplv3" and "COPYING.gplv3" 24 * 25 * The Modified Berkeley Software Distribution License 26 * See the file "COPYING.mbsd" 27 * 28 * These files have the following md5sums: 29 * 30 * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 31 * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 32 * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd 33 */ 34 35/*=export_func optionPagedUsage 36 * private: 37 * 38 * what: Decipher a boolean value 39 * arg: + tOptions* + pOpts + program options descriptor + 40 * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + 41 * 42 * doc: 43 * Run the usage output through a pager. 44 * This is very handy if it is very long. 45 * This is disabled on platforms without a working fork() function. 46=*/ 47void 48optionPagedUsage(tOptions* pOptions, tOptDesc* pOD) 49{ 50#if ! defined(HAVE_WORKING_FORK) 51 if ((pOD->fOptState & OPTST_RESET) != 0) 52 return; 53 54 (*pOptions->pUsageProc)(pOptions, EXIT_SUCCESS); 55#else 56 static pid_t my_pid; 57 char zPageUsage[ 1024 ]; 58 59 /* 60 * IF we are being called after the usage proc is done 61 * (and thus has called "exit(2)") 62 * THEN invoke the pager to page through the usage file we created. 63 */ 64 switch (pagerState) { 65 case PAGER_STATE_INITIAL: 66 { 67 if ((pOD->fOptState & OPTST_RESET) != 0) 68 return; 69 70 my_pid = getpid(); 71#ifdef HAVE_SNPRINTF 72 snprintf(zPageUsage, sizeof(zPageUsage), "/tmp/use.%lu", (tAoUL)my_pid); 73#else 74 sprintf(zPageUsage, "/tmp/use.%lu", (tAoUL)my_pid); 75#endif 76 unlink(zPageUsage); 77 78 /* 79 * Set usage output to this temporary file 80 */ 81 option_usage_fp = fopen(zPageUsage, "w" FOPEN_BINARY_FLAG); 82 if (option_usage_fp == NULL) 83 _exit(EXIT_FAILURE); 84 85 pagerState = PAGER_STATE_READY; 86 87 /* 88 * Set up so this routine gets called during the exit logic 89 */ 90 atexit((void(*)(void))optionPagedUsage); 91 92 /* 93 * The usage procedure will now put the usage information into 94 * the temporary file we created above. 95 */ 96 (*pOptions->pUsageProc)(pOptions, EXIT_SUCCESS); 97 98 /* NOTREACHED */ 99 _exit(EXIT_FAILURE); 100 } 101 102 case PAGER_STATE_READY: 103 { 104 tSCC zPage[] = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu"; 105 tCC* pzPager = (tCC*)getenv("PAGER"); 106 107 /* 108 * Use the "more(1)" program if "PAGER" has not been defined 109 */ 110 if (pzPager == NULL) 111 pzPager = "more"; 112 113 /* 114 * Page the file and remove it when done. 115 */ 116#ifdef HAVE_SNPRINTF 117 snprintf(zPageUsage, sizeof(zPageUsage), zPage, pzPager, (tAoUL)my_pid); 118#else 119 sprintf(zPageUsage, zPage, pzPager, (tAoUL)my_pid); 120#endif 121 fclose(stderr); 122 dup2(STDOUT_FILENO, STDERR_FILENO); 123 124 (void)system(zPageUsage); 125 } 126 127 case PAGER_STATE_CHILD: 128 /* 129 * This is a child process used in creating shell script usage. 130 */ 131 break; 132 } 133#endif 134} 135 136/* 137 * Local Variables: 138 * mode: C 139 * c-file-style: "stroustrup" 140 * indent-tabs-mode: nil 141 * End: 142 * end of autoopts/pgusage.c */ 143