OpenCoverage

input.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/input.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* input.c -- functions to perform buffered input with synchronization. */-
2-
3/* Copyright (C) 1992-2018 Free Software Foundation, Inc.-
4-
5 This file is part of GNU Bash, the Bourne Again SHell.-
6-
7 Bash is free software: you can redistribute it and/or modify-
8 it under the terms of the GNU General Public License as published by-
9 the Free Software Foundation, either version 3 of the License, or-
10 (at your option) any later version.-
11-
12 Bash is distributed in the hope that it will be useful,-
13 but WITHOUT ANY WARRANTY; without even the implied warranty of-
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
15 GNU General Public License for more details.-
16-
17 You should have received a copy of the GNU General Public License-
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.-
19*/-
20-
21#include "config.h"-
22-
23#include "bashtypes.h"-
24#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)-
25# include <sys/file.h>-
26#endif-
27#include "filecntl.h"-
28#include "posixstat.h"-
29#include <stdio.h>-
30#include <errno.h>-
31-
32#if defined (HAVE_UNISTD_H)-
33# include <unistd.h>-
34#endif-
35-
36#include "bashansi.h"-
37#include "bashintl.h"-
38-
39#include "shell.h"-
40#include "input.h"-
41#include "externs.h"-
42#include "trap.h"-
43-
44#if !defined (errno)-
45extern int errno;-
46#endif /* !errno */-
47-
48#if defined (EAGAIN)-
49# define X_EAGAIN EAGAIN-
50#else-
51# define X_EAGAIN -99-
52#endif-
53-
54#if defined (EWOULDBLOCK)-
55# define X_EWOULDBLOCK EWOULDBLOCK-
56#else-
57# define X_EWOULDBLOCK -99-
58#endif-
59-
60extern void termsig_handler __P((int));-
61-
62/* Functions to handle reading input on systems that don't restart read(2)-
63 if a signal is received. */-
64-
65static char localbuf[128];-
66static int local_index = 0, local_bufused = 0;-
67-
68/* Posix and USG systems do not guarantee to restart read () if it is-
69 interrupted by a signal. We do the read ourselves, and restart it-
70 if it returns EINTR. */-
71int-
72getc_with_restart (stream)-
73 FILE *stream;-
74{-
75 unsigned char uc;-
76-
77 CHECK_TERMSIG;
never executed: termsig_handler (terminating_signal);
terminating_signalDescription
TRUEnever evaluated
FALSEnever evaluated
0
78-
79 /* Try local buffering to reduce the number of read(2) calls. */-
80 if (local_index == local_bufused || local_bufused == 0)
local_index == local_bufusedDescription
TRUEnever evaluated
FALSEnever evaluated
local_bufused == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
81 {-
82 while (1)-
83 {-
84 QUIT;
never executed: termsig_handler (terminating_signal);
never executed: throw_to_top_level ();
terminating_signalDescription
TRUEnever evaluated
FALSEnever evaluated
interrupt_stateDescription
TRUEnever evaluated
FALSEnever evaluated
0
85 run_pending_traps ();-
86-
87 local_bufused = read (fileno (stream), localbuf, sizeof(localbuf));-
88 if (local_bufused > 0)
local_bufused > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
89 break;
never executed: break;
0
90 else if (local_bufused == 0)
local_bufused == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
91 {-
92 local_index = 0;-
93 return EOF;
never executed: return (-1) ;
0
94 }-
95 else if (errno == X_EAGAIN || errno == X_EWOULDBLOCK)
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
96 {-
97 if (sh_unset_nodelay_mode (fileno (stream)) < 0)
sh_unset_nodel... (stream)) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
98 {-
99 sys_error (_("cannot reset nodelay mode for fd %d"), fileno (stream));-
100 local_index = local_bufused = 0;-
101 return EOF;
never executed: return (-1) ;
0
102 }-
103 continue;
never executed: continue;
0
104 }-
105 else if (errno != EINTR)
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
106 {-
107 local_index = local_bufused = 0;-
108 return EOF;
never executed: return (-1) ;
0
109 }-
110 else if (interrupt_state || terminating_signal) /* QUIT; */
interrupt_stateDescription
TRUEnever evaluated
FALSEnever evaluated
terminating_signalDescription
TRUEnever evaluated
FALSEnever evaluated
0
111 local_index = local_bufused = 0;
never executed: local_index = local_bufused = 0;
0
112 }
never executed: end of block
0
113 local_index = 0;-
114 }
never executed: end of block
0
115 uc = localbuf[local_index++];-
116 return uc;
never executed: return uc;
0
117}-
118-
119int-
120ungetc_with_restart (c, stream)-
121 int c;-
122 FILE *stream;-
123{-
124 if (local_index == 0 || c == EOF)
local_index == 0Description
TRUEnever evaluated
FALSEnever evaluated
c == (-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
125 return EOF;
never executed: return (-1) ;
0
126 localbuf[--local_index] = c;-
127 return c;
never executed: return c;
0
128}-
129-
130#if defined (BUFFERED_INPUT)-
131-
132/* A facility similar to stdio, but input-only. */-
133-
134#if defined (USING_BASH_MALLOC)-
135# define MAX_INPUT_BUFFER_SIZE 8176-
136#else-
137# define MAX_INPUT_BUFFER_SIZE 8192-
138#endif-
139-
140#if !defined (SEEK_CUR)-
141# define SEEK_CUR 1-
142#endif /* !SEEK_CUR */-
143-
144#ifdef max-
145# undef max-
146#endif-
147#define max(a, b) (((a) > (b)) ? (a) : (b))-
148#ifdef min-
149# undef min-
150#endif-
151#define min(a, b) ((a) > (b) ? (b) : (a))-
152-
153int bash_input_fd_changed;-
154-
155/* This provides a way to map from a file descriptor to the buffer-
156 associated with that file descriptor, rather than just the other-
157 way around. This is needed so that buffers are managed properly-
158 in constructs like 3<&4. buffers[x]->b_fd == x -- that is how the-
159 correspondence is maintained. */-
160static BUFFERED_STREAM **buffers = (BUFFERED_STREAM **)NULL;-
161static int nbuffers;-
162-
163#define ALLOCATE_BUFFERS(n) \-
164 do { if ((n) >= nbuffers) allocate_buffers (n); } while (0)-
165-
166/* Make sure `buffers' has at least N elements. */-
167static void-
168allocate_buffers (n)-
169 int n;-
170{-
171 register int i, orig_nbuffers;-
172-
173 orig_nbuffers = nbuffers;-
174 nbuffers = n + 20;-
175 buffers = (BUFFERED_STREAM **)xrealloc-
176 (buffers, nbuffers * sizeof (BUFFERED_STREAM *));-
177-
178 /* Zero out the new buffers. */-
179 for (i = orig_nbuffers; i < nbuffers; i++)
i < nbuffersDescription
TRUEevaluated 1442749 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5251 times by 1 test
Evaluated by:
  • Self test
5251-1442749
180 buffers[i] = (BUFFERED_STREAM *)NULL;
executed 1442749 times by 1 test: buffers[i] = (BUFFERED_STREAM *) ((void *)0) ;
Executed by:
  • Self test
1442749
181}
executed 5251 times by 1 test: end of block
Executed by:
  • Self test
5251
182-
183/* Construct and return a BUFFERED_STREAM corresponding to file descriptor-
184 FD, using BUFFER. */-
185static BUFFERED_STREAM *-
186make_buffered_stream (fd, buffer, bufsize)-
187 int fd;-
188 char *buffer;-
189 size_t bufsize;-
190{-
191 BUFFERED_STREAM *bp;-
192-
193 bp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));-
194 ALLOCATE_BUFFERS (fd);
executed 5251 times by 1 test: allocate_buffers (fd);
Executed by:
  • Self test
