[BACK]Return to lsystem.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Diff for /src/usr.bin/less/lsystem.c between version 1.9 and 1.10

version 1.9, 2014/04/25 13:38:21 version 1.10, 2015/11/05 22:08:44
Line 6 
Line 6 
  *   *
  * For more information, see the README file.   * For more information, see the README file.
  */   */
   /*
    * Modified for use with illumos.
    * Copyright 2014 Garrett D'Amore <garrett@damore.org>
    */
   
   
 /*  /*
  * Routines to execute other programs.   * Routines to execute other programs.
  * Necessarily very OS dependent.   * Necessarily very OS dependent.
Line 17 
Line 20 
 #include <signal.h>  #include <signal.h>
 #include "position.h"  #include "position.h"
   
 #if MSDOS_COMPILER  
 #include <dos.h>  
 #ifdef _MSC_VER  
 #include <direct.h>  
 #define setdisk(n) _chdrive((n)+1)  
 #else  
 #include <dir.h>  
 #endif  
 #endif  
   
 extern int screen_trashed;  extern int screen_trashed;
 extern IFILE curr_ifile;  extern IFILE curr_ifile;
   
   static int pipe_data(char *cmd, off_t spos, off_t epos);
   
 #if HAVE_SYSTEM  
   
 /*  /*
  * Pass the specified command to a shell to be executed.   * Pass the specified command to a shell to be executed.
  * Like plain "system()", but handles resetting terminal modes, etc.   * Like plain "system()", but handles resetting terminal modes, etc.
  */   */
         public void  void
 lsystem(cmd, donemsg)  lsystem(const char *cmd, const char *donemsg)
         char *cmd;  
         char *donemsg;  
 {  {
         register int inp;          int inp;
 #if HAVE_SHELL          char *shell;
         register char *shell;          char *p;
         register char *p;  
 #endif  
         IFILE save_ifile;          IFILE save_ifile;
 #if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C  
         char cwd[FILENAME_MAX+1];  
 #endif  
   
         /*          /*
          * Print the command which is to be executed,           * Print the command which is to be executed,
Line 58 
Line 43 
          */           */
         if (cmd[0] == '-')          if (cmd[0] == '-')
                 cmd++;                  cmd++;
         else          else {
         {  
                 clear_bot();                  clear_bot();
                 putstr("!");                  putstr("!");
                 putstr(cmd);                  putstr(cmd);
                 putstr("\n");                  putstr("\n");
         }          }
   
 #if MSDOS_COMPILER  
 #if MSDOS_COMPILER==WIN32C  
         if (*cmd == '\0')  
                 cmd = getenv("COMSPEC");  
 #else  
         /*          /*
          * Working directory is global on MSDOS.  
          * The child might change the working directory, so we  
          * must save and restore CWD across calls to "system",  
          * or else we won't find our file when we return and  
          * try to "reedit_ifile" it.  
          */  
         getcwd(cwd, FILENAME_MAX);  
 #endif  
 #endif  
   
         /*  
          * Close the current input file.           * Close the current input file.
          */           */
         save_ifile = save_curr_ifile();          save_ifile = save_curr_ifile();
Line 94 
Line 62 
         deinit();          deinit();
         flush();        /* Make sure the deinit chars get out */          flush();        /* Make sure the deinit chars get out */
         raw_mode(0);          raw_mode(0);
 #if MSDOS_COMPILER==WIN32C  
         close_getchr();  
 #endif  
   
         /*          /*
          * Restore signals to their defaults.           * Restore signals to their defaults.
          */           */
         init_signals(0);          init_signals(0);
   
 #if HAVE_DUP  
         /*          /*
          * Force standard input to be the user's terminal           * Force standard input to be the user's terminal
          * (the normal standard input), even if less's standard input           * (the normal standard input), even if less's standard input
          * is coming from a pipe.           * is coming from a pipe.
          */           */
         inp = dup(0);          inp = dup(0);
         close(0);          (void) close(0);
 #if OS2  
         /* The __open() system call translates "/dev/tty" to "con". */  
         if (__open("/dev/tty", OPEN_READ) < 0)  
 #else  
         if (open("/dev/tty", OPEN_READ) < 0)          if (open("/dev/tty", OPEN_READ) < 0)
 #endif                  (void) dup(inp);
                 dup(inp);  
 #endif  
   
         /*          /*
          * Pass the command to the system to be executed.           * Pass the command to the system to be executed.
Line 126 
Line 84 
          * <$SHELL -c "command"> instead of just <command>.           * <$SHELL -c "command"> instead of just <command>.
          * If the command is empty, just invoke a shell.           * If the command is empty, just invoke a shell.
          */           */
 #if HAVE_SHELL  
         p = NULL;          p = NULL;
         if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0')          if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0') {
         {                  if (*cmd == '\0') {
                 if (*cmd == '\0')  
                         p = save(shell);                          p = save(shell);
                 else                  } else {
                 {  
                         char *esccmd = shell_quote(cmd);                          char *esccmd = shell_quote(cmd);
                         if (esccmd != NULL)                          if (esccmd != NULL) {
                         {                                  p = easprintf("%s -c %s", shell, esccmd);
                                 size_t len = strlen(shell) + strlen(esccmd) + 5;  
                                 p = (char *) ecalloc(len, sizeof(char));  
                                 SNPRINTF3(p, len, "%s %s %s", shell, shell_coption(), esccmd);  
                                 free(esccmd);                                  free(esccmd);
                         }                          }
                 }                  }
         }          }
         if (p == NULL)          if (p == NULL) {
         {  
                 if (*cmd == '\0')                  if (*cmd == '\0')
                         p = save("sh");                          p = save("sh");
                 else                  else
                         p = save(cmd);                          p = save(cmd);
         }          }
         system(p);          (void) system(p);
         free(p);          free(p);
 #else  
 #if MSDOS_COMPILER==DJGPPC  
         /*  
          * Make stdin of the child be in cooked mode.  
          */  
         setmode(0, O_TEXT);  
         /*  
          * We don't need to catch signals of the child (it  
          * also makes trouble with some DPMI servers).  
          */  
         __djgpp_exception_toggle();  
         system(cmd);  
         __djgpp_exception_toggle();  
 #else  
         system(cmd);  
 #endif  
 #endif  
   
 #if HAVE_DUP  
         /*          /*
          * Restore standard input, reset signals, raw mode, etc.           * Restore standard input, reset signals, raw mode, etc.
          */           */
         close(0);          (void) close(0);
         dup(inp);          (void) dup(inp);
         close(inp);          (void) close(inp);
 #endif  
   
 #if MSDOS_COMPILER==WIN32C  
         open_getchr();  
 #endif  
         init_signals(1);          init_signals(1);
         raw_mode(1);          raw_mode(1);
         if (donemsg != NULL)          if (donemsg != NULL) {
         {  
                 putstr(donemsg);                  putstr(donemsg);
                 putstr("  (press RETURN)");                  putstr("  (press RETURN)");
                 get_return();                  get_return();
                 putchr('\n');                  (void) putchr('\n');
                 flush();                  flush();
         }          }
         init();          init();
         screen_trashed = 1;          screen_trashed = 1;
   
 #if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C  
         /*          /*
          * Restore the previous directory (possibly  
          * changed by the child program we just ran).  
          */  
         chdir(cwd);  
 #if MSDOS_COMPILER != DJGPPC  
         /*  
          * Some versions of chdir() don't change to the drive  
          * which is part of CWD.  (DJGPP does this in chdir.)  
          */  
         if (cwd[1] == ':')  
         {  
                 if (cwd[0] >= 'a' && cwd[0] <= 'z')  
                         setdisk(cwd[0] - 'a');  
                 else if (cwd[0] >= 'A' && cwd[0] <= 'Z')  
                         setdisk(cwd[0] - 'A');  
         }  
 #endif  
 #endif  
   
         /*  
          * Reopen the current input file.           * Reopen the current input file.
          */           */
         reedit_ifile(save_ifile);          reedit_ifile(save_ifile);
   
 #if defined(SIGWINCH) || defined(SIGWIND)  
         /*          /*
          * Since we were ignoring window change signals while we executed           * Since we were ignoring window change signals while we executed
          * the system command, we must assume the window changed.           * the system command, we must assume the window changed.
          * Warning: this leaves a signal pending (in "sigs"),           * Warning: this leaves a signal pending (in "sigs"),
          * so psignals() should be called soon after lsystem().           * so psignals() should be called soon after lsystem().
          */           */
         winch(0);          sigwinch(0);
 #endif  
 }  }
   
 #endif  
   
 #if PIPEC  
   
 /*  /*
  * Pipe a section of the input file into the given shell command.   * Pipe a section of the input file into the given shell command.
  * The section to be piped is the section "between" the current   * The section to be piped is the section "between" the current
Line 249 
Line 150 
  * If the mark is on the current screen, or if the mark is ".",   * If the mark is on the current screen, or if the mark is ".",
  * the whole current screen is piped.   * the whole current screen is piped.
  */   */
         public int  int
 pipe_mark(c, cmd)  pipe_mark(int c, char *cmd)
         int c;  
         char *cmd;  
 {  {
         POSITION mpos, tpos, bpos;          off_t mpos, tpos, bpos;
   
         /*          /*
          * mpos = the marked position.           * mpos = the marked position.
Line 262 
Line 161 
          * bpos = bottom of screen.           * bpos = bottom of screen.
          */           */
         mpos = markpos(c);          mpos = markpos(c);
         if (mpos == NULL_POSITION)          if (mpos == -1)
                 return (-1);                  return (-1);
         tpos = position(TOP);          tpos = position(TOP);
         if (tpos == NULL_POSITION)          if (tpos == -1)
                 tpos = ch_zero();                  tpos = ch_zero();
         bpos = position(BOTTOM);          bpos = position(BOTTOM);
   
         if (c == '.')          if (c == '.')
                 return (pipe_data(cmd, tpos, bpos));                  return (pipe_data(cmd, tpos, bpos));
         else if (mpos <= tpos)          else if (mpos <= tpos)
                 return (pipe_data(cmd, mpos, bpos));                  return (pipe_data(cmd, mpos, bpos));
         else if (bpos == NULL_POSITION)          else if (bpos == -1)
                 return (pipe_data(cmd, tpos, bpos));                  return (pipe_data(cmd, tpos, bpos));
         else          else
                 return (pipe_data(cmd, tpos, mpos));                  return (pipe_data(cmd, tpos, mpos));
 }  }
   
 /*  /*
  * Create a pipe to the given shell command.   * Create a pipe to the given shell command.
  * Feed it the file contents between the positions spos and epos.   * Feed it the file contents between the positions spos and epos.
  */   */
         public int  static int
 pipe_data(cmd, spos, epos)  pipe_data(char *cmd, off_t spos, off_t epos)
         char *cmd;  
         POSITION spos;  
         POSITION epos;  
 {  {
         register FILE *f;          FILE *f;
         register int c;          int c;
         extern FILE *popen();  
   
         /*          /*
          * This is structured much like lsystem().           * This is structured much like lsystem().
Line 299 
Line 194 
          * to perform the necessary deinitialization before running           * to perform the necessary deinitialization before running
          * the command, and reinitialization after it.           * the command, and reinitialization after it.
          */           */
         if (ch_seek(spos) != 0)          if (ch_seek(spos) != 0) {
         {  
                 error("Cannot seek to start position", NULL_PARG);                  error("Cannot seek to start position", NULL_PARG);
                 return (-1);                  return (-1);
         }          }
   
         if ((f = popen(cmd, "w")) == NULL)          if ((f = popen(cmd, "w")) == NULL) {
         {  
                 error("Cannot create pipe", NULL_PARG);                  error("Cannot create pipe", NULL_PARG);
                 return (-1);                  return (-1);
         }          }
Line 319 
Line 212 
         flush();          flush();
         raw_mode(0);          raw_mode(0);
         init_signals(0);          init_signals(0);
 #if MSDOS_COMPILER==WIN32C  
         close_getchr();  
 #endif  
 #ifdef SIGPIPE  
         LSIGNAL(SIGPIPE, SIG_IGN);          LSIGNAL(SIGPIPE, SIG_IGN);
 #endif  
   
         c = EOI;          c = EOI;
         while (epos == NULL_POSITION || spos++ <= epos)          while (epos == -1 || spos++ <= epos) {
         {  
                 /*                  /*
                  * Read a character from the file and give it to the pipe.                   * Read a character from the file and give it to the pipe.
                  */                   */
Line 342 
Line 229 
         /*          /*
          * Finish up the last line.           * Finish up the last line.
          */           */
         while (c != '\n' && c != EOI )          while (c != '\n' && c != EOI) {
         {                  c = ch_forw_get();
                 c = ch_forw_get();                  if (c == EOI)
                 if (c == EOI)                          break;
                         break;                  if (putc(c, f) == EOF)
                 if (putc(c, f) == EOF)                          break;
                         break;          }
         }  
   
         pclose(f);          (void) pclose(f);
   
 #ifdef SIGPIPE  
         LSIGNAL(SIGPIPE, SIG_DFL);          LSIGNAL(SIGPIPE, SIG_DFL);
 #endif  
 #if MSDOS_COMPILER==WIN32C  
         open_getchr();  
 #endif  
         init_signals(1);          init_signals(1);
         raw_mode(1);          raw_mode(1);
         init();          init();
         screen_trashed = 1;          screen_trashed = 1;
 #if defined(SIGWINCH) || defined(SIGWIND)  
         /* {{ Probably don't need this here. }} */          /* {{ Probably don't need this here. }} */
         winch(0);          sigwinch(0);
 #endif  
         return (0);          return (0);
 }  }
   
 #endif  

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10