source: trunk/essentials/app-shells/bash/lib/sh/zread.c

Last change on this file was 3265, checked in by bird, 18 years ago

minor adjustment.

  • Property svn:eol-style set to native
File size: 3.6 KB
Line 
1/* Copyright (C) 1999-2002 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)
30extern 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. */
39ssize_t
40zread (fd, buf, len)
41 int fd;
42 char *buf;
43 size_t len;
44{
45 ssize_t 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
60ssize_t
61zreadintr (fd, buf, len)
62 int fd;
63 char *buf;
64 size_t len;
65{
66 ssize_t r;
67 int nintr;
68
69 for (nintr = 0; ; )
70 {
71 r = read (fd, buf, len);
72 if (r >= 0)
73 return r;
74 if (r == -1 && errno == EINTR)
75 {
76 if (++nintr > NUM_INTR)
77 return -1;
78 continue;
79 }
80 return r;
81 }
82}
83
84/* Read one character from FD and return it in CP. Return values are as
85 in read(2). This does some local buffering to avoid many one-character
86 calls to read(2), like those the `read' builtin performs. */
87
88static char lbuf[128];
89static size_t lind, lused;
90
91ssize_t
92zreadc (fd, cp)
93 int fd;
94 char *cp;
95{
96 ssize_t nr;
97
98 if (lind == lused || lused == 0)
99 {
100#ifdef __OS2__
101 off_t end, start = lseek (fd, 0, SEEK_CUR);
102#endif
103 nr = zread (fd, lbuf, sizeof (lbuf));
104 lind = 0;
105 if (nr <= 0)
106 {
107 lused = 0;
108 return nr;
109 }
110#ifdef __OS2__
111 /* \r\n -> \n translation screws us down in zsyncfd, so,
112 we have to check if translation took place and wind back
113 to right before the first one. New line characters are
114 read one by one. */
115 if (start >= 0
116 && (end = lseek (fd, 0, SEEK_CUR)) > 0
117 && nr != end - start)
118 {
119 if (lbuf[0] == '\n')
120 {
121 if (lseek (fd, start, SEEK_SET) >= 0)
122 {
123 nr = zread (fd, lbuf, 1);
124 if (nr <= 0)
125 {
126 lused = 0;
127 return nr;
128 }
129 }
130 }
131 else
132 {
133 char *nl = memchr (&lbuf[0], '\n', nr);
134 if (nl != NULL
135 && lseek (fd, start + (nl - &lbuf[0]), SEEK_SET) >= 0)
136 nr = nl - &lbuf[0];
137 }
138 }
139#endif
140 lused = nr;
141 }
142 if (cp)
143 *cp = lbuf[lind++];
144 return 1;
145}
146
147void
148zreset ()
149{
150 lind = lused = 0;
151}
152
153/* Sync the seek pointer for FD so that the kernel's idea of the last char
154 read is the last char returned by zreadc. */
155void
156zsyncfd (fd)
157 int fd;
158{
159 off_t off;
160 int r;
161
162 off = lused - lind;
163 r = 0;
164 if (off > 0)
165 r = lseek (fd, -off, SEEK_CUR);
166
167 if (r >= 0)
168 lused = lind = 0;
169}
Note: See TracBrowser for help on using the repository browser.