0
|
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
|