Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / miscellany / less-177 / os.c
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 <stdio.h>
14 #include <signal.h>
15 #include <setjmp.h>
16 #include "less.h"
17
18 /*
19  * BSD setjmp() saves (and longjmp() restores) the signal mask.
20  * This costs a system call or two per setjmp(), so if possible we clear the
21  * signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead.
22  * On other systems, setjmp() doesn't affect the signal mask and so
23  * _setjmp() does not exist; we just use setjmp().
24  */
25 #if HAS__SETJMP && SIGSETMASK
26 #define SET_JUMP        _setjmp
27 #define LONG_JUMP       _longjmp
28 #else
29 #define SET_JUMP        setjmp
30 #define LONG_JUMP       longjmp
31 #endif
32
33 extern char *getenv();
34
35 public int reading;
36
37 static jmp_buf read_label;
38
39 /*
40  * Like read() system call, but is deliberately interruptible.
41  * A call to intread() from a signal handler will interrupt
42  * any pending iread().
43  */
44         public int
45 iread(fd, buf, len)
46         int fd;
47         char *buf;
48         unsigned int len;
49 {
50         register int n;
51
52         if (SET_JUMP(read_label))
53         {
54                 /*
55                  * We jumped here from intread.
56                  */
57                 reading = 0;
58 #if SIGSETMASK
59                 sigsetmask(0);
60 #endif
61                 return (READ_INTR);
62         }
63
64         flush();
65         reading = 1;
66         n = read(fd, buf, len);
67         reading = 0;
68         if (n < 0)
69                 return (-1);
70         return (n);
71 }
72
73 /*
74  * Interrupt a pending iread().
75  */
76         public void
77 intread()
78 {
79         LONG_JUMP(read_label, 1);
80 }
81
82 #if GET_TIME
83         public long
84 get_time()
85 {
86         long t;
87
88         time(&t);
89         return (t);
90 }
91 #endif
92
93 /*
94  * errno_message: Return an error message based on the value of "errno".
95  */
96
97 #if PERROR
98
99 extern char *sys_errlist[];
100 extern int sys_nerr;
101 extern int errno;
102
103         public char *
104 errno_message(filename)
105         char *filename;
106 {
107         register char *p;
108         register char *m;
109         char msg[16];
110
111         if (errno < sys_nerr)
112                 p = sys_errlist[errno];
113         else
114         {
115                 sprintf(msg, "Error %d", errno);
116                 p = msg;
117         }
118         m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
119         sprintf(m, "%s: %s", filename, p);
120         return (m);
121 }
122
123 #else
124
125         public char *
126 errno_message(filename)
127         char *filename;
128 {
129         register char *m;
130         static char msg[] = ": cannot open";
131
132         m = (char *) ecalloc(strlen(filename) + sizeof(msg), sizeof(char));
133         strcpy(m, filename);
134         strcat(m, msg);
135         return (m);
136 }
137
138 #endif