(fd) >= nbuffersDescription
TRUEevaluated 5251 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 17 times by 1 test
Evaluated by:
  • Self test
17-5251
195 buffers[fd] = bp;-
196 bp->b_fd = fd;-
197 bp->b_buffer = buffer;-
198 bp->b_size = bufsize;-
199 bp->b_used = bp->b_inputp = bp->b_flag = 0;-
200 if (bufsize == 1)
bufsize == 1Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5264 times by 1 test
Evaluated by:
  • Self test
4-5264
201 bp->b_flag |= B_UNBUFF;
executed 4 times by 1 test: bp->b_flag |= 0x04;
Executed by:
  • Self test
4
202 if (O_TEXT && (fcntl (fd, F_GETFL) & O_TEXT) != 0)
dead code: (fcntl (fd, 3 ) & 0) != 0
dead code: bp->b_flag |= 0x10;
-
203 bp->b_flag |= B_TEXT;
dead code: bp->b_flag |= 0x10;
-
204 return (bp);
executed 5268 times by 1 test: return (bp);
Executed by:
  • Self test
5268
205}-
206-
207/* Allocate a new BUFFERED_STREAM, copy BP to it, and return the new copy. */-
208static BUFFERED_STREAM *-
209copy_buffered_stream (bp)-
210 BUFFERED_STREAM *bp;-
211{-
212 BUFFERED_STREAM *nbp;-
213-
214 if (!bp)
!bpDescription
TRUEevaluated 28888 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-28888
215 return ((BUFFERED_STREAM *)NULL);
executed 28888 times by 1 test: return ((BUFFERED_STREAM *) ((void *)0) );
Executed by:
  • Self test
28888
216-
217 nbp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM));-
218 xbcopy ((char *)bp, (char *)nbp, sizeof (BUFFERED_STREAM));-
219 return (nbp);
never executed: return (nbp);
0
220}-
221-
222int-
223set_bash_input_fd (fd)-
224 int fd;-
225{-
226 if (bash_input.type == st_bstream)
bash_input.type == st_bstreamDescription
TRUEnever evaluated
FALSEnever evaluated
0
227 bash_input.location.buffered_fd = fd;
never executed: bash_input.location.buffered_fd = fd;
0
228 else if (interactive_shell == 0)
interactive_shell == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
229 default_buffered_input = fd;
never executed: default_buffered_input = fd;
0
230 return 0;
never executed: return 0;
0
231}-
232-
233int-
234fd_is_bash_input (fd)-
235 int fd;-
236{-
237 if (bash_input.type == st_bstream && bash_input.location.buffered_fd == fd)
bash_input.type == st_bstreamDescription
TRUEevaluated 2715010 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 420 times by 1 test
Evaluated by:
  • Self test
bash_input.loc...fered_fd == fdDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 2715008 times by 1 test
Evaluated by:
  • Self test
2-2715010
238 return 1;
executed 2 times by 1 test: return 1;
Executed by:
  • Self test
2
239 else if (interactive_shell == 0 && default_buffered_input == fd)
interactive_shell == 0Description
TRUEevaluated 2715357 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 71 times by 1 test
Evaluated by:
  • Self test
default_buffered_input == fdDescription
TRUEnever evaluated
FALSEevaluated 2715357 times by 1 test
Evaluated by:
  • Self test
0-2715357
240 return 1;
never executed: return 1;
0
241 return 0;
executed 2715428 times by 1 test: return 0;
Executed by:
  • Self test
2715428
242}-
243-
244/* Save the buffered stream corresponding to file descriptor FD (which bash-
245 is using to read input) to a buffered stream associated with NEW_FD. If-
246 NEW_FD is -1, a new file descriptor is allocated with fcntl. The new-
247 file descriptor is returned on success, -1 on error. */-
248int-
249save_bash_input (fd, new_fd)-
250 int fd, new_fd;-
251{-
252 int nfd;-
253-
254 /* Sync the stream so we can re-read from the new file descriptor. We-
255 might be able to avoid this by copying the buffered stream verbatim-
256 to the new file descriptor. */-
257 if (buffers[fd])
buffers[fd]Description
TRUEnever evaluated
FALSEnever evaluated
0
258 sync_buffered_stream (fd);
never executed: sync_buffered_stream (fd);
0
259-
260 /* Now take care of duplicating the file descriptor that bash is-
261 using for input, so we can reinitialize it later. */-
262 nfd = (new_fd == -1) ? fcntl (fd, F_DUPFD, 10) : new_fd;
(new_fd == -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
263 if (nfd == -1)
nfd == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
264 {-
265 if (fcntl (fd, F_GETFD, 0) == 0)
fcntl (fd, 1 , 0) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
266 sys_error (_("cannot allocate new file descriptor for bash input from fd %d"), fd);
never executed: sys_error ( dcgettext (((void *)0), "cannot allocate new file descriptor for bash input from fd %d" , 5) , fd);
0
267 return -1;
never executed: return -1;
0
268 }-
269-
270 if (nfd < nbuffers && buffers[nfd])
nfd < nbuffersDescription
TRUEnever evaluated
FALSEnever evaluated
buffers[nfd]Description
TRUEnever evaluated
FALSEnever evaluated
0
271 {-
272 /* What's this? A stray buffer without an associated open file-
273 descriptor? Free up the buffer and report the error. */-
274 internal_error (_("save_bash_input: buffer already exists for new fd %d"), nfd);-
275 if (buffers[nfd]->b_flag & B_SHAREDBUF)
buffers[nfd]->b_flag & 0x20Description
TRUEnever evaluated
FALSEnever evaluated
0
276 buffers[nfd]->b_buffer = (char *)NULL;
never executed: buffers[nfd]->b_buffer = (char *) ((void *)0) ;
0
277 free_buffered_stream (buffers[nfd]);-
278 }
never executed: end of block
0
279-
280 /* Reinitialize bash_input.location. */-
281 if (bash_input.type == st_bstream)
bash_input.type == st_bstreamDescription
TRUEnever evaluated
FALSEnever evaluated
0
282 {-
283 bash_input.location.buffered_fd = nfd;-
284 fd_to_buffered_stream (nfd);-
285 close_buffered_fd (fd); /* XXX */-
286 }
never executed: end of block
0
287 else-
288 /* If the current input type is not a buffered stream, but the shell-
289 is not interactive and therefore using a buffered stream to read-
290 input (e.g. with an `eval exec 3>output' inside a script), note-
291 that the input fd has been changed. pop_stream() looks at this-
292 value and adjusts the input fd to the new value of-
293 default_buffered_input accordingly. */-
294 bash_input_fd_changed++;
never executed: bash_input_fd_changed++;
0
295-
296 if (default_buffered_input == fd)
default_buffered_input == fdDescription
TRUEnever evaluated
FALSEnever evaluated
0
297 default_buffered_input = nfd;
never executed: default_buffered_input = nfd;
0
298-
299 SET_CLOSE_ON_EXEC (nfd);-
300 return nfd;
never executed: return nfd;
0
301}-
302-
303/* Check that file descriptor FD is not the one that bash is currently-
304 using to read input from a script. FD is about to be duplicated onto,-
305 which means that the kernel will close it for us. If FD is the bash-
306 input file descriptor, we need to seek backwards in the script (if-
307 possible and necessary -- scripts read from stdin are still unbuffered),-
308 allocate a new file descriptor to use for bash input, and re-initialize-
309 the buffered stream. Make sure the file descriptor used to save bash-
310 input is set close-on-exec. Returns 0 on success, -1 on failure. This-
311 works only if fd is > 0 -- if fd == 0 and bash is reading input from-
312 fd 0, sync_buffered_stream is used instead, to cooperate with input-
313 redirection (look at redir.c:add_undo_redirect()). */-
314int-
315check_bash_input (fd)-
316 int fd;-
317{-
318 if (fd_is_bash_input (fd))
fd_is_bash_input (fd)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 1364588 times by 1 test
Evaluated by:
  • Self test
2-1364588
319 {-
320 if (fd > 0)
fd > 0Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
0-2
321 return ((save_bash_input (fd, -1) == -1) ? -1 : 0);
never executed: return ((save_bash_input (fd, -1) == -1) ? -1 : 0);
0
322 else if (fd == 0)
fd == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-2
323 return ((sync_buffered_stream (fd) == -1) ? -1 : 0);
executed 2 times by 1 test: return ((sync_buffered_stream (fd) == -1) ? -1 : 0);
Executed by:
  • Self test
2
324 }
never executed: end of block
0
325 return 0;
executed 1364588 times by 1 test: return 0;
Executed by:
  • Self test
1364588
326}-
327 -
328/* This is the buffered stream analogue of dup2(fd1, fd2). The-
329 BUFFERED_STREAM corresponding to fd2 is deallocated, if one exists.-
330 BUFFERS[fd1] is copied to BUFFERS[fd2]. This is called by the-
331 redirect code for constructs like 4<&0 and 3</etc/rc.local. */-
332int-
333duplicate_buffered_stream (fd1, fd2)-
334 int fd1, fd2;-
335{-
336 int is_bash_input, m;-
337-
338 if (fd1 == fd2)
fd1 == fd2Description
TRUEevaluated 634537 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 28888 times by 1 test
Evaluated by:
  • Self test
28888-634537
339 return 0;
executed 634537 times by 1 test: return 0;
Executed by:
  • Self test
634537
340-
341 m = max (fd1, fd2);
((fd1) > (fd2))Description
TRUEevaluated 28848 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 40 times by 1 test
Evaluated by:
  • Self test
40-28848
342 ALLOCATE_BUFFERS (m);
never executed: allocate_buffers (m);
(m) >= nbuffersDescription
TRUEnever evaluated
FALSEevaluated 28888 times by 1 test
Evaluated by:
  • Self test
0-28888
343-
344 /* If FD2 is the file descriptor bash is currently using for shell input,-
345 we need to do some extra work to make sure that the buffered stream-
346 actually exists (it might not if fd1 was not active, and the copy-
347 didn't actually do anything). */-
348 is_bash_input = (bash_input.type == st_bstream) &&
(bash_input.ty...== st_bstream)Description
TRUEevaluated 28881 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 7 times by 1 test
Evaluated by:
  • Self test
7-28881
349 (bash_input.location.buffered_fd == fd2);
(bash_input.lo...red_fd == fd2)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 28879 times by 1 test
Evaluated by:
  • Self test
2-28879
350-
351 if (buffers[fd2])
buffers[fd2]Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 28886 times by 1 test
Evaluated by:
  • Self test
2-28886
352 {-
353 /* If the two objects share the same b_buffer, don't free it. */-
354 if (buffers[fd1] && buffers[fd1]->b_buffer && buffers[fd1]->b_buffer == buffers[fd2]->b_buffer)
buffers[fd1]Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
buffers[fd1]->b_bufferDescription
TRUEnever evaluated
FALSEnever evaluated
buffers[fd1]->...fd2]->b_bufferDescription
TRUEnever evaluated
FALSEnever evaluated
0-2
355 buffers[fd2] = (BUFFERED_STREAM *)NULL;
never executed: buffers[fd2] = (BUFFERED_STREAM *) ((void *)0) ;
0
356 /* If this buffer is shared with another fd, don't free the buffer */-
357 else if (buffers[fd2]->b_flag & B_SHAREDBUF)
buffers[fd2]->b_flag & 0x20Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test
0-2
358 {-
359 buffers[fd2]->b_buffer = (char *)NULL;-
360 free_buffered_stream (buffers[fd2]);-
361 }
never executed: end of block
0
362 else-
363 free_buffered_stream (buffers[fd2]);
executed 2 times by 1 test: free_buffered_stream (buffers[fd2]);
Executed by:
  • Self test
2
364 }-
365 buffers[fd2] = copy_buffered_stream (buffers[fd1]);-
366 if (buffers[fd2])
buffers[fd2]Description
TRUEnever evaluated
FALSEevaluated 28888 times by 1 test
Evaluated by:
  • Self test
0-28888
367 buffers[fd2]->b_fd = fd2;
never executed: buffers[fd2]->b_fd = fd2;
0
368-
369 if (is_bash_input)
is_bash_inputDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 28886 times by 1 test
Evaluated by:
  • Self test
2-28886
370 {-
371 if (!buffers[fd2])
!buffers[fd2]Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-2
372 fd_to_buffered_stream (fd2);
executed 2 times by 1 test: fd_to_buffered_stream (fd2);
Executed by:
  • Self test
2
373 buffers[fd2]->b_flag |= B_WASBASHINPUT;-
374 }
executed 2 times by 1 test: end of block
Executed by:
  • Self test
2
375-
376 if (fd_is_bash_input (fd1) || (buffers[fd1] && (buffers[fd1]->b_flag & B_SHAREDBUF)))
fd_is_bash_input (fd1)Description
TRUEnever evaluated
FALSEevaluated 28888 times by 1 test
Evaluated by:
  • Self test
buffers[fd1]Description
TRUEnever evaluated
FALSEevaluated 28888 times by 1 test
Evaluated by:
  • Self test
(buffers[fd1]->b_flag & 0x20)Description
TRUEnever evaluated
FALSEnever evaluated
0-28888
377 buffers[fd2]->b_flag |= B_SHAREDBUF;
never executed: buffers[fd2]->b_flag |= 0x20;
0
378-
379 return (fd2);
executed 28888 times by 1 test: return (fd2);
Executed by:
  • Self test
28888
380}-
381-
382/* Return 1 if a seek on FD will succeed. */-
383#define fd_is_seekable(fd) (lseek ((fd), 0L, SEEK_CUR) >= 0)-
384-
385/* Take FD, a file descriptor, and create and return a buffered stream-
386 corresponding to it. If something is wrong and the file descriptor-
387 is invalid, return a NULL stream. */-
388BUFFERED_STREAM *-
389fd_to_buffered_stream (fd)-
390 int fd;-
391{-
392 char *buffer;-
393 size_t size;-
394 struct stat sb;-
395-
396 if (fstat (fd, &sb) < 0)
fstat (fd, &sb) < 0Description
TRUEnever evaluated
FALSEevaluated 5268 times by 1 test
Evaluated by:
  • Self test
0-5268
397 {-
398 close (fd);-
399 return ((BUFFERED_STREAM *)NULL);
never executed: return ((BUFFERED_STREAM *) ((void *)0) );
0
400 }-
401-
402 size = (fd_is_seekable (fd)) ? min (sb.st_size, MAX_INPUT_BUFFER_SIZE) : 1;
((lseek ((fd), 0L, 1 ) >= 0))Description
TRUEevaluated 5265 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 3 times by 1 test
Evaluated by:
  • Self test
(sb.st_size) > (8176)Description
TRUEevaluated 19 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5246 times by 1 test
Evaluated by:
  • Self test
3-5265
403 if (size == 0)
size == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test
FALSEevaluated 5267 times by 1 test
Evaluated by:
  • Self test
1-5267
404 size = 1;
executed 1 time by 1 test: size = 1;
Executed by:
  • Self test
1
405 buffer = (char *)xmalloc (size);-
406-
407 return (make_buffered_stream (fd, buffer, size));
executed 5268 times by 1 test: return (make_buffered_stream (fd, buffer, size));
Executed by:
  • Self test
5268
408}-
409-
410/* Return a buffered stream corresponding to FILE, a file name. */-
411BUFFERED_STREAM *-
412open_buffered_stream (file)-
413 char *file;-
414{-
415 int fd;-
416-
417 fd = open (file, O_RDONLY);-
418 return ((fd >= 0) ? fd_to_buffered_stream (fd) : (BUFFERED_STREAM *)NULL);
never executed: return ((fd >= 0) ? fd_to_buffered_stream (fd) : (BUFFERED_STREAM *) ((void *)0) );
0
419}-
420-
421/* Deallocate a buffered stream and free up its resources. Make sure we-
422 zero out the slot in BUFFERS that points to BP. */-
423void-
424free_buffered_stream (bp)-
425 BUFFERED_STREAM *bp;-
426{-
427 int n;-
428-
429 if (!bp)
!bpDescription
TRUEnever evaluated
FALSEevaluated 4857 times by 1 test
Evaluated by:
  • Self test
0-4857
430 return;
never executed: return;
0
431-
432 n = bp->b_fd;-
433 if (bp->b_buffer)
bp->b_bufferDescription
TRUEevaluated 4857 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-4857
434 free (bp->b_buffer);
executed 4857 times by 1 test: sh_xfree((bp->b_buffer), "input.c", 434);
Executed by:
  • Self test
4857
435 free (bp);-
436 buffers[n] = (BUFFERED_STREAM *)NULL;-
437}
executed 4857 times by 1 test: end of block
Executed by:
  • Self test
