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