]> git.ipfire.org Git - thirdparty/bash.git/blob - lib/sh/zread.c
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / lib / sh / zread.c
1 /* Copyright (C) 1999 Free Software Foundation, Inc.
2
3 This file is part of GNU Bash, the Bourne Again SHell.
4
5 Bash is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with Bash; see the file COPYING. If not, write to the Free Software
17 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
18
19 #include <config.h>
20
21 #include <sys/types.h>
22
23 #if defined (HAVE_UNISTD_H)
24 # include <unistd.h>
25 #endif
26
27 #include <errno.h>
28
29 #if !defined (errno)
30 extern int errno;
31 #endif
32
33 #ifndef SEEK_CUR
34 # define SEEK_CUR 1
35 #endif
36
37 /* Read LEN bytes from FD into BUF. Retry the read on EINTR. Any other
38 error causes the loop to break. */
39 int
40 zread (fd, buf, len)
41 int fd;
42 char *buf;
43 size_t len;
44 {
45 int r;
46
47 while ((r = read (fd, buf, len)) < 0 && errno == EINTR)
48 ;
49 return r;
50 }
51
52 /* Read LEN bytes from FD into BUF. Retry the read on EINTR, up to three
53 interrupts. Any other error causes the loop to break. */
54
55 #ifdef NUM_INTR
56 # undef NUM_INTR
57 #endif
58 #define NUM_INTR 3
59
60 int
61 zread1 (fd, buf, len)
62 int fd;
63 char *buf;
64 size_t len;
65 {
66 int r, nintr;
67
68 for (nintr = 0; ; )
69 {
70 r = read (fd, buf, len);
71 if (r >= 0)
72 return r;
73 if (r == -1 && errno == EINTR)
74 {
75 if (++nintr > NUM_INTR)
76 return -1;
77 continue;
78 }
79 return r;
80 }
81 }
82
83 /* Read one character from FD and return it in CP. Return values are as
84 in read(2). This does some local buffering to avoid many one-character
85 calls to read(2), like those the `read' builtin performs. */
86
87 static unsigned char lbuf[128];
88 static int lind, lused;
89
90 int
91 zreadc (fd, cp)
92 int fd;
93 char *cp;
94 {
95 int r;
96
97 if (lind == lused || lused == 0)
98 {
99 lused = zread (fd, lbuf, sizeof (lbuf));
100 lind = 0;
101 if (lused <= 0)
102 return (lused);
103 }
104 if (cp)
105 *cp = (char)lbuf[lind++];
106 return 1;
107 }
108
109 void
110 zreset ()
111 {
112 lind = lused = 0;
113 }
114
115 /* Sync the seek pointer for FD so that the kernel's idea of the last char
116 read is the last char returned by zreadc. */
117 void
118 zsyncfd (fd)
119 int fd;
120 {
121 int off;
122
123 off = lused - lind;
124 if (off > 0)
125 lseek (fd, -off, SEEK_CUR);
126 lused = lind = 0;
127 }