home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / useful / text / show / less / source / source.lha / os.c < prev    next >
C/C++ Source or Header  |  1993-01-24  |  7KB  |  309 lines

  1. /*
  2.  * Operating system dependent routines.
  3.  *
  4.  * Most of the stuff in here is based on Unix, but an attempt
  5.  * has been made to make things work on other operating systems.
  6.  * This will sometimes result in a loss of functionality, unless
  7.  * someone rewrites code specifically for the new operating system.
  8.  *
  9.  * The makefile provides defines to decide whether various
  10.  * Unix features are present.
  11.  */
  12.  
  13. #include "less.h"
  14.  
  15. #include <signal.h>
  16.  
  17. #ifdef AMIGA
  18. #ifndef STAT
  19. #define STAT 1
  20. #endif
  21. #endif
  22.  
  23. #if EDITOR || SHELL_ESCAPE
  24. char *getenv();
  25.  
  26. /*
  27.  * Pass the specified command to a shell to be executed.
  28.  * Like plain "system()", but handles resetting terminal modes, etc.
  29.  */
  30.         public void
  31. lsystem(cmd)
  32.         char *cmd;
  33. {
  34.         int inp;
  35.         char cmdbuf[256];
  36.         char *shell;
  37.  
  38.         /*
  39.          * Print the command which is to be executed,
  40.          * unless the command starts with a "-".
  41.          */
  42.         if (cmd[0] == '-')
  43.                 cmd++;
  44.         else
  45.         {
  46.                 lower_left();
  47.                 clear_eol();
  48.                 putstr("!");
  49.                 putstr(cmd);
  50.                 putstr("\n");
  51.         }
  52.  
  53.         /*
  54.          * De-initialize the terminal and take out of raw mode.
  55.          */
  56.         deinit();
  57.         flush();
  58.         raw_mode(0);
  59.  
  60. #ifdef AMIGA
  61.         {
  62.         extern long tty;
  63.  
  64.         if (called_from_WB)
  65.                 error("can't execute a CLI command from Workbench, sorry!");
  66.         else
  67.                 if (cmd && *cmd)
  68.                         /* run a one shot */
  69.                         Execute(cmd, 0L, tty);
  70.         }
  71. #else
  72.         /*
  73.          * Restore signals to their defaults.
  74.          */
  75.         SIGNAL(SIGINT, SIG_DFL);
  76. #ifdef SIGTSTP
  77.         SIGNAL(SIGTSTP, SIG_DFL);
  78. #endif
  79.         /*
  80.          * Force standard input to be the terminal, "/dev/tty",
  81.          * even if less's standard input is coming from a pipe.
  82.          */
  83.         inp = dup(0);
  84.         close(0);
  85.         if (open("/dev/tty", 0) < 0)
  86.                 dup(inp);
  87.  
  88.         /*
  89.          * Pass the command to the system to be executed.
  90.          */
  91.         if ((shell = getenv("SHELL")) != NULL)
  92.         {
  93.                 sprintf(cmdbuf, "%s -c \"%s\"", shell, cmd);
  94.                 cmd = cmdbuf;
  95.         }
  96.         system(cmd);
  97.  
  98.         /*
  99.          * Restore standard input, reset signals, raw mode, etc.
  100.          */
  101.         close(0);
  102.         dup(inp);
  103.         close(inp);
  104.  
  105.         init_signals();
  106.         raw_mode(1);
  107.         init();
  108. #endif
  109. }
  110. #endif
  111.  
  112.  
  113. /*
  114.  * Expand a filename, substituting any environment variables, etc.
  115.  * The implementation of this is necessarily very operating system
  116.  * dependent.  This implementation is unabashedly only for Unix systems.
  117.  */
  118. #if GLOB
  119.  
  120. #include <stdio.h>
  121. FILE *popen();
  122.  
  123.         public char *
  124. glob(filename)
  125.         char *filename;
  126. {
  127.         FILE *f;
  128.         char *p;
  129.         int ch;
  130.         static char ECHO[] = "echo ";
  131.         static char filebuf[FILENAME+sizeof(ECHO)+1];
  132.  
  133.         if (filename[0] == '#')
  134.                 return (filename);
  135.         strcpy(filebuf, ECHO);
  136.         strtcpy(filebuf+sizeof(ECHO)-1, filename, sizeof(filebuf)-sizeof(ECHO));
  137.         if ((f = popen(filebuf, "r")) == NULL)
  138.                 return (filename);
  139.         for (p = filebuf;  p < &filebuf[sizeof(filebuf)-1];  p++)
  140.         {
  141.                 if ((ch = getc(f)) == '\n' || ch == EOF)
  142.                         break;
  143.                 *p = ch;
  144.         }
  145.         *p = '\0';
  146.         pclose(f);
  147.         return (filebuf);
  148. }
  149.  
  150. #else
  151.  
  152. #ifdef __STDC__
  153. char *glob (char *filename)
  154. #else
  155.         public char *
  156. glob(filename)
  157.         char *filename;
  158. #endif
  159. {
  160.         return (filename);
  161. }
  162.  
  163. #endif
  164.  
  165.  
  166. /*
  167.  * Returns NULL if the file can be opened and
  168.  * is an ordinary file, otherwise an error message
  169.  * (if it cannot be opened or is a directory, etc.)
  170.  */
  171.  
  172. #if STAT
  173.  
  174. #include <sys/types.h>
  175. #include <sys/stat.h>
  176.  
  177. static char *stat_erm
  178.     __PROTO((char *filename, char *message, int len, char *erm));
  179.  
  180.  
  181. #ifdef __STDC__
  182. char *bad_file (char *filename, char *message, int len)
  183. #else
  184.         public char *
  185. bad_file(filename, message, len)
  186.         char *filename;
  187.         char *message;
  188.         int len;
  189. #endif
  190. {
  191.         struct stat statbuf;
  192.  
  193. #ifdef AMIGA
  194.         /* On the Amiga, you can't stat a pipe: file, for some reason */
  195.         if (strnicmp(filename, "pipe:", 5) == 0)  /* kludge! */
  196.                 return NULL;
  197. #endif
  198.         if (stat(filename, &statbuf) < 0)
  199.                 return (errno_message(filename, message, len));
  200.         if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
  201.         {
  202. #ifdef AMIGA
  203.                 return stat_erm(filename, message, len, " is a directory");
  204. #else
  205.                 static char is_dir[] = " is a directory";
  206.                 strtcpy(message, filename, len-sizeof(is_dir)-1);
  207.                 strcat(message, is_dir);
  208.                 return (message);
  209. #endif
  210.         }
  211.         if ((statbuf.st_mode & S_IFMT) != S_IFREG)
  212.         {
  213. #ifdef AMIGA
  214.                 return stat_erm
  215.                     (filename, message, len, " is not a regular file");
  216. #else
  217.                 static char not_reg[] = " is not a regular file";
  218.                 strtcpy(message, filename, len-sizeof(not_reg)-1);
  219.                 strcat(message, not_reg);
  220.                 return (message);
  221. #endif
  222.         }
  223. #ifdef AMIGA
  224.         if (!(statbuf.st_mode & S_IREAD))
  225.                 return
  226.                     stat_erm(filename, message, len, " is read-protected");
  227. #endif
  228.         return (NULL);
  229. }
  230.  
  231. #ifdef AMIGA
  232. static char *stat_erm(char *filename, char *message, int len, char *erm)
  233. {
  234.         strtcpy(message, filename, len - strlen(erm));
  235.         strcat(message, erm);
  236.         return (message);
  237. }
  238. #endif
  239.  
  240. #else
  241.  
  242. #ifdef __STDC__
  243. char *bad_file (char *filename, char *message, int len)
  244. #else
  245.         public char *
  246. bad_file(filename, message, len)
  247.         char *filename;
  248.         char *message;
  249.         int len;
  250. #endif
  251. {
  252.         return (NULL);
  253. }
  254.  
  255. #endif
  256.  
  257. /*
  258.  * Return an error message based on the value of "errno".
  259.  */
  260.  
  261. #if PERROR
  262.  
  263. #ifdef __STDC__
  264. char *errno_message (char *filename, char *message, int len)
  265. #else
  266.         public char *
  267. errno_message(filename, message, len)
  268.         char *filename;
  269.         char *message;
  270.         int len;
  271. #endif
  272. {
  273.         char *p;
  274.         static char msg[16];
  275.  
  276.         extern char *__sys_errlist[];
  277.         extern int __sys_nerr;
  278.         extern int errno;
  279.  
  280.         if (errno < __sys_nerr)
  281.                 p = __sys_errlist[errno];
  282.         else
  283.         {
  284.                 sprintf(msg, "Error %ld", errno);
  285.                 p = msg;
  286.         }
  287.         strtcpy(message, filename, len-strlen(p)-3);
  288.         strcat(message, ": ");
  289.         strcat(message, p);
  290.         return (message);
  291. }
  292.  
  293. #else
  294.  
  295.         public char *
  296. errno_message(filename, message, len)
  297.         char *filename;
  298.         char *message;
  299.         int len;
  300. {
  301.         static char msg[] = ": cannot open";
  302.  
  303.         strtcpy(message, filename, len-sizeof(msg)-1);
  304.         strcat(message, msg);
  305.         return (message);
  306. }
  307.  
  308. #endif
  309.