home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / less-321-src.tgz / tar.out / fsf / less / os.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  286 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. /*
  82.  * Like read() system call, but is deliberately interruptible.
  83.  * A call to intread() from a signal handler will interrupt
  84.  * any pending iread().
  85.  */
  86.     public int
  87. iread(fd, buf, len)
  88.     int fd;
  89.     char *buf;
  90.     unsigned int len;
  91. {
  92.     register int n;
  93.  
  94. #if MSDOS_COMPILER
  95.     if (kbhit())
  96.     {
  97.         int c;
  98.         
  99.         c = getch();
  100.         if (c == '\003')
  101.             return (READ_INTR);
  102.         ungetch(c);
  103.     }
  104. #endif
  105.     if (SET_JUMP(read_label))
  106.     {
  107.         /*
  108.          * We jumped here from intread.
  109.          */
  110.         reading = 0;
  111. #if HAVE_SIGSETMASK
  112.         sigsetmask(0);
  113. #else
  114. #ifdef _OSK
  115.         sigmask(~0);
  116. #endif
  117. #endif
  118.         return (READ_INTR);
  119.     }
  120.  
  121.     flush();
  122.     reading = 1;
  123.     n = read(fd, buf, len);
  124.     reading = 0;
  125.     if (n < 0)
  126.         return (-1);
  127.     return (n);
  128. }
  129.  
  130. /*
  131.  * Interrupt a pending iread().
  132.  */
  133.     public void
  134. intread()
  135. {
  136.     LONG_JUMP(read_label, 1);
  137. }
  138.  
  139. /*
  140.  * Return the current time.
  141.  */
  142. #if HAVE_TIME
  143.     public long
  144. get_time()
  145. {
  146.     time_type t;
  147.  
  148.     time(&t);
  149.     return (t);
  150. }
  151. #endif
  152.  
  153.  
  154. #if !HAVE_STRERROR
  155. /*
  156.  * Local version of strerror, if not available from the system.
  157.  */
  158.     static char *
  159. strerror(err)
  160.     int err;
  161. {
  162. #if HAVE_SYS_ERRLIST
  163.     static char buf[16];
  164.     extern char *sys_errlist[];
  165.     extern int sys_nerr;
  166.   
  167.     if (err < sys_nerr)
  168.         return sys_errlist[err];
  169.     sprintf(buf, "Error %d", err);
  170.     return buf;
  171. #else
  172.     return ("cannot open");
  173. #endif
  174. }
  175. #endif
  176.  
  177. /*
  178.  * errno_message: Return an error message based on the value of "errno".
  179.  */
  180.     public char *
  181. errno_message(filename)
  182.     char *filename;
  183. {
  184.     register char *p;
  185.     register char *m;
  186. #if HAVE_ERRNO
  187. #if MUST_DEFINE_ERRNO
  188.     extern int errno;
  189. #endif
  190.     extern char *strerror (int); /* FIXME - use MUST_DEFINE_STRERROR? */
  191.     p = strerror(errno);
  192. #else
  193.     p = "cannot open";
  194. #endif
  195.     m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
  196.     sprintf(m, "%s: %s", filename, p);
  197.     return (m);
  198. }
  199.  
  200. /*
  201.  * Return the largest possible number that can fit in a long.
  202.  */
  203.     static long
  204. get_maxlong()
  205. {
  206. #ifdef LONG_MAX
  207.     return (LONG_MAX);
  208. #else
  209. #ifdef MAXLONG
  210.     return (MAXLONG);
  211. #else
  212.     long n, n2;
  213.  
  214.     /*
  215.      * Keep doubling n until we overflow.
  216.      * {{ This actually only returns the largest power of two that
  217.      *    can fit in a long, but percentage() doesn't really need
  218.      *    it any more accurate than that. }}
  219.      */
  220.     n2 = 128;  /* Hopefully no maxlong is less than 128! */
  221.     do {
  222.         n = n2;
  223.         n2 *= 2;
  224.     } while (n2 / 2 == n);
  225.     return (n);
  226. #endif
  227. #endif
  228. }
  229.  
  230. /*
  231.  * Return the ratio of two POSITIONS, as a percentage.
  232.  * {{ Assumes a POSITION is a long int. }}
  233.  */
  234.     public int
  235. percentage(num, den)
  236.     POSITION num, den;
  237. {
  238.     if (num <= get_maxlong() / 100)
  239.         return ((100 * num) / den);
  240.     else
  241.         return (num / (den / 100));
  242. }
  243.  
  244. /*
  245.  * Return the specified percentage of a POSITION.
  246.  * {{ Assumes a POSITION is a long int. }}
  247.  */
  248.     public POSITION
  249. percent_pos(pos, percent)
  250.     POSITION pos;
  251.     int percent;
  252. {
  253.     if (pos <= get_maxlong() / 100)
  254.         return ((percent * pos) / 100);
  255.     else
  256.         return (percent * (pos / 100));
  257. }
  258.  
  259. #ifdef _OSK_MWC32
  260.  
  261. /*
  262.  * This implements an ANSI-style intercept setup for Microware C 3.2
  263.  */
  264.     public int 
  265. os9_signal(type, handler)
  266.     int type;
  267.     RETSIGTYPE (*handler)();
  268. {
  269.     intercept(handler);
  270. }
  271.  
  272. #include <sgstat.h>
  273.  
  274.     public int 
  275. isatty(f)
  276.     int f;
  277. {
  278.     struct sgbuf sgbuf;
  279.  
  280.     if (_gs_opt(f, &sgbuf) < 0)
  281.         return -1;
  282.     return (sgbuf.sg_class == 0);
  283. }
  284.     
  285. #endif
  286.