static void
textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD )
{
#   define _TT_(n) tSCC z ## n [] = #n;
    TEXTTO_TABLE
#   undef _TT_
#   define _TT_(n) z ## n ,
      static char const*  apzTTNames[] = { TEXTTO_TABLE };
#   undef _TT_

#if ! defined(HAVE_WORKING_FORK)
    printf( "%1$s_%2$s_TEXT='no %2$s text'\n",
            pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
#else
    int  nlHoldCt = 0;
    int  pipeFd[2];
    FILE* fp;

    printf( "%s_%s_TEXT='", pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
    fflush( stdout );

    if (pipe( pipeFd ) != 0) {
        fprintf( stderr, zBadPipe, errno, strerror( errno ));
        exit( EXIT_FAILURE );
    }

    switch (fork()) {
    case -1:
        fprintf( stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
        exit( EXIT_FAILURE );
        break;

    case 0:
        dup2( pipeFd[1], STDERR_FILENO );
        dup2( pipeFd[1], STDOUT_FILENO );
        close( pipeFd[0] );

        switch (whichVar) {
        case TT_LONGUSAGE:
            (*(pOpts->pUsageProc))( pOpts, EXIT_SUCCESS );
            /* NOTREACHED */
            exit( EXIT_FAILURE );

        case TT_USAGE:
            (*(pOpts->pUsageProc))( pOpts, EXIT_FAILURE );
            /* NOTREACHED */
            exit( EXIT_FAILURE );

        case TT_VERSION:
            if (pOD->fOptState & OPTST_ALLOC_ARG) {
                AGFREE(pOD->optArg.argString);
                pOD->fOptState &= ~OPTST_ALLOC_ARG;
            }
            pOD->optArg.argString = "c";
            optionPrintVersion( pOpts, pOD );
            /* NOTREACHED */

        default:
            exit( EXIT_FAILURE );
        }

    default:
        close( pipeFd[1] );
        fp = fdopen( pipeFd[0], "r" FOPEN_BINARY_FLAG );
    }

    for (;;) {
        int  ch = fgetc( fp );
        switch (ch) {

        case '\n':
            nlHoldCt++;
            break;

        case '\'':
            while (nlHoldCt > 0) {
                fputc( '\n', stdout );
                nlHoldCt--;
            }
            fputs( "'\\''", stdout );
            break;

        case EOF:
            goto endCharLoop;

        default:
            while (nlHoldCt > 0) {
                fputc( '\n', stdout );
                nlHoldCt--;
            }
            fputc( ch, stdout );
            break;
        }
    } endCharLoop:;

    fputs( "'\n\n", stdout );
    close( pipeFd[0] );
#endif
}
Exemple #2
0
/**
 *  The purpose of this function is to assign "long usage", short usage
 *  and version information to a shell variable.  Rather than wind our
 *  way through all the logic necessary to emit the text directly, we
 *  fork(), have our child process emit the text the normal way and
 *  capture the output in the parent process.
 *
 * @param[in] opts  the program options
 * @param[in] which what to print: long usage, usage or version
 * @param[in] od    for TT_VERSION, it is the version option
 */
static void
text_to_var(tOptions * opts, teTextTo which, tOptDesc * od)
{
#   define _TT_(n) static char const z ## n [] = #n;
    TEXTTO_TABLE
#   undef _TT_
#   define _TT_(n) z ## n ,
      static char const * ttnames[] = { TEXTTO_TABLE };
#   undef _TT_

#if ! defined(HAVE_WORKING_FORK)
    printf(SET_NO_TEXT_FMT, opts->pzPROGNAME, ttnames[which]);
#else
    int  fdpair[2];

    fflush(stdout);
    fflush(stderr);

    if (pipe(fdpair) != 0)
        fserr_exit(opts->pzProgName, "pipe", zinter_proc_pipe);

    switch (fork()) {
    case -1:
        fserr_exit(opts->pzProgName, "fork", opts->pzProgName);
        /* NOTREACHED */

    case 0:
        /*
         * Send both stderr and stdout to the pipe.  No matter which
         * descriptor is used, we capture the output on the read end.
         */
        dup2(fdpair[1], STDERR_FILENO);
        dup2(fdpair[1], STDOUT_FILENO);
        close(fdpair[0]);

        switch (which) {
        case TT_LONGUSAGE:
            (*(opts->pUsageProc))(opts, EXIT_SUCCESS);
            /* NOTREACHED */

        case TT_USAGE:
            (*(opts->pUsageProc))(opts, EXIT_FAILURE);
            /* NOTREACHED */

        case TT_VERSION:
            if (od->fOptState & OPTST_ALLOC_ARG) {
                AGFREE(od->optArg.argString);
                od->fOptState &= ~OPTST_ALLOC_ARG;
            }
            od->optArg.argString = "c";
            optionPrintVersion(opts, od);
            /* NOTREACHED */

        default:
            option_exits(EXIT_FAILURE);
            /* NOTREACHED */
        }
        /* NOTREACHED */

    default:
        close(fdpair[1]);
    }

    emit_var_text(opts->pzPROGNAME, ttnames[which], fdpair[0]);
#endif
}
Exemple #3
0
/*
 *  The purpose of this function is to assign "long usage", short usage
 *  and version information to a shell variable.  Rather than wind our
 *  way through all the logic necessary to emit the text directly, we
 *  fork(), have our child process emit the text the normal way and
 *  capture the output in the parent process.
 */
static void
text_to_var(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD)
{
#   define _TT_(n) static char const z ## n [] = #n;
    TEXTTO_TABLE
#   undef _TT_
#   define _TT_(n) z ## n ,
      static char const * apzTTNames[] = { TEXTTO_TABLE };
#   undef _TT_

#if ! defined(HAVE_WORKING_FORK)
    printf(SET_NO_TEXT_FMT, pOpts->pzPROGNAME, apzTTNames[ whichVar]);
#else
    int  pipeFd[2];

    fflush(stdout);
    fflush(stderr);

    if (pipe(pipeFd) != 0) {
        fprintf(stderr, zBadPipe, errno, strerror(errno));
        exit(EXIT_FAILURE);
    }

    switch (fork()) {
    case -1:
        fprintf(stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
        exit(EXIT_FAILURE);
        break;

    case 0:
        /*
         * Send both stderr and stdout to the pipe.  No matter which
         * descriptor is used, we capture the output on the read end.
         */
        dup2(pipeFd[1], STDERR_FILENO);
        dup2(pipeFd[1], STDOUT_FILENO);
        close(pipeFd[0]);

        switch (whichVar) {
        case TT_LONGUSAGE:
            (*(pOpts->pUsageProc))(pOpts, EXIT_SUCCESS);
            /* NOTREACHED */

        case TT_USAGE:
            (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
            /* NOTREACHED */

        case TT_VERSION:
            if (pOD->fOptState & OPTST_ALLOC_ARG) {
                AGFREE(pOD->optArg.argString);
                pOD->fOptState &= ~OPTST_ALLOC_ARG;
            }
            pOD->optArg.argString = "c";
            optionPrintVersion(pOpts, pOD);
            /* NOTREACHED */

        default:
            exit(EXIT_FAILURE);
        }

    default:
        close(pipeFd[1]);
    }

    emit_var_text(pOpts->pzPROGNAME, apzTTNames[whichVar], pipeFd[0]);
#endif
}