home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / dos_os2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  6.9 KB  |  258 lines

  1. /* ///////////////////////////////////////////////////////////////////
  2. //  File:    dos_os2.c
  3. //
  4. //  Descript:    routines that are common to dos & os/2 and `fairly'
  5. //        compiler independent
  6. //        included by i386.c, ibmpc.c, os2.c
  7. //
  8. //  Public:    sys_flush();
  9. //        sys_delete_file();
  10. //        sys_rename();
  11. //        sys_suspend();
  12. //        sys_System();
  13. //
  14. //  Private:    discover_shell();
  15. //        parse_command_line();
  16. //
  17. //  Public:    NumLock_Is_Gold, PC_Alt_Char
  18. //
  19. //  Private:    ---
  20. //
  21. //  Revisions:
  22. //   - --- --    ---    ---
  23. /////////////////////////////////////////////////////////////////// */
  24. #ifndef __DOS_OS2_CODE_INCLUDED
  25. #define __DOS_OS2_CODE_INCLUDED
  26.  
  27. #ifdef UNIXSLASH
  28. const char SlashChar[2] = "/";
  29. #else
  30. const char SlashChar[2] = "\\";
  31. #endif
  32. extern char *get_cwd (void);
  33.  
  34. int NumLock_Is_Gold = 0;           /* map numlock key to F1 */
  35. int PC_Alt_Char = 27;
  36.  
  37. void sys_flush (int dummy)
  38. {
  39.    (void) dummy;
  40. }
  41.  
  42. /* Delete the file NAME.  returns 0 on failure, 1 on sucess
  43.  * Under OS/2 and DOS, unlink()[UNIX] and remove()[ANSI] are equivalent.
  44.  */
  45.  
  46. int sys_delete_file(char *name)
  47. {
  48.     return(1 + remove(name));
  49. }
  50.  
  51. /* Rename the file or directory OLDNAME to NEWNAME.  Moving a file
  52.  * to a different directory on the same drive is possible.
  53.  * returns 0 on success and -1 on error
  54.  */
  55.  
  56. int sys_rename(char *oldname, char *newname)
  57. {
  58.     return(rename(oldname,newname));
  59. }
  60.  
  61. /* find shell (once only) */
  62. static char *shell = NULL, *shell_switch = NULL;
  63. static void discover_shell(void)
  64. {
  65.    if ( shell != NULL )  return;
  66. #ifdef SH_SHELL                   /* maybe some day ... */
  67.    shell_switch = "-c";
  68.    if ( (shell = getenv("SHELL")) != NULL )  return;
  69. #endif
  70.    shell_switch = "/c";
  71.    if ( (shell = getenv("COMSPEC")) != NULL ) return;
  72. #ifdef __os2__   
  73.    shell = "cmd.exe";               /* absolute last resort! */
  74. #else
  75.    shell = "command.com";           /* absolute last resort! */   
  76. #endif
  77. }
  78.  
  79.  
  80.  
  81. /* ///////////////////////////////////////////////////////////////////
  82. //  Function:   static int parse_command_line( int *argc, char ***argv,
  83. //                           char **fname,
  84. //                           char *command_line );
  85. //  Descript:    parse command_line
  86. //
  87. //  Returns:    the handles to redirect
  88. //
  89. //  Caveat:    requires spaces to separate each argument
  90. //        ie., args>filename    will NOT work
  91. ///////////////////////////////////////////////////////////////////// */
  92. #define DIRECT_SPAWN 0x1000           /* some arbitrary number */
  93. static int
  94. parse_command_line( int *argc, char ***argv, char **fname, char *command_line )
  95. {
  96.    int count, handles = 0;
  97.    char *pt;
  98.  
  99.    discover_shell();               /* find which shell to use */
  100.    while ( (*command_line != '\0') && (*command_line == ' '))
  101.      command_line++;               /* start on 1st non-space */
  102.  
  103.    if ( *command_line == '!' ) {
  104.       handles = DIRECT_SPAWN;
  105.       command_line++;               /* advance past '!' */
  106.       while ((*command_line != '\0') && (*command_line == ' '))
  107.           command_line++;               /* start on next non-space */
  108.    }
  109.  
  110.    pt = command_line;
  111.    count = 0;
  112.    while ( *pt != '\0' ) {
  113.       count++;                   /* this is an argument */
  114.       while ((*pt != '\0') && (*pt != ' '))  
  115.     {
  116.        if ( *pt == '|' )           /* cannot spawn directly */
  117.          handles = 0;               /* need shell for pipes */
  118.        pt++;                   /* advance until a space */
  119.       }
  120.       while ( *pt == ' '  )
  121.           pt++;                   /* advance until a non-space */
  122.    }
  123.  
  124.    *argv = (char **) SLMALLOC( (count+3) * sizeof(char *) );
  125.    if ( *argv == NULL )
  126.      return 0;                   /* malloc error */
  127.  
  128.    *argc = 0;   
  129.    if ( !(handles & DIRECT_SPAWN) ) {
  130.       (*argv)[ *argc ] = shell;
  131.       (*argc)++;
  132.       if ( count > 0 )  {
  133.      (*argv)[ *argc ] = shell_switch;
  134.      (*argc)++;
  135.       }
  136.       count += (*argc);
  137.    }
  138.  
  139.    pt = command_line;
  140.    while ((*argc < count) && (*pt != '\0')) {
  141.       (*argv)[ *argc ] = pt;
  142.       (*argc)++;
  143.       while ( *pt != '\0' && *pt != ' ' )
  144.           pt++;            /* advance until a space */
  145.       if ( *pt != '\0' )
  146.           *(pt++) = '\0';        /* parse argument here */
  147.       while ( *pt == ' ')
  148.           pt++;                /* advance until a non-space */
  149.    }
  150.    (*argv) [ *argc ] = (char *) NULL;    /* NULL terminated list */
  151.  
  152. /*  now examine the arguments for '>' redirect */
  153.  
  154.    for ( count = 0; count < *argc; count++ ) {
  155.       for ( pt = (*argv)[count]; *pt && *pt != '>'; pt++ )
  156.      /* find '>' char */;
  157.       if ( *pt == '>' ) {
  158.      if ( pt == (*argv)[count] ) {
  159.         handles |= 0x01;
  160.      } else {
  161.         switch ( *(--pt) ) {
  162.          case '1':
  163.            handles |= 0x01;
  164.            break;
  165.          case '2':
  166.            handles |= 0x02;
  167.            break;
  168.          case '&':
  169.            handles |= 0x03;
  170.            break;
  171.         }
  172.      }
  173.      (*argv)[count] = NULL;        /* remove from the list */
  174.      count++;            /* file name follows '>' */
  175.      if ( (*argv)[count] != NULL )
  176.        *fname = (*argv)[count];
  177.       }
  178.    }
  179.    if ((*fname == NULL) || (**fname == '\0' ))
  180.      handles = 0x00;        /* don't redirect if there is no name */
  181.  
  182.    return handles;
  183. }
  184.  
  185.  
  186. /* ///////////////////////////////////////////////////////////////////
  187. //  Function:   int sys_System(char *command_line);
  188. //
  189. //  Descript:    shell wrapper that understands some common redirection syntax
  190. //        command args  > filename        ; stdout
  191. //        command args 1> filename        ; stdout
  192. //        command args 2> filename        ; stderr
  193. //        command args &> filename        ; stdout+stderr
  194. //        command args  > filename 2>&1        ; stdout+stderr
  195. //
  196. // additionally, if command is prefixed by a '!', then the command is
  197. // spawned directly without invoking the shell
  198. //
  199. //  Returns:    returns error codes as per spawn*()
  200. //
  201. //  Caveat:    requires spaces to separate each argument
  202. //        ie., command args>filename    will NOT work
  203. ///////////////////////////////////////////////////////////////////// */
  204.  
  205. int
  206. sys_System(char *command_line1)
  207. {
  208.    int ret, handles, argc = 0;
  209.    char *fname = NULL, **argv = NULL, *command_line;
  210.   
  211.    if (NULL == (command_line = (char *) SLMALLOC (strlen (command_line1) + 1)))
  212.      {
  213.     msg_error ("Malloc error.");
  214.     return -1;
  215.      }
  216.    
  217.    strcpy (command_line, command_line1);
  218.  
  219.    handles = parse_command_line( &argc, &argv, &fname, command_line );
  220.    if ( (handles & 0x01) && (freopen(fname, "at",  stdout) == NULL) )
  221.      msg_error( "Couldn\'t redirect <stdout>" );
  222.    if ( (handles & 0x02) && (freopen(fname, "at",  stderr) == NULL) )
  223.      msg_error( "Couldn\'t redirect <stderr>" );
  224.  
  225.    ret = spawnvp(P_WAIT, argv[0], (void *) argv);
  226.    if ( -1 == ret ) {
  227.       switch(errno) {
  228.        case ENOENT:
  229.      if ( handles & DIRECT_SPAWN ) msg_error("Command not found.");
  230.      else msg_error("Shell not found.");
  231.      break;
  232.        case ENOMEM:
  233.      msg_error("Insufficient Memory.");
  234.      break;
  235.        default:
  236.      msg_error("Unknown Error.");
  237.       }
  238.    }
  239.  
  240.    if ( (handles & 0x01) && (freopen("con", "at",  stdout) == NULL) )
  241.      exit_error( "Couldn\'t reattach <stdout> to console", 1 );
  242.    if ( (handles & 0x02) && (freopen("con", "at",  stderr) == NULL) )
  243.      exit_error( "Couldn\'t reattach <stderr> to console", 1 );
  244.  
  245.    if ( argc ) SLFREE( argv );
  246.    
  247.    SLFREE (command_line);
  248.    return ret;
  249. }
  250.  
  251.  
  252. void sys_suspend(void)
  253. {
  254.    sys_System( "" );
  255. }
  256.  
  257. #endif    /* whole file */
  258.