Ignore:
Timestamp:
Sep 23, 2019, 5:23:37 AM (6 years ago)
Author:
Alex Taylor
Message:

Add Sys2Exec function (DosExecPgm wrapper)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rxutilex/trunk/rxutilex.c

    r43 r47  
    9494#define SZ_LIBRARY_NAME         "RXUTILEX"  // Name of this library
    9595//#define SZ_ERROR_NAME       "SYS2ERR"   // REXX variable used to store error codes - must be defined in Makefile
    96 #define SZ_VERSION              "0.1.6"     // Current version of this library
     96#define SZ_VERSION              "0.1.7"     // Current version of this library
    9797
    9898// Maximum string lengths...
     
    153153    "Sys2Write",
    154154    "Sys2QuerySysValue",
     155    "Sys2Exec",
    155156    "Sys2Version"
    156157};
     
    174175RexxFunctionHandler Sys2KillProcess;
    175176RexxFunctionHandler Sys2QueryForegroundProcess;
     177RexxFunctionHandler Sys2Exec;
    176178
    177179RexxFunctionHandler Sys2QueryDriveInfo;
     
    27162718
    27172719
     2720/* ------------------------------------------------------------------------- *
     2721 * Sys2Exec                                                                  *
     2722 *                                                                           *
     2723 * Wrapper to DosExecPgm.                                                    *
     2724 *                                                                           *
     2725 * REXX ARGUMENTS:                                                           *
     2726 *   1. Name of executable program                                (REQUIRED) *
     2727 *   2. Arguments to pass to program (default "")                            *
     2728 *   3. Execution mode flag, one of:                                         *
     2729 *       'W' or 'S': Wait for program to return (EXEC_SYNC)                  *
     2730 *       'N' or 'A': No wait (EXEC_ASYNC)                                    *
     2731 *       'D' or 'B': Detach process (EXEC_BACKGROUND)                        *
     2732 *                                                                           *
     2733 * REXX RETURN VALUE:                                                        *
     2734 *   If EXEC_SYNC mode was requested, returns the termination status from    *
     2735 *   the started session.  Otherwise, returns the process ID.                *
     2736 * ------------------------------------------------------------------------- */
     2737ULONG APIENTRY Sys2Exec( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     2738{
     2739    RESULTCODES st_RC = {0};
     2740    CHAR        szLoadErr[ CCHMAXPATH ] = {0},
     2741                szTerminate[ US_INTEGER_MAXZ ];
     2742    PSZ         pszProg,
     2743                pszArgs,
     2744                s;
     2745    ULONG       cbArgs,
     2746                ulExec;
     2747    APIRET      rc;
     2748
     2749    // Reset the error indicator
     2750    WriteErrorCode( 0, NULL );
     2751
     2752    // Make sure we have at least one valid argument
     2753    if (( argc < 1 ) || ( !RXVALIDSTRING( argv[0]) ))
     2754        return ( 40 );
     2755
     2756    // Second argument is optional but must be a valid string if specified
     2757    if (( argc >= 2 ) && ( !RXVALIDSTRING(argv[1]) ))
     2758        return ( 40 );
     2759
     2760    // Third argument: execution mode flag
     2761    if ( argc >= 3 && RXVALIDSTRING(argv[2]) ) {
     2762        strupr( argv[2].strptr );
     2763        switch ( argv[2].strptr[0] ) {
     2764            case 'N':
     2765            case 'A': ulExec = EXEC_ASYNC; break;
     2766            case 'W':
     2767            case 'S': ulExec = EXEC_SYNC; break;
     2768            case 'D':
     2769            case 'B': ulExec = EXEC_BACKGROUND; break;
     2770            default: return ( 40 );
     2771        }
     2772    }
     2773
     2774    // Build the argument strings (first arg must be the program name)
     2775    pszProg = strrchr( argv[0].strptr, '\\');
     2776    if ( pszProg == NULL )
     2777        pszProg = strrchr( argv[0].strptr, ':');
     2778    if ( pszProg == NULL )
     2779        pszProg = argv[0].strptr;
     2780    cbArgs = strlen( pszProg + 1 );
     2781    if ( argc >= 2 ) {
     2782        cbArgs += argv[1].strlength + 1;
     2783    }
     2784    pszArgs = calloc( cbArgs + 1, sizeof(char) );
     2785    if ( pszArgs == NULL ) {
     2786        WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "malloc");
     2787        SaveResultString( prsResult, NULL, 0 );
     2788        return ( 0 );
     2789    }
     2790
     2791    // Concatenate the program and argument strings, null-separated
     2792    // (We use 0x1A while building the string to avoid termination issues)
     2793    if ( argc >= 2 )
     2794        sprintf( pszArgs, "%s\x1A%s\x1A", pszProg, argv[1].strptr );
     2795    else
     2796        sprintf( pszArgs, "%s\x1A", pszProg );
     2797    // Now replace the 0x1A's with nulls (starting from string end)
     2798    while (( s = strrchr( pszArgs, 0x1A )) != NULL )
     2799        *s = 0;
     2800
     2801    // Launch the program
     2802    rc = DosExecPgm( szLoadErr, sizeof( szLoadErr), ulExec,
     2803                     pszArgs, NULL, &st_RC, pszProg );
     2804    if ( rc != NO_ERROR ) {
     2805        WriteErrorCode( rc, "DosExecPgm");
     2806        SaveResultString( prsResult, PSZ_ZERO, 1 );
     2807        return ( 0 );
     2808    }
     2809
     2810    sprintf( szTerminate, "%u", st_RC.codeTerminate );
     2811    SaveResultString( prsResult, szTerminate, strlen(szTerminate) );
     2812    return ( 0 );
     2813}
     2814
    27182815
    27192816// -------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.