From: Paul Mackerras Date: Sun, 30 Mar 2003 08:26:56 +0000 (+0000) Subject: Add complete_read(), an EINTR-proof and partial-read-proof read, X-Git-Tag: ppp-2.4.7~312 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=d524a1339c6016f60dcebdddc7536f510a558ada Add complete_read(), an EINTR-proof and partial-read-proof read, and use it for reading synchronization pipes. --- diff --git a/pppd/main.c b/pppd/main.c index 7b57a2a..6bb4b65 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -40,7 +40,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: main.c,v 1.124 2003/03/04 05:37:22 fcusack Exp $" +#define RCSID "$Id: main.c,v 1.125 2003/03/30 08:26:56 paulus Exp $" #include #include @@ -822,7 +822,7 @@ detach() /* wait for parent to finish updating pid & lock files and die */ close(pipefd[1]); - read(pipefd[0], numbuf, 1); + complete_read(pipefd[0], numbuf, 1); close(pipefd[0]); } @@ -852,7 +852,7 @@ create_pidfile(pid) slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", _PATH_VARRUN, ifname); if ((pidfile = fopen(pidfilename, "w")) != NULL) { - fprintf(pidfile, "%d\n", getpid()); + fprintf(pidfile, "%d\n", pid); (void) fclose(pidfile); } else { error("Failed to create pid file %s: %m", pidfilename); @@ -872,7 +872,7 @@ create_linkpidfile(pid) slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", _PATH_VARRUN, linkname); if ((pidfile = fopen(linkpidfile, "w")) != NULL) { - fprintf(pidfile, "%d\n", getpid()); + fprintf(pidfile, "%d\n", pid); if (ifname[0]) fprintf(pidfile, "%s\n", ifname); (void) fclose(pidfile); @@ -1428,9 +1428,7 @@ safe_fork() if (pid > 0) { close(pipefd[1]); /* this read() blocks until the close(pipefd[1]) below */ - while (read(pipefd[0], buf, 1) < 0) - if (errno != EINTR) - break; + complete_read(pipefd[0], buf, 1); close(pipefd[0]); return pid; } diff --git a/pppd/pppd.h b/pppd/pppd.h index 60ca8b5..75b344f 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -39,7 +39,7 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: pppd.h,v 1.80 2003/03/03 05:11:46 paulus Exp $ + * $Id: pppd.h,v 1.81 2003/03/30 08:26:56 paulus Exp $ */ /* @@ -511,6 +511,8 @@ void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ void end_pr_log __P((void)); /* finish up after using pr_log */ void dump_packet __P((const char *, u_char *, int)); /* dump packet to debug log if interesting */ +ssize_t complete_read __P((int, void *, size_t)); + /* read a complete buffer */ /* Procedures exported from auth.c */ void link_required __P((int)); /* we are starting to use the link */ diff --git a/pppd/utils.c b/pppd/utils.c index 8c70452..fb2c6aa 100644 --- a/pppd/utils.c +++ b/pppd/utils.c @@ -33,7 +33,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: utils.c,v 1.20 2002/12/04 23:03:33 paulus Exp $" +#define RCSID "$Id: utils.c,v 1.21 2003/03/30 08:26:56 paulus Exp $" #include #include @@ -832,6 +832,32 @@ dump_packet(const char *tag, unsigned char *p, int len) dbglog("%s %P", tag, p, len); } +/* + * complete_read - read a full `count' bytes from fd, + * unless end-of-file or an error other than EINTR is encountered. + */ +ssize_t +complete_read(int fd, void *buf, size_t count) +{ + size_t done; + ssize_t nb; + char *ptr = buf; + + for (done = 0; done < count; ) { + nb = read(fd, ptr, count - done); + if (nb < 0) { + if (errno == EINTR) + continue; + return -1; + } + if (nb == 0) + break; + done += nb; + ptr += nb; + } + return done; +} + /* Procedures for locking the serial device using a lock file. */ #ifndef LOCK_DIR #ifdef __linux__