chiark / gitweb /
Fixed spurious failure with Interrupted system call; Fixed race when fd closed at... debian_version_0_60_1
authorian <ian>
Sat, 30 Jan 1999 22:54:06 +0000 (22:54 +0000)
committerian <ian>
Sat, 30 Jan 1999 22:54:06 +0000 (22:54 +0000)
.cvsignore
Makefile.in
both.c [new file with mode: 0644]
both.h [new file with mode: 0644]
client.c
debian/changelog
lib.c
lib.h
parser.c
process.c
servexec.c

index 8196f16f149ba959c7a2e974a4e850f629242816..2a264cec268b7749a76203bca3cf3c2f9b59da40 100644 (file)
@@ -19,6 +19,7 @@ config.cache
 config.log
 config.h
 config.status
+Makefile
 
 *.new
 
index bfa02cd7a772f40a9a41e59a0e7011bd0bf320fd..6bf4ea49dc672e353294080f66646307b0fa8387 100644 (file)
@@ -66,7 +66,10 @@ install:     all
                if ! test -f $(etcsubdir)/system.override; then \
                        $(INSTALL_DATA) -o root -g root system.override $(etcsubdir); fi
 
-daemon:                overlord.o process.o servexec.o parserlexer.o debug.o lib.o
+daemon:                overlord.o process.o servexec.o parserlexer.o debug.o lib.o both.o
+               $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+client:                client.o both.o
                $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
 
 lexer.l:       language.i4
@@ -75,9 +78,9 @@ spec.sgml:    spec.sgml.in Makefile
                sed -e '/<version><\/version>/ s/>/&$(VERSION)/' \
                        spec.sgml.in >$@.new && mv -f $@.new $@
 
-client.o:      config.h common.h pcsum.h version.h
+client.o:      config.h common.h pcsum.h both.h version.h
 
-process.o:     config.h common.h pcsum.h daemon.h lib.h tokens.h
+process.o:     config.h common.h pcsum.h both.h daemon.h lib.h tokens.h
 
 overlord.o:    config.h common.h pcsum.h daemon.h
 
