]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/sh/zread.c
Imported from ../bash-2.04.tar.gz.
[thirdparty/bash.git] / lib / sh / zread.c
CommitLineData
bb70624e
JA
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)
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. */
39int
40zread (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
60int
61zread1 (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
87static unsigned char lbuf[128];
88static int lind, lused;
89
90int
91zreadc (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
109void
110zreset ()
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. */
117void
118zsyncfd (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}