]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/less-177/os.c
ap: Fix write past end of addrs[] array.
[nmh] / 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