--- /dev/null
+/*
+ * 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);
+ }
+}