#include #include #include #include #include #define ERROR_NO_ERROR 0 #define ERROR_MEMORY_ALLOCATION_FAILED -1 #define ERROR_INVALID_NUMBER_OF_PARAMETERS -2 #define ERROR_EXEC_E2BIG -3 #define ERROR_EXEC_EACCES -4 #define ERROR_EXEC_EINVAL -5 #define ERROR_EXEC_EMFILE -6 #define ERROR_EXEC_ENOENT -7 #define ERROR_EXEC_ENOEXEC -8 #define ERROR_EXEC_ENOMEM -9 #define ERROR_EXEC_UNKNOWN -10 char * errorMessage(int err) { switch (err) { case ERROR_NO_ERROR: return "No error\n"; case ERROR_MEMORY_ALLOCATION_FAILED: return "Memory allocation failed\n"; case ERROR_INVALID_NUMBER_OF_PARAMETERS: return "Invalid number of parameters\n"; case ERROR_EXEC_E2BIG: return "_exec: The space required for the arguments and environment settings exceeds 32 KB.\n"; case ERROR_EXEC_EACCES: return "_exec: The specified file has a locking or sharing violation.\n"; case ERROR_EXEC_EINVAL: return "_exec: Invalid parameter.\n"; case ERROR_EXEC_EMFILE: return "_exec: Too many files open (the specified file must be opened to determine whether it is executable).\n"; case ERROR_EXEC_ENOENT: return "_exec: The file or path not found.\n"; case ERROR_EXEC_ENOEXEC: return "_exec: The specified file is not executable or has an invalid executable-file format.\n"; case ERROR_EXEC_ENOMEM: return "_exec: Not enough memory is available to execute the new process; the available memory has been corrupted; or an invalid block exists, indicating that the calling process was not allocated properly.\n"; case ERROR_EXEC_UNKNOWN: return "Unknown _exec error.\n"; default: return "Unknown error.\n"; } } int main( int cArg, char* rgArg[] ) { int cArgCommand = cArg; // Take one off for the name of this exe, then add // one for the null at the end of the arg list. int i; // Looping variable int rc = ERROR_NO_ERROR; // Return code char **rgArgCommand; // An array for the command args // Make sure we got enough parameters to execute. if( cArg < 4) { fprintf(stderr, errorMessage(ERROR_MEMORY_ALLOCATION_FAILED)); fprintf( stderr, "Usage: %s <-cp classpath> [arg1 [arg2 [...]]]\n", rgArg[0] ); return ERROR_INVALID_NUMBER_OF_PARAMETERS; } // Allocate room to the arglist for the cal to exec rgArgCommand = (char **)malloc(sizeof(char *)*cArgCommand); // Did the memory allocation succeed? if (NULL == rgArgCommand) { fprintf(stderr, errorMessage(ERROR_MEMORY_ALLOCATION_FAILED)); return ERROR_MEMORY_ALLOCATION_FAILED; } fprintf( stderr, "Arg count = %d\n", cArg); fprintf( stderr, "Command arg count = %d\n", cArgCommand); // copy over the arguments for the command for (i = 1; i < cArg; i++) { fprintf(stderr, "rgArgCommand[%d] = rgArg[%d] (%s)\n", (i - 1), i, rgArg[i]); rgArgCommand[i - 1] = rgArg[i]; } // null out the command arg array fprintf( stderr, "null out rgArgCommand[%d]\n",i); rgArgCommand[cArgCommand - 1] = (char *)0; // exec the command if (-1 == _execv( rgArg[1], rgArgCommand)) { switch (errno) { case E2BIG: // The space required for the arguments and environment settings exceeds 32 KB. rc = ERROR_EXEC_E2BIG; break; case EACCES: // The specified file has a locking or sharing violation. rc = ERROR_EXEC_EACCES; break; case EINVAL: // Invalid parameter. rc = ERROR_EXEC_EINVAL; break; case EMFILE: // Too many files open (the specified file must be opened to determine whether it is executable). rc = ERROR_EXEC_EMFILE; break; case ENOENT: // The file or path not found. rc = ERROR_EXEC_ENOENT; break; case ENOEXEC: // The specified file is not executable or has an invalid executable-file format. rc = ERROR_EXEC_ENOEXEC; break; case ENOMEM: // Not enough memory is available to execute the new process; the available memory has been // corrupted; or an invalid block exists, indicating that the calling process was not allocated // properly. rc = ERROR_EXEC_ENOMEM; break; default: rc = ERROR_EXEC_UNKNOWN; break; } } free(rgArgCommand); return rc; }