diff --git a/both.c b/both.c
new file mode 100644 (file)
index 0000000..46cf85c
--- /dev/null
+++ b/both.c
@@ -0,0 +1,56 @@
+/*
+ * userv - both.c
+ * Useful very-low-level utility routines, used in both client and daemon.
+ * These do not (and cannot) depend on infrastructure eg syscallerror,
+ * because these are not the same.
+ *
+ * Copyright (C)1999 Ian Jackson
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with userv; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Some nasty people can return 0/EOF + EINTR from stdio !
+ * These functions attempt to work around this braindamage by retrying
+ * the call after clearerr.  If this doesn't work then clearly your
+ * libc is _completely_ fubar rather than just somewhat fubar.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "both.h"
+
+int working_getc(FILE *file) {
+  int c;
+  
+  for (;;) {
+    c= getc(file);
+    if (c != EOF || errno != EINTR) return c;
+    clearerr(file);
+  }
+}
+
+size_t working_fread(void *ptr, size_t sz, FILE *file) {
+  size_t done, nr;
+
+  done= 0;
+  for (;;) {
+    nr= fread((char*)ptr + done, 1, sz-done, file);
+    done += nr;
+    if (done == sz || !ferror(file) || errno != EINTR) return done;
+    clearerr(file);
+  }
+}
diff --git a/both.h b/both.h
new file mode 100644 (file)
index 0000000..084405d
--- /dev/null
+++ b/both.h
@@ -0,0 +1,29 @@
+/*
+ * userv - lib.c
+ * Useful very-low-level utility routines' declarations,
+ * for both client and daemon.
+ *
+ * Copyright (C)1999 Ian Jackson
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with userv; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef BOTH_H
+#define BOTH_H
+
+int working_getc(FILE *file);
+size_t working_fread(void *ptr, size_t sz, FILE *file);
+
+#endif
index d201bef428672b9b84683082b990b886f514700e..4987073a3de76dad9d9dcbe55e85ab7cb5b99a37 100644 (file)
--- a/client.c
+++ b/client.c
@@ -72,6 +72,7 @@
 
 #include "config.h"
 #include "common.h"
+#include "both.h"
 #include "version.h"
 
 enum fdmodifiervalues {
@@ -213,7 +214,7 @@ static void NONRETURNPRINTFFORMAT(1,2) protoerror(const char *fmt, ...) {
 
 static void xfread(void *p, size_t sz, FILE *file) {
   size_t nr;
-  nr= fread(p,1,sz,file);
+  nr= working_fread(p,sz,file);
   if (nr != sz) protoreaderror(file,"in data");
 }
 
@@ -277,7 +278,8 @@ static void getprogress(struct progress_msg *progress_r, FILE *file) {
        protoerror("stderr message length %d is far too long",
                   progress_r->data.errmsg.messagelen);
       for (i=0; i<progress_r->data.errmsg.messagelen; i++) {
-       c= getc(file); if (c==EOF) protoreaderror(file,"in error message");
+       c= working_getc(file);
+       if (c==EOF) protoreaderror(file,"in error message");
        if (isprint(c)) putc(c,stderr);
        else fprintf(stderr,"\\x%02x",(unsigned char)c);
       }
@@ -370,6 +372,7 @@ static void sighandler_chld(int ignored) /* DOES return, unlike in daemon */ {
     if (child == 0 || (child == -1 && errno == ECHILD)) break;
     if (child == -1) syscallerror("wait for child process (in sigchld handler)");
     for (fd=0; fd<fdsetupsize && fdsetup[fd].catpid != child; fd++);
+fprintf(stderr,"chld found pid=%ld fd=%d setupsize=%d\n",(long)child,fd,fdsetupsize);
     if (fd>=fdsetupsize) continue; /* perhaps the caller gave us children */
     if ((WIFEXITED(status) && WEXITSTATUS(status)==0) ||
        (WIFSIGNALED(status) && WTERMSIG(status)==SIGPIPE) ||
@@ -1130,6 +1133,7 @@ static void connect_pipes(void) {
   struct sigaction sig;
   char catnamebuf[sizeof(int)*3+30];
   int fd, reading;
+  pid_t child;
   
   for (fd=0; fd<fdsetupsize; fd++) {
     if (!fdsetup[fd].filename) continue;
@@ -1139,9 +1143,12 @@ static void connect_pipes(void) {
       if (fdsetup[fd].copyfd<0)
        syscallerror("open file `%s' for fd %d",fdsetup[fd].filename,fd);
     }
-    fdsetup[fd].catpid= fork();
-    if (fdsetup[fd].catpid==-1) syscallerror("fork for cat for fd %d",fd);
-    if (!fdsetup[fd].catpid) {
+    blocksignals(SIG_BLOCK);
+    child= fork();
+    fdsetup[fd].catpid= child;
+    blocksignals(SIG_UNBLOCK);
+    if (child==-1) syscallerror("fork for cat for fd %d",fd);
+    if (!child) {
       snprintf(catnamebuf,sizeof(catnamebuf),"cat fd%d",fd);
       catnamebuf[sizeof(catnamebuf)-1]= 0;
       sig.sa_handler= SIG_DFL;
index a3639eaa167c919635c8653d6fff5e0f904c310e..8fd0d2f5842daf73bed61c754877b1e76e59bc68 100644 (file)
@@ -11,9 +11,14 @@ userv (0.60.1) frozen unstable; urgency=high
     be security-critical, and the bug can be avoided by not using
     "-quoted strings in configuration files.)
 
+  * Fixed spurious failure with `Interrupted system call' on systems
+    where fread can fail due to read giving EINTR (blech!)
+
+  * Fixed race when fd closed at startup, which could cause
+    `system call failure: kill cat for <fd>: No such process'.
+
   * Fixed spurious assertion failure if user's home directory not
     accessible.
-
   * Fixed a couple of memory and fd leaks in error exits from
     include-directory and include-lookup in parser.c.
 
@@ -31,7 +36,7 @@ userv (0.60.1) frozen unstable; urgency=high
 
   * Debian package description mentions use by system admin.
 
- -- 
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Sat, 30 Jan 1999 22:54:29 +0000
 
 
 *** Main changelog file included here - see far down this file for the
diff --git a/lib.c b/lib.c
index e36382927e158d007eed9bdbb13a3246c73f8f97..7a22d19eae1e96a29dd9214447f33e1024b8418b 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -2,7 +2,7 @@
  * userv - lib.c
  * useful utility routines, used in daemon, but not very dependent on it
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
diff --git a/lib.h b/lib.h
index 81ff9fcec04fdcd18ad7da34f5c89ed91632a67f..c38f2435ad8608c6ca7151baf347d8c6c2a40de4 100644 (file)
--- a/lib.h
+++ b/lib.h
@@ -2,7 +2,7 @@
  * userv - lib.c
  * useful utility routines' imports and exports, used in daemon
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
index e73b4c5a56f97d6a927c03e416ffe29c3f786838..aa11d8ed7355357dc2ec568c0f70b1cc85885fdf 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -6,7 +6,7 @@
  * about m4 quoting &c., but we have to #include it so that the C
  * objects from the lexer are available.
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
index b091f4e5b8876b490f6159eb0a0f071eac07a51d..3ca468cea0414cffc31e94c7cc7299a6c5db6bb5 100644 (file)
--- a/process.c
+++ b/process.c
@@ -2,7 +2,7 @@
  * userv - process.c
  * daemon code to process one request (is parent of service process)
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -60,6 +60,7 @@
 
 #include "config.h"
 #include "common.h"
+#include "both.h"
 #include "daemon.h"
 #include "lib.h"
 #include "tokens.h"
@@ -147,7 +148,7 @@ static void xfflush(FILE *file) {
 
 static void xfread(void *p, size_t sz) {
   size_t nr;
-  nr= fread(p,1,sz,srfile); if (nr == sz) return;
+  nr= working_fread(p,sz,srfile); if (nr == sz) return;
   if (ferror(srfile)) syscallerror("reading from client");
   blocksignals();
   assert(feof(srfile));
index 778cd8b415b50c60fed57e1dbe63b526a77981d5..95c77a5c517cb90e013f9ff2ad6c503faecf2057 100644 (file)
@@ -2,7 +2,7 @@
  * userv - execserv.c
  * daemon code which executes actual service (ie child process)
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by