4857
438-
439/* Close the file descriptor associated with BP, a buffered stream, and free-
440 up the stream. Return the status of closing BP's file descriptor. */-
441int-
442close_buffered_stream (bp)-
443 BUFFERED_STREAM *bp;-
444{-
445 int fd;-
446-
447 if (!bp)
!bpDescription
TRUEnever evaluated
FALSEevaluated 4855 times by 1 test
Evaluated by:
  • Self test
0-4855
448 return (0);
never executed: return (0);
0
449 fd = bp->b_fd;-
450 if (bp->b_flag & B_SHAREDBUF)
bp->b_flag & 0x20Description
TRUEnever evaluated
FALSEevaluated 4855 times by 1 test
Evaluated by:
  • Self test
0-4855
451 bp->b_buffer = (char *)NULL;
never executed: bp->b_buffer = (char *) ((void *)0) ;
0
452 free_buffered_stream (bp);-
453 return (close (fd));
executed 4855 times by 1 test: return (close (fd));
Executed by:
  • Self test
4855
454}-
455-
456/* Deallocate the buffered stream associated with file descriptor FD, and-
457 close FD. Return the status of the close on FD. */-
458int-
459close_buffered_fd (fd)-
460 int fd;-
461{-
462 if (fd < 0)
fd < 0Description
TRUEnever evaluated
FALSEevaluated 698794 times by 1 test
Evaluated by:
  • Self test
0-698794
463 {-
464 errno = EBADF;-
465 return -1;
never executed: return -1;
0
466 }-
467 if (fd >= nbuffers || !buffers || !buffers[fd])
fd >= nbuffersDescription
TRUEevaluated 31 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 698763 times by 1 test
Evaluated by:
  • Self test
!buffersDescription
TRUEnever evaluated
FALSEevaluated 698763 times by 1 test
Evaluated by:
  • Self test
!buffers[fd]Description
TRUEevaluated 693908 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 4855 times by 1 test
Evaluated by:
  • Self test
0-698763
468 return (close (fd));
executed 693939 times by 1 test: return (close (fd));
Executed by:
  • Self test
693939
469 return (close_buffered_stream (buffers[fd]));
executed 4855 times by 1 test: return (close_buffered_stream (buffers[fd]));
Executed by:
  • Self test
4855
470}-
471-
472/* Make the BUFFERED_STREAM associated with buffers[FD] be BP, and return-
473 the old BUFFERED_STREAM. */-
474BUFFERED_STREAM *-
475set_buffered_stream (fd, bp)-
476 int fd;-
477 BUFFERED_STREAM *bp;-
478{-
479 BUFFERED_STREAM *ret;-
480-
481 ret = buffers[fd];-
482 buffers[fd] = bp;-
483 return ret;
executed 1432257 times by 1 test: return ret;
Executed by:
  • Self test
1432257
484}-
485-
486/* Read a buffer full of characters from BP, a buffered stream. */-
487static int-
488b_fill_buffer (bp)-
489 BUFFERED_STREAM *bp;-
490{-
491 ssize_t nr;-
492 off_t o;-
493-
494 CHECK_TERMSIG;
never executed: termsig_handler (terminating_signal);
terminating_signalDescription
TRUEnever evaluated
FALSEevaluated 38630 times by 1 test
Evaluated by:
  • Self test
0-38630
495 /* In an environment where text and binary files are treated differently,-
496 compensate for lseek() on text files returning an offset different from-
497 the count of characters read() returns. Text-mode streams have to be-
498 treated as unbuffered. */-
499 if ((bp->b_flag & (B_TEXT | B_UNBUFF)) == B_TEXT)
(bp->b_flag & ...0x04)) == 0x10Description
TRUEnever evaluated
FALSEevaluated 38630 times by 1 test
Evaluated by:
  • Self test
