~ubuntu-branches/ubuntu/quantal/less/quantal

« back to all changes in this revision

Viewing changes to os.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Schoepf
  • Date: 2002-04-04 16:43:52 UTC
  • Revision ID: james.westby@ubuntu.com-20020404164352-qldq048yoc7x5sd5
Tags: upstream-374
ImportĀ upstreamĀ versionĀ 374

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1984-2000  Mark Nudelman
 
3
 *
 
4
 * You may distribute under the terms of either the GNU General Public
 
5
 * License or the Less License, as specified in the README file.
 
6
 *
 
7
 * For more information about less, or for information on how to 
 
8
 * contact the author, see the README file.
 
9
 */
 
10
 
 
11
 
 
12
/*
 
13
 * Operating system dependent routines.
 
14
 *
 
15
 * Most of the stuff in here is based on Unix, but an attempt
 
16
 * has been made to make things work on other operating systems.
 
17
 * This will sometimes result in a loss of functionality, unless
 
18
 * someone rewrites code specifically for the new operating system.
 
19
 *
 
20
 * The makefile provides defines to decide whether various
 
21
 * Unix features are present.
 
22
 */
 
23
 
 
24
#include "less.h"
 
25
#include <signal.h>
 
26
#include <setjmp.h>
 
27
#if HAVE_TIME_H
 
28
#include <time.h>
 
29
#endif
 
30
#if HAVE_ERRNO_H
 
31
#include <errno.h>
 
32
#endif
 
33
#if HAVE_VALUES_H
 
34
#include <values.h>
 
35
#endif
 
36
 
 
37
#if HAVE_TIME_T
 
38
#define time_type       time_t
 
39
#else
 
40
#define time_type       long
 
41
#endif
 
42
 
 
43
/*
 
44
 * BSD setjmp() saves (and longjmp() restores) the signal mask.
 
45
 * This costs a system call or two per setjmp(), so if possible we clear the
 
46
 * signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead.
 
47
 * On other systems, setjmp() doesn't affect the signal mask and so
 
48
 * _setjmp() does not exist; we just use setjmp().
 
49
 */
 
50
#if HAVE__SETJMP && HAVE_SIGSETMASK
 
51
#define SET_JUMP        _setjmp
 
52
#define LONG_JUMP       _longjmp
 
53
#else
 
54
#define SET_JUMP        setjmp
 
55
#define LONG_JUMP       longjmp
 
56
#endif
 
57
 
 
58
public int reading;
 
59
 
 
60
static jmp_buf read_label;
 
61
 
 
62
extern int sigs;
 
63
 
 
64
/*
 
65
 * Like read() system call, but is deliberately interruptible.
 
66
 * A call to intread() from a signal handler will interrupt
 
67
 * any pending iread().
 
68
 */
 
69
        public int
 
70
iread(fd, buf, len)
 
71
        int fd;
 
72
        char *buf;
 
73
        unsigned int len;
 
74
{
 
75
        register int n;
 
76
 
 
77
#if MSDOS_COMPILER==WIN32C
 
78
        if (ABORT_SIGS())
 
79
                return (READ_INTR);
 
80
#else
 
81
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
 
82
        if (kbhit())
 
83
        {
 
84
                int c;
 
85
                
 
86
                c = getch();
 
87
                if (c == '\003')
 
88
                        return (READ_INTR);
 
89
                ungetch(c);
 
90
        }
 
91
#endif
 
92
#endif
 
93
        if (SET_JUMP(read_label))
 
94
        {
 
95
                /*
 
96
                 * We jumped here from intread.
 
97
                 */
 
98
                reading = 0;
 
99
#if HAVE_SIGPROCMASK
 
100
                {
 
101
                  sigset_t mask;
 
102
                  sigemptyset(&mask);
 
103
                  sigprocmask(SIG_SETMASK, &mask, NULL);
 
104
                }
 
105
#else
 
106
#if HAVE_SIGSETMASK
 
107
                sigsetmask(0);
 
108
#else
 
109
#ifdef _OSK
 
110
                sigmask(~0);
 
111
#endif
 
112
#endif
 
113
#endif
 
114
                return (READ_INTR);
 
115
        }
 
116
 
 
117
        flush();
 
118
        reading = 1;
 
119
#if MSDOS_COMPILER==DJGPPC
 
120
        if (isatty(fd))
 
121
        {
 
122
                /*
 
123
                 * Don't try reading from a TTY until a character is
 
124
                 * available, because that makes some background programs
 
125
                 * believe DOS is busy in a way that prevents those
 
126
                 * programs from working while "less" waits.
 
127
                 */
 
128
                fd_set readfds;
 
129
 
 
130
                FD_ZERO(&readfds);
 
131
                FD_SET(fd, &readfds);
 
132
                if (select(fd+1, &readfds, 0, 0, 0) == -1)
 
133
                        return (-1);
 
134
        }
 
135
#endif
 
136
        n = read(fd, buf, len);
 
137
#if 1
 
138
        /*
 
139
         * This is a kludge to workaround a problem on some systems
 
140
         * where terminating a remote tty connection causes read() to
 
141
         * start returning 0 forever, instead of -1.
 
142
         */
 
143
        {
 
144
                extern int ignore_eoi;
 
145
                if (!ignore_eoi)
 
146
                {
 
147
                        static int consecutive_nulls = 0;
 
148
                        if (n == 0)
 
149
                                consecutive_nulls++;
 
150
                        else
 
151
                                consecutive_nulls = 0;
 
152
                        if (consecutive_nulls > 20)
 
153
                                quit(QUIT_ERROR);
 
154
                }
 
155
        }
 
156
#endif
 
157
        reading = 0;
 
158
        if (n < 0)
 
159
                return (-1);
 
160
        return (n);
 
161
}
 
