home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / os2 / less / lsystem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-27  |  6.1 KB  |  328 lines

  1. /*
  2.  * Routines to execute other programs.
  3.  * Necessarily very OS dependent.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <signal.h>
  8.  
  9. #include "less.h"
  10. #include "position.h"
  11.  
  12. #if __MSDOS__
  13. #include <process.h>
  14. #include <dos.h>
  15. #include <fcntl.h>
  16. #include <io.h>
  17. #include <errno.h>
  18. #include <dir.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <time.h>
  22. #include <ctype.h>
  23. char get_swchar();
  24. void swchar_to_dos();
  25. void swchar_to_unix();
  26. #endif
  27.  
  28. #ifdef OS2
  29. #include <process.h>
  30. extern int _osmode;
  31. #define DOS_MODE 0
  32. #endif
  33.  
  34. extern char *getenv();
  35.  
  36. extern int screen_trashed;
  37. extern IFILE curr_ifile;
  38.  
  39.  
  40. /*
  41.  * Pass the specified command to a shell to be executed.
  42.  * Like plain "system()", but handles resetting terminal modes, etc.
  43.  */
  44.     public void
  45. lsystem(cmd)
  46.     char *cmd;
  47. {
  48.     register int inp;
  49.     register char *shell;
  50.     register char *p;
  51.     register char *curr_filename;
  52.  
  53.     /*
  54.      * Print the command which is to be executed,
  55.      * unless the command starts with a "-".
  56.      */
  57.     if (cmd[0] == '-')
  58.         cmd++;
  59.     else
  60.     {
  61.         lower_left();
  62.         clear_eol();
  63.         putstr("!");
  64.         putstr(cmd);
  65.         putstr("\n");
  66.     }
  67.  
  68.     /*
  69.      * Close the current input file.
  70.      */
  71.     curr_filename = get_filename(curr_ifile);
  72.     (void) edit(NULL, 0);
  73.  
  74.     /*
  75.      * De-initialize the terminal and take out of raw mode.
  76.      */
  77.     deinit();
  78.     flush();    /* Make sure the deinit chars get out */
  79.     raw_mode(0);
  80.  
  81.     /*
  82.      * Restore signals to their defaults.
  83.      */
  84.     init_signals(0);
  85.  
  86.     /*
  87.      * Force standard input to be the user's terminal
  88.      * (the normal standard input), even if less's standard input
  89.      * is coming from a pipe.
  90.      */
  91. #if __MSDOS__
  92. {
  93.     register int inp2;
  94.  
  95.     inp = dup(0);
  96.     inp2 = open("CON", O_TEXT|O_RDONLY);
  97.     dup2(0,inp2);
  98. }
  99. #else
  100.     inp = dup(0);
  101.     close(0);
  102. #ifdef OS2
  103.         if (open("con", 0) < 0)
  104. #else
  105.     if (open("/dev/tty", 0) < 0)
  106. #endif
  107.         dup(inp);
  108. #endif
  109.  
  110.     /*
  111.      * Pass the command to the system to be executed.
  112.      * If we have a SHELL environment variable, use
  113.      * <$SHELL -c "command"> instead of just <command>.
  114.      * If the command is empty, just invoke a shell.
  115.      */
  116. #if __MSDOS__
  117. {
  118.     int result;
  119.     char sw_char;
  120.  
  121.     sw_char = get_swchar();
  122.     swchar_to_dos();
  123.     result = system(cmd);
  124.     if (result != 0)
  125.         perror("less");
  126.     if (sw_char == '-')
  127.         swchar_to_unix();
  128. }
  129. #else
  130.     p = NULL;
  131. #ifdef OS2
  132.         if ( *cmd == 0 )
  133.         {
  134.           if ( (p = getenv("COMSPEC")) == NULL )
  135.             p = (_osmode == DOS_MODE) ? "COMMAND" : "CMD";
  136.  
  137.           spawnlp(P_WAIT, p, p, NULL);
  138.         }
  139.         else
  140.           system(cmd);
  141. #else
  142.     if ((shell = getenv("SHELL")) != NULL && *shell != '\0')
  143.     {
  144.         if (*cmd == '\0')
  145.             p = save(shell);
  146.         else
  147.         {
  148.             p = (char *) ecalloc(strlen(shell) + strlen(cmd) + 7,
  149.                     sizeof(char));
  150.             sprintf(p, "%s -c \"%s\"", shell, cmd);
  151.         }
  152.     }
  153.     if (p == NULL)
  154.     {
  155.         if (*cmd == '\0')
  156.             p = save("sh");
  157.         else
  158.             p = save(cmd);
  159.     }
  160.  
  161.     system(p);
  162.     free(p);
  163. #endif
  164. #endif
  165.  
  166.     /*
  167.      * Restore standard input, reset signals, raw mode, etc.
  168.      */
  169. #if __MSDOS__
  170.     close(inp2);
  171.     dup2(0,inp);
  172.     close(inp);
  173. #else
  174.     close(0);
  175.     dup(inp);
  176.     close(inp);
  177. #endif
  178.  
  179.     init_signals(1);
  180.     raw_mode(1);
  181.     init();
  182.     screen_trashed = 1;
  183.  
  184.     /*
  185.      * Reopen the current input file.
  186.      */
  187.     (void) edit(curr_filename, 0);
  188.  
  189. #if defined(SIGWINCH) || defined(SIGWIND)
  190.     /*
  191.      * Since we were ignoring window change signals while we executed
  192.      * the system command, we must assume the window changed.
  193.      * Warning: this leaves a signal pending (in "sigs"),
  194.      * so psignals() should be called soon after lsystem().
  195.      */
  196.     winch();
  197. #endif
  198. }
  199.  
  200. #if PIPEC
  201.  
  202. /*
  203.  * Pipe a section of the input file into the given shell command.
  204.  * The section to be piped is the section "between" the current
  205.  * position and the position marked by the given letter.
  206.  *
  207.  * The "current" position means the top line displayed if the mark
  208.  * is after the current screen, or the bottom line displayed if
  209.  * the mark is before the current screen.
  210.  * If the mark is on the current screen, the whole screen is displayed.
  211.  */
  212.     public int
  213. pipe_mark(c, cmd)
  214.     int c;
  215.     char *cmd;
  216. {
  217.     POSITION mpos, tpos, bpos;
  218.  
  219.     /*
  220.      * mpos = the marked position.
  221.      * tpos = top of screen.
  222.      * bpos = bottom of screen.
  223.      */
  224.     mpos = markpos(c);
  225.     if (mpos == NULL_POSITION)
  226.         return (-1);
  227.     tpos = position(TOP);
  228.     if (tpos == NULL_POSITION)
  229.         tpos = ch_zero();
  230.     bpos = position(BOTTOM);
  231.  
  232.      if (c == '.')
  233.          return (pipe_data(cmd, tpos, bpos));
  234.      else if (mpos <= tpos)
  235.          return (pipe_data(cmd, mpos, tpos));
  236.      else if (bpos == NULL_POSITION)
  237.          return (pipe_data(cmd, tpos, bpos));
  238.      else
  239.          return (pipe_data(cmd, tpos, mpos));
  240. }
  241.  
  242. /*
  243.  * Create a pipe to the given shell command.
  244.  * Feed it the file contents between the positions spos and epos.
  245.  */
  246.     public int
  247. pipe_data(cmd, spos, epos)
  248.     char *cmd;
  249.     POSITION spos;
  250.     POSITION epos;
  251. {
  252.     register FILE *f;
  253.     register int c;
  254.     extern FILE *popen();
  255.  
  256.     /*
  257.      * This is structured much like lsystem().
  258.      * Since we're running a shell program, we must be careful
  259.      * to perform the necessary deinitialization before running
  260.      * the command, and reinitialization after it.
  261.      */
  262.     if (ch_seek(spos) != 0)
  263.     {
  264.         error("Cannot seek to start position", NULL_PARG);
  265.         return (-1);
  266.     }
  267.  
  268.     if ((f = popen(cmd, "w")) == NULL)
  269.     {
  270.         error("Cannot create pipe", NULL_PARG);
  271.         return (-1);
  272.     }
  273.     lower_left();
  274.     clear_eol();
  275.     putstr("!");
  276.     putstr(cmd);
  277.     putstr("\n");
  278.  
  279.     deinit();
  280.     flush();
  281.     raw_mode(0);
  282.     init_signals(0);
  283. #ifdef SIGPIPE
  284.     SIGNAL(SIGPIPE, SIG_IGN);
  285. #endif
  286.  
  287.     while (epos == NULL_POSITION || spos++ <= epos)
  288.     {
  289.         /*
  290.          * Read a character from the file and give it to the pipe.
  291.          */
  292.         c = ch_forw_get();
  293.         if (c == EOI)
  294.             break;
  295.         if (putc(c, f) == EOF)
  296.             break;
  297.     }
  298.  
  299.     /*
  300.      * Finish up the last line.
  301.      */
  302.      while (c != '\n' && c != EOI )
  303.      {
  304.          c = ch_forw_get();
  305.          if (c == EOI)
  306.              break;
  307.          if (putc(c, f) == EOF)
  308.              break;
  309.      }
  310.  
  311.     pclose(f);
  312.  
  313. #ifdef SIGPIPE
  314.     SIGNAL(SIGPIPE, SIG_DFL);
  315. #endif
  316.     init_signals(1);
  317.     raw_mode(1);
  318.     init();
  319.     screen_trashed = 1;
  320. #if defined(SIGWINCH) || defined(SIGWIND)
  321.     /* {{ Probably don't need this here. }} */
  322.     winch();
  323. #endif
  324.     return (0);
  325. }
  326.  
  327. #endif
  328.