chiark / gitweb /
Upgrade licence to GPLv3+.
[userv.git] / both.c
1 /*
2  * userv - both.c
3  * Useful very-low-level utility routines, used in both client and daemon.
4  * These do not (and cannot) depend on infrastructure eg syscallerror,
5  * because these are not the same.
6  *
7  * userv is
8  * Copyright 1996-2017 Ian Jackson <ian@davenant.greenend.org.uk>.
9  * Copyright 2000      Ben Harris <bjh21@cam.ac.uk>
10  * Copyright 2016-2017 Peter Benie <pjb1008@cam.ac.uk>
11  *
12  * This is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with userv; if not, see <http://www.gnu.org/licenses/>.
24  */
25
26 /* Some nasty people can return 0/EOF + EINTR from stdio !
27  * These functions attempt to work around this braindamage by retrying
28  * the call after clearerr.  If this doesn't work then clearly your
29  * libc is _completely_ fubar rather than just somewhat fubar.
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <string.h>
36
37 #include "config.h"
38 #include "both.h"
39
40 void *xmalloc(size_t s) {
41   void *p;
42   p= malloc(s?s:1); if (!p) syscallerror("malloc");
43   return p;
44 }
45
46 void *xrealloc(void *p, size_t s) {
47   p= realloc(p,s);
48   if (!p) syscallerror("realloc");
49   return p;
50 }
51
52 char *xstrsave(const char *s) {
53   char *r;
54
55   r= xmalloc(strlen(s)+1);
56   strcpy(r,s);
57   return r;
58 }
59
60
61 int working_getc(FILE *file) {
62   int c;
63   
64   for (;;) {
65     c= getc(file);
66     if (c != EOF || errno != EINTR) return c;
67     clearerr(file);
68   }
69 }
70
71 size_t working_fread(void *ptr, size_t sz, FILE *file) {
72   size_t done, nr;
73
74   done= 0;
75   for (;;) {
76     nr= fread((char*)ptr + done, 1, sz-done, file);
77     done += nr;
78     if (done == sz || !ferror(file) || errno != EINTR) return done;
79     clearerr(file);
80   }
81 }