(safe_read): Get this function from gcc's cccp.c.
[gnulib.git] / lib / safe-read.c
1 /* safe-read.c -- an interface to read that retries after interrupts
2    Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17    */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <sys/types.h>
24
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #include <errno.h>
30 #ifndef STDC_HEADERS
31 extern int errno;
32 #endif
33
34 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
35    retrying if necessary.  Return a negative value if an error occurs,
36    otherwise return the actual number of bytes read,
37    which must be LEN unless end-of-file was reached.  */
38
39    The canonical source for this function is in the gcc distribution
40    in file cccp.c.  So don't make any changes here.  */
41
42 static int
43 safe_read (desc, ptr, len)
44      int desc;
45      char *ptr;
46      int len;
47 {
48   int left = len;
49   while (left > 0) {
50     int nchars = read (desc, ptr, left);
51     if (nchars < 0)
52       {
53 #ifdef EINTR
54         if (errno == EINTR)
55           continue;
56 #endif
57         return nchars;
58       }
59     if (nchars == 0)
60       break;
61     ptr += nchars;
62     left -= nchars;
63   }
64   return len - left;
65 }