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