0-38630
500 {-
501 o = lseek (bp->b_fd, 0, SEEK_CUR);-
502 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);-
503 if (nr > 0 && nr < lseek (bp->b_fd, 0, SEEK_CUR) - o)
nr > 0Description
TRUEnever evaluated
FALSEnever evaluated
nr < lseek (bp...fd, 0, 1 ) - oDescription
TRUEnever evaluated
FALSEnever evaluated
0
504 {-
505 lseek (bp->b_fd, o, SEEK_SET);-
506 bp->b_flag |= B_UNBUFF;-
507 bp->b_size = 1;-
508 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);-
509 }
never executed: end of block
0
510 }
never executed: end of block
0
511 else-
512 nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
executed 38630 times by 1 test: nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
Executed by:
  • Self test
38630
513 if (nr <= 0)
nr <= 0Description
TRUEevaluated 338 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 38292 times by 1 test
Evaluated by:
  • Self test
338-38292
514 {-
515 bp->b_used = bp->b_inputp = 0;-
516 bp->b_buffer[0] = 0;-
517 if (nr == 0)
nr == 0Description
TRUEevaluated 338 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-338
518 bp->b_flag |= B_EOF;
executed 338 times by 1 test: bp->b_flag |= 0x01;
Executed by:
  • Self test
338
519 else-
520 bp->b_flag |= B_ERROR;
never executed: bp->b_flag |= 0x02;
0
521 return (EOF);
executed 338 times by 1 test: return ( (-1) );
Executed by:
  • Self test
338
522 }-
523-
524 bp->b_used = nr;-
525 bp->b_inputp = 0;-
526 return (bp->b_buffer[bp->b_inputp++] & 0xFF);
executed 38292 times by 1 test: return (bp->b_buffer[bp->b_inputp++] & 0xFF);
Executed by:
  • Self test
