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