This is dos_os2.c in view mode; [Download] [Up]
/* /////////////////////////////////////////////////////////////////// // File: dos_os2.c // // Descript: routines that are common to dos & os/2 and `fairly' // compiler independent // included by i386.c, ibmpc.c, os2.c // // Public: sys_flush(); // sys_delete_file(); // sys_rename(); // sys_suspend(); // sys_System(); // // Private: discover_shell(); // parse_command_line(); // // Public: NumLock_Is_Gold, PC_Alt_Char // // Private: --- // // Revisions: // - --- -- --- --- /////////////////////////////////////////////////////////////////// */ #ifndef __DOS_OS2_CODE_INCLUDED #define __DOS_OS2_CODE_INCLUDED #ifdef __GO32__ # include <fcntl.h> # include <sys/types.h> # include <sys/stat.h> # include <sys/file.h> #endif #ifdef __os2__ #include <config.h> #include <fcntl.h> #include <io.h> #include <sys/types.h> #include <sys/stat.h> #endif #ifdef msdos #include <fcntl.h> #include <io.h> #include <sys/stat.h> #endif #ifdef UNIXSLASH const char SlashChar[2] = "/"; #else const char SlashChar[2] = "\\"; #endif extern char *get_cwd (void); int NumLock_Is_Gold = 0; /* map numlock key to F1 */ int PC_Alt_Char = 27; void sys_flush (int dummy) { (void) dummy; } /* Delete the file NAME. returns 0 on failure, 1 on sucess * Under OS/2 and DOS, unlink()[UNIX] and remove()[ANSI] are equivalent. */ int sys_delete_file(char *name) { return(1 + remove(name)); } /* Rename the file or directory OLDNAME to NEWNAME. Moving a file * to a different directory on the same drive is possible. * returns 0 on success and -1 on error */ int sys_rename(char *oldname, char *newname) { return(rename(oldname,newname)); } /* find shell (once only) */ static char *shell = NULL, *shell_switch = NULL; static void discover_shell(void) { if ( shell != NULL ) return; #ifdef SH_SHELL /* maybe some day ... */ shell_switch = "-c"; if ( (shell = getenv("SHELL")) != NULL ) return; #endif shell_switch = "/c"; if ( (shell = getenv("COMSPEC")) != NULL ) return; #ifdef __os2__ shell = "cmd.exe"; /* absolute last resort! */ #else shell = "command.com"; /* absolute last resort! */ #endif } /* /////////////////////////////////////////////////////////////////// // Function: static int parse_command_line( int *argc, char ***argv, // char **fname, // char *command_line ); // Descript: parse command_line // // Returns: the handles to redirect // // Caveat: requires spaces to separate each argument // ie., args>filename will NOT work ///////////////////////////////////////////////////////////////////// */ #define DIRECT_SPAWN 0x1000 /* some arbitrary number */ static int parse_command_line( int *argc, char ***argv, char **fname, char *command_line ) { int count, handles = 0; char *pt; discover_shell(); /* find which shell to use */ while ( (*command_line != '\0') && (*command_line == ' ')) command_line++; /* start on 1st non-space */ if ( *command_line == '!' ) { handles = DIRECT_SPAWN; command_line++; /* advance past '!' */ while ((*command_line != '\0') && (*command_line == ' ')) command_line++; /* start on next non-space */ } pt = command_line; count = 0; while ( *pt != '\0' ) { count++; /* this is an argument */ while ((*pt != '\0') && (*pt != ' ')) { if ( *pt == '|' ) /* cannot spawn directly */ handles = 0; /* need shell for pipes */ pt++; /* advance until a space */ } while ( *pt == ' ' ) pt++; /* advance until a non-space */ } *argv = (char **) SLMALLOC( (count+3) * sizeof(char *) ); if ( *argv == NULL ) return 0; /* malloc error */ *argc = 0; if ( !(handles & DIRECT_SPAWN) ) { (*argv)[ *argc ] = shell; (*argc)++; if ( count > 0 ) { (*argv)[ *argc ] = shell_switch; (*argc)++; } count += (*argc); } pt = command_line; while ((*argc < count) && (*pt != '\0')) { (*argv)[ *argc ] = pt; (*argc)++; while ( *pt != '\0' && *pt != ' ' ) pt++; /* advance until a space */ if ( *pt != '\0' ) *(pt++) = '\0'; /* parse argument here */ while ( *pt == ' ') pt++; /* advance until a non-space */ } (*argv) [ *argc ] = (char *) NULL; /* NULL terminated list */ /* now examine the arguments for '>' redirect */ for ( count = 0; count < *argc; count++ ) { for ( pt = (*argv)[count]; *pt && *pt != '>'; pt++ ) /* find '>' char */; if ( *pt == '>' ) { if ( pt == (*argv)[count] ) { handles |= 0x01; } else { switch ( *(--pt) ) { case '1': handles |= 0x01; break; case '2': handles |= 0x02; break; case '&': handles |= 0x03; break; } } (*argv)[count] = NULL; /* remove from the list */ count++; /* file name follows '>' */ if ( (*argv)[count] != NULL ) *fname = (*argv)[count]; } } if ((*fname == NULL) || (**fname == '\0' )) handles = 0x00; /* don't redirect if there is no name */ return handles; } /* /////////////////////////////////////////////////////////////////// // Function: int sys_System(char *command_line); // // Descript: shell wrapper that understands some common redirection syntax // command args > filename ; stdout // command args 1> filename ; stdout // command args 2> filename ; stderr // command args &> filename ; stdout+stderr // command args > filename 2>&1 ; stdout+stderr // // additionally, if command is prefixed by a '!', then the command is // spawned directly without invoking the shell // // Returns: returns error codes as per spawn*() // // Caveat: requires spaces to separate each argument // ie., command args>filename will NOT work ///////////////////////////////////////////////////////////////////// */ static int execute_the_command (char **, int, char *); int sys_System(char *command_line1) { int ret = -1, handles, argc = 0; char *fname = NULL, **argv = NULL, *command_line; if (NULL == (command_line = (char *) SLMALLOC (strlen (command_line1) + 1))) { msg_error ("Malloc error."); return -1; } strcpy (command_line, command_line1); handles = parse_command_line( &argc, &argv, &fname, command_line ); if (argc) { ret = execute_the_command (argv, handles, fname); if (argc) SLFREE(argv); } SLFREE (command_line); return ret; } void sys_suspend(void) { sys_System( "" ); } static int execute_the_command (char **argv, int handles, char *file) { int ret = 0; int fd1 = -1, fd2 = -1; int fd_err = -1, fd_out = -1; if (handles & 1) { /* save stdout file handle */ fd1 = dup (fileno (stdout)); if (fd1 == -1) { msg_error ("Unable to dup stdout"); return -1; } fd_out = open (file, O_CREAT | O_TRUNC | O_TEXT | O_WRONLY | O_APPEND, S_IREAD | S_IWRITE); if ((fd_out == -1) || (-1 == dup2 (fd_out, fileno (stdout)))) { msg_error ("Unable to redirect stdout!"); ret = -1; } } if (handles & 0x2) /* stderr */ { /* save stderr file handle */ fd2 = dup (fileno (stderr)); if (fd2 == -1) { msg_error ("Unable to dup stderr"); return -1; } if (fd_out == -1) { fd_err = open (file, O_CREAT | O_TRUNC | O_TEXT | O_RDWR | O_APPEND, S_IREAD | S_IWRITE); } else fd_err = fd_out; if ((fd_err == -1) || (-1 == dup2 (fd_err, fileno (stderr)))) { msg_error ("Unable to redirect stderr!"); ret = -1; } } if (fd_out != -1) close (fd_out); if ((fd_err != -1) && (fd_err != fd_out)) close (fd_err); if (ret == 0) { ret = spawnvp(P_WAIT, argv[0], (void *) argv); if (-1 == ret ) { switch(errno) { case ENOENT: if (handles & DIRECT_SPAWN ) msg_error("Command not found."); else msg_error("Shell not found."); break; case ENOMEM: msg_error("Insufficient Memory."); break; default: msg_error("Unknown Error."); } } } if (fd1 != -1) { if (-1 == dup2 (fd1, fileno (stdout))) { msg_error ("Unable to reattach stdout"); } close (fd1); } if (fd2 != -1) { if (-1 == dup2 (fd2, fileno (stderr))) { msg_error ("Unable to reattach stderr"); } close (fd2); } return ret; } #endif /* whole file */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.