38292
527}-
528-
529/* Get a character from buffered stream BP. */-
530#define bufstream_getc(bp) \-
531 (bp->b_inputp == bp->b_used || !bp->b_used) \-
532 ? b_fill_buffer (bp) \-
533 : bp->b_buffer[bp->b_inputp++] & 0xFF-
534-
535/* Push C back onto buffered stream BP. */-
536static int-
537bufstream_ungetc(c, bp)-
538 int c;-
539 BUFFERED_STREAM *bp;-
540{-
541 if (c == EOF || bp == 0 || bp->b_inputp == 0)
c == (-1)Description
TRUEnever evaluated
FALSEevaluated 1160 times by 1 test
Evaluated by:
  • Self test
bp == 0Description
TRUEnever evaluated
FALSEevaluated 1160 times by 1 test
Evaluated by:
  • Self test
bp->b_inputp == 0Description
TRUEnever evaluated
FALSEevaluated 1160 times by 1 test
Evaluated by:
  • Self test
0-1160
542 return (EOF);
never executed: return ( (-1) );
0
543-
544 bp->b_buffer[--bp->b_inputp] = c;-
545 return (c);
executed 1160 times by 1 test: return (c);
Executed by:
  • Self test
1160
546}-
547-
548/* Seek backwards on file BFD to synchronize what we've read so far-
549 with the underlying file pointer. */-
550int-
551sync_buffered_stream (bfd)-
552 int bfd;-
553{-
554 BUFFERED_STREAM *bp;-
555 off_t chars_left;-
556-
557 if (buffers == 0 || (bp = buffers[bfd]) == 0)
buffers == 0Description
TRUEnever evaluated
FALSEevaluated 3984410 times by 1 test
Evaluated by:
  • Self test
(bp = buffers[bfd]) == 0Description
TRUEevaluated 6919 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 3977491 times by 1 test
Evaluated by:
  • Self test
0-3984410
558 return (-1);
executed 6919 times by 1 test: return (-1);
Executed by:
  • Self test
6919
559-
560 chars_left = bp->b_used - bp->b_inputp;-
561 if (chars_left)
chars_leftDescription
TRUEevaluated 37747 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 3939744 times by 1 test
Evaluated by:
  • Self test
37747-3939744
562 lseek (bp->b_fd, -chars_left, SEEK_CUR);
executed 37747 times by 1 test: lseek (bp->b_fd, -chars_left, 1 );
Executed by:
  • Self test
37747
563 bp->b_used = bp->b_inputp = 0;-
564 return (0);
executed 3977491 times by 1 test: return (0);
Executed by:
  • Self test
3977491
565}-
566-
567int-
568buffered_getchar ()-
569{-
570 CHECK_TERMSIG;
never executed: termsig_handler (terminating_signal);
terminating_signalDescription
TRUEnever evaluated
FALSEevaluated 13228869 times by 1 test
Evaluated by:
  • Self test
0-13228869
571-
572 if (bash_input.location.buffered_fd < 0 || buffers[bash_input.location.buffered_fd] == 0)
bash_input.loc...uffered_fd < 0Description
TRUEnever evaluated
FALSEevaluated 13228869 times by 1 test
Evaluated by:
  • Self test
buffers[bash_i...fered_fd] == 0Description
TRUEnever evaluated
FALSEevaluated 13228869 times by 1 test
Evaluated by:
  • Self test
0-13228869
573 return EOF;
never executed: return (-1) ;
0
574-
575#if !defined (DJGPP)-
576 return (bufstream_getc (buffers[bash_input.location.buffered_fd]));
executed 13228869 times by 1 test: return ((buffers[bash_input.location.buffered_fd]->b_inputp == buffers[bash_input.location.buffered_fd]->b_used || !buffers[bash_input.location.buffered_fd]->b_used) ? b_fill_buffer (buffers[bash_input.location.buffered_fd]) : buffers[bash_input.location.buffered_fd]->b_buffer[buffers[bash_input.location.buffered_fd]->b_inputp++] & 0xFF);
Executed by:
  • Self test
13228869
577#else-
578 /* On DJGPP, ignore \r. */-
579 int ch;-
580 while ((ch = bufstream_getc (buffers[bash_input.location.buffered_fd])) == '\r')-
581 ;-
582 return ch;-
583#endif-
584}-
585-
586int-
587buffered_ungetchar (c)-
588 int c;-
589{-
590 return (bufstream_ungetc (c, buffers[bash_input.location.buffered_fd]));
executed 1160 times by 1 test: return (bufstream_ungetc (c, buffers[bash_input.location.buffered_fd]));
Executed by:
  • Self test
1160
591}-
592-
593/* Make input come from file descriptor BFD through a buffered stream. */-
594void-
595with_input_from_buffered_stream (bfd, name)-
596 int bfd;-
597 char *name;-
598{-
599 INPUT_STREAM location;-
600 BUFFERED_STREAM *bp;-
601-
602 location.buffered_fd = bfd;-
603 /* Make sure the buffered stream exists. */-
604 bp = fd_to_buffered_stream (bfd);-
605 init_yy_io (bp == 0 ? return_EOF : buffered_getchar,-
606 buffered_ungetchar, st_bstream, name, location);-
607}
executed 5266 times by 1 test: end of block
Executed by:
  • Self test
