Add complete_read(), an EINTR-proof and partial-read-proof read,
authorPaul Mackerras <paulus@samba.org>
Sun, 30 Mar 2003 08:26:56 +0000 (08:26 +0000)
committerPaul Mackerras <paulus@samba.org>
Sun, 30 Mar 2003 08:26:56 +0000 (08:26 +0000)
and use it for reading synchronization pipes.

pppd/main.c
pppd/pppd.h
pppd/utils.c

index 7b57a2a570e6c771f2909f4c024ec3c5c93e9ba1..6bb4b65b256efb9255d2c1121b081cdd897b1a39 100644 (file)
@@ -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 <stdio.h>
 #include <ctype.h>
@@ -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;
        }
index 60ca8b54f230f56992e08ce1704042234fb758e3..75b344f0058c323211e7b4469154183bdf9282a5 100644 (file)
@@ -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 */
index 8c7045298b7bf0546022fc25a8a705549df12659..fb2c6aa20b05af1cfb9be9c27b3d8f3520c87a55 100644 (file)
@@ -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 <stdio.h>
 #include <ctype.h>
@@ -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__