162
 
 
163
/*
 
164
 * Interrupt a pending iread().
 
165
 */
 
166
        public void
 
167
intread()
 
168
{
 
169
        LONG_JUMP(read_label, 1);
 
170
}
 
171
 
 
172
/*
 
173
 * Return the current time.
 
174
 */
 
175
#if HAVE_TIME
 
176
        public long
 
177
get_time()
 
178
{
 
179
        time_type t;
 
180
 
 
181
        time(&t);
 
182
        return (t);
 
183
}
 
184
#endif
 
185
 
 
186
 
 
187
#if !HAVE_STRERROR
 
188
/*
 
189
 * Local version of strerror, if not available from the system.
 
190
 */
 
191
        static char *
 
192
strerror(err)
 
193
        int err;
 
194
{
 
195
#if HAVE_SYS_ERRLIST
 
196
        static char buf[16];
 
197
        extern char *sys_errlist[];
 
198
        extern int sys_nerr;
 
199
  
 
200
        if (err < sys_nerr)
 
201
                return sys_errlist[err];
 
202
        sprintf(buf, "Error %d", err);
 
203
        return buf;
 
204
#else
 
205
        return ("cannot open");
 
206
#endif
 
207
}
 
208
#endif
 
209
 
 
210
/*
 
211
 * errno_message: Return an error message based on the value of "errno".
 
212
 */
 
213
        public char *
 
214
errno_message(filename)
 
215
        char *filename;
 
216
{
 
217
        register char *p;
 
218
        register char *m;
 
219
#if HAVE_ERRNO
 
220
#if MUST_DEFINE_ERRNO
 
221
        extern int errno;
 
222
#endif
 
223
        p = strerror(errno);
 
224
#else
 
225
        p = "cannot open";
 
226
#endif
 
227
        m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
 
228
        sprintf(m, "%s: %s", filename, p);
 
229
        return (m);
 
230
}
 
231
 
 
232
/*
 
233
 * Return the ratio of two POSITIONS, as a percentage.
 
234
 * {{ Assumes a POSITION is a long int. }}
 
235
 */
 
236
        public int
 
237
percentage(num, den)
 
238
        POSITION num, den;
 
239
{
 
240
        POSITION num100 = num * 100;
 
241
 
 
242
        if (num100 / 100 == num)
 
243
                return (num100 / den);
 
244
        else
 
245
                return (num / (den / 100));
 
246
}
 
247
 
 
248
/*
 
249
 * Return the specified percentage of a POSITION.
 
250
 */
 
251
        public POSITION
 
252
percent_pos(pos, percent)
 
253
        POSITION pos;
 
254
        int percent;
 
255
{
 
256
        POSITION result100;
 
257
 
 
258
        if (percent == 0)
 
259
                return (0);
 
260
        else if ((result100 = pos * percent) / percent == pos)
 
261
                return (result100 / 100);
 
262
        else
 
263
                return (percent * (pos / 100));
 
264
}
 
265
 
 
266
#if !HAVE_STRCHR
 
267
/*
 
268
 * strchr is used by regexp.c.
 
269
 */
 
270
        char *
 
271
strchr(s, c)
 
272
        char *s;
 
273
        int c;
 
274
{
 
275
        for ( ;  *s != '\0';  s++)
 
276
                if (*s == c)
 
277
                        return (s);
 
278
        if (c == '\0')
 
279
                return (s);
 
280
        return (NULL);
 
281
}
 
282
#endif
 
283
 
 
284
#if !HAVE_MEMCPY
 
285
        VOID_POINTER
 
286
memcpy(dst, src, len)
 
287
        VOID_POINTER dst;
 
288
        VOID_POINTER src;
 
289
        int len;
 
290
{
 
291
        char *dstp = (char *) dst;
 
292
        char *srcp = (char *) src;
 
293
        int i;
 
294
 
 
295
        for (i = 0;  i < len;  i++)
 
296
                dstp[i] = srcp[i];
 
297
        return (dst);
 
298
}
 
299
#endif
 
300
 
 
301
#ifdef _OSK_MWC32
 
302
 
 
303
/*
 
304
 * This implements an ANSI-style intercept setup for Microware C 3.2
 
305
 */
 
306
        public int 
 
307
os9_signal(type, handler)
 
308
        int type;
 
309
        RETSIGTYPE (*handler)();
 
310
{
 
311
        intercept(handler);
 
312
}
 
313
 
 
314
#include <sgstat.h>
 
315
 
 
316
        int 
 
317
isatty(f)
 
318
        int f;
 
319
{
 
320
        struct sgbuf sgbuf;
 
321
 
 
322
        if (_gs_opt(f, &sgbuf) < 0)
 
323
                return -1;
 
324
        return (sgbuf.sg_class == 0);
 
325
}
 
326
        
 
327
#endif