5266
608-
609#if defined (TEST)-
610void *-
611xmalloc(s)-
612int s;-
613{-
614 return (malloc (s));-
615}-
616-
617void *-
618xrealloc(s, size)-
619char *s;-
620int size;-
621{-
622 if (!s)-
623 return(malloc (size));-
624 else-
625 return(realloc (s, size));-
626}-
627-
628void-
629init_yy_io ()-
630{-
631}-
632-
633process(bp)-
634BUFFERED_STREAM *bp;-
635{-
636 int c;-
637-
638 while ((c = bufstream_getc(bp)) != EOF)-
639 putchar(c);-
640}-
641-
642BASH_INPUT bash_input;-
643-
644struct stat dsb; /* can be used from gdb */-
645-
646/* imitate /bin/cat */-
647main(argc, argv)-
648int argc;-
649char **argv;-
650{-
651 register int i;-
652 BUFFERED_STREAM *bp;-
653-
654 if (argc == 1) {-
655 bp = fd_to_buffered_stream (0);-
656 process(bp);-
657 exit(0);-
658 }-
659 for (i = 1; i < argc; i++) {-
660 if (argv[i][0] == '-' && argv[i][1] == '\0') {-
661 bp = fd_to_buffered_stream (0);-
662 if (!bp)-
663 continue;-
664 process(bp);-
665 free_buffered_stream (bp);-
666 } else {-
667 bp = open_buffered_stream (argv[i]);-
668 if (!bp)-
669 continue;-
670 process(bp);-
671 close_buffered_stream (bp);-
672 }-
673 }-
674 exit(0);-
675}-
676#endif /* TEST */-
677#endif /* BUFFERED_INPUT */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2