home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / less_332.lzh / less_332 / os.c < prev    next >
Text File  |  1998-03-03  |  6KB  |  309 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994,1995,1996  Mark Nudelman
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice in the documentation and/or other materials provided with 
  12.  *    the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
  15.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  17.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
  18.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  19.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
  20.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
  21.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  22.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
  23.  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 
  24.  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Operating system dependent routines.
  30.  *
  31.  * Most of the stuff in here is based on Unix, but an attempt
  32.  * has been made to make things work on other operating systems.
  33.  * This will sometimes result in a loss of functionality, unless
  34.  * someone rewrites code specifically for the new operating system.
  35.  *
  36.  * The makefile provides defines to decide whether various
  37.  * Unix features are present.
  38.  */
  39.  
  40. #include "less.h"
  41. #include <signal.h>
  42. #include <setjmp.h>
  43. #if HAVE_TIME_H
  44. #include <time.h>
  45. #endif
  46. #if HAVE_ERRNO_H
  47. #include <errno.h>
  48. #endif
  49. #if HAVE_VALUES_H
  50. #include <values.h>
  51. #endif
  52. #if HAVE_LIMITS_H
  53. #include <limits.h>
  54. #endif
  55.  
  56. #if HAVE_TIME_T
  57. #define time_type    time_t
  58. #else
  59. #define    time_type    long
  60. #endif
  61.  
  62. /*
  63.  * BSD setjmp() saves (and longjmp() restores) the signal mask.
  64.  * This costs a system call or two per setjmp(), so if possible we clear the
  65.  * signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead.
  66.  * On other systems, setjmp() doesn't affect the signal mask and so
  67.  * _setjmp() does not exist; we just use setjmp().
  68.  */
  69. #if HAVE__SETJMP && HAVE_SIGSETMASK
  70. #define SET_JUMP    _setjmp
  71. #define LONG_JUMP    _longjmp
  72. #else
  73. #define SET_JUMP    setjmp
  74. #define LONG_JUMP    longjmp
  75. #endif
  76.  
  77. public int reading;
  78.  
  79. static jmp_buf read_label;
  80.  
  81. extern int sigs;
  82.  
  83. /*
  84.  * Like read() system call, but is deliberately interruptible.
  85.  * A call to intread() from a signal handler will interrupt
  86.  * any pending iread().
  87.  */
  88.     public int
  89. iread(fd, buf, len)
  90.     int fd;
  91.     char *buf;
  92.     unsigned int len;
  93. {
  94.     register int n;
  95.  
  96. #if MSDOS_COMPILER==WIN32C
  97.     if (ABORT_SIGS())
  98.         return (READ_INTR);
  99. #else
  100. #if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
  101.     if (kbhit())
  102.     {
  103.         int c;
  104.         
  105.         c = getch();
  106.         if (c == '\003')
  107.             return (READ_INTR);
  108.         ungetch(c);
  109.     }
  110. #endif
  111. #endif
  112.     if (SET_JUMP(read_label))
  113.     {
  114.         /*
  115.          * We jumped here from intread.
  116.          */
  117.         reading = 0;
  118. #if HAVE_SIGSETMASK
  119.         sigsetmask(0);
  120. #else
  121. #ifdef _OSK
  122.         sigmask(~0);
  123. #endif
  124. #endif
  125.         return (READ_INTR);
  126.     }
  127.  
  128.     flush();
  129.     reading = 1;
  130. #if MSDOS_COMPILER==DJGPPC
  131.     if (isatty(fd))
  132.     {
  133.         /*
  134.          * Don't try reading from a TTY until a character is
  135.          * available, because that makes some background programs
  136.          * believe DOS is busy in a way that prevents those
  137.          * programs from working while "less" waits.
  138.          */
  139.         fd_set readfds;
  140.  
  141.         FD_ZERO(&readfds);
  142.         FD_SET(fd, &readfds);
  143.         if (select(fd+1, &readfds, 0, 0, 0) == -1)
  144.             return (-1);
  145.     }
  146. #endif
  147.     n = read(fd, buf, len);
  148.     reading = 0;
  149.     if (n < 0)
  150.         return (-1);
  151.     return (n);
  152. }
  153.  
  154. /*
  155.  * Interrupt a pending iread().
  156.  */
  157.     public void
  158. intread()
  159. {
  160.     LONG_JUMP(read_label, 1);
  161. }
  162.  
  163. /*
  164.  * Return the current time.
  165.  */
  166. #if HAVE_TIME
  167.     public long
  168. get_time()
  169. {
  170.     time_type t;
  171.  
  172.     time(&t);
  173.     return (t);
  174. }
  175. #endif
  176.  
  177.  
  178. #if !HAVE_STRERROR
  179. /*
  180.  * Local version of strerror, if not available from the system.
  181.  */
  182.     static char *
  183. strerror(err)
  184.     int err;
  185. {
  186. #if HAVE_SYS_ERRLIST
  187.     static char buf[16];
  188.     extern char *sys_errlist[];
  189.     extern int sys_nerr;
  190.   
  191.     if (err < sys_nerr)
  192.         return sys_errlist[err];
  193.     sprintf(buf, "Error %d", err);
  194.     return buf;
  195. #else
  196.     return ("cannot open");
  197. #endif
  198. }
  199. #endif
  200.  
  201. /*
  202.  * errno_message: Return an error message based on the value of "errno".
  203.  */
  204.     public char *
  205. errno_message(filename)
  206.     char *filename;
  207. {
  208.     register char *p;
  209.     register char *m;
  210. #if HAVE_ERRNO
  211. #if MUST_DEFINE_ERRNO
  212.     extern int errno;
  213. #endif
  214.     p = strerror(errno);
  215. #else
  216.     p = "cannot open";
  217. #endif
  218.     m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
  219.     sprintf(m, "%s: %s", filename, p);
  220.     return (m);
  221. }
  222.  
  223. /*
  224.  * Return the largest possible number that can fit in a long.
  225.  */
  226.     static long
  227. get_maxlong()
  228. {
  229. #ifdef LONG_MAX
  230.     return (LONG_MAX);
  231. #else
  232. #ifdef MAXLONG
  233.     return (MAXLONG);
  234. #else
  235.     long n, n2;
  236.  
  237.     /*
  238.      * Keep doubling n until we overflow.
  239.      * {{ This actually only returns the largest power of two that
  240.      *    can fit in a long, but percentage() doesn't really need
  241.      *    it any more accurate than that. }}
  242.      */
  243.     n2 = 128;  /* Hopefully no maxlong is less than 128! */
  244.     do {
  245.         n = n2;
  246.         n2 *= 2;
  247.     } while (n2 / 2 == n);
  248.     return (n);
  249. #endif
  250. #endif
  251. }
  252.  
  253. /*
  254.  * Return the ratio of two POSITIONS, as a percentage.
  255.  * {{ Assumes a POSITION is a long int. }}
  256.  */
  257.     public int
  258. percentage(num, den)
  259.     POSITION num, den;
  260. {
  261.     if (num <= get_maxlong() / 100)
  262.         return ((100 * num) / den);
  263.     else
  264.         return (num / (den / 100));
  265. }
  266.  
  267. /*
  268.  * Return the specified percentage of a POSITION.
  269.  * {{ Assumes a POSITION is a long int. }}
  270.  */
  271.     public POSITION
  272. percent_pos(pos, percent)
  273.     POSITION pos;
  274.     int percent;
  275. {
  276.     if (pos <= get_maxlong() / 100)
  277.         return ((percent * pos) / 100);
  278.     else
  279.         return (percent * (pos / 100));
  280. }
  281.  
  282. #ifdef _OSK_MWC32
  283.  
  284. /*
  285.  * This implements an ANSI-style intercept setup for Microware C 3.2
  286.  */
  287.     public int 
  288. os9_signal(type, handler)
  289.     int type;
  290.     RETSIGTYPE (*handler)();
  291. {
  292.     intercept(handler);
  293. }
  294.  
  295. #include <sgstat.h>
  296.  
  297.     public int 
  298. isatty(f)
  299.     int f;
  300. {
  301.     struct sgbuf sgbuf;
  302.  
  303.     if (_gs_opt(f, &sgbuf) < 0)
  304.         return -1;
  305.     return (sgbuf.sg_class == 0);
  306. }
  307.     
  308. #endif
  309.