pidentd  3.0.19
About: implementation of the RFC1413 identification server (more or less complete rewrite compared to version 2)
  Fossies Dox: pidentd-3.0.19.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

safeio.c
Go to the documentation of this file.
1 /*
2 ** safeio.c - Signal/Async safe wrapper functions
3 **
4 ** Copyright (c) 1997-1999 Peter Eriksson <pen@lysator.liu.se>
5 **
6 ** This program is free software; you can redistribute it and/or
7 ** modify it as you wish - as long as you don't claim that you wrote
8 ** it.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 */
14 
15 #include "config.h"
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <math.h>
22 #ifdef HAVE_UNISTD_H
23 #include <unistd.h>
24 #endif
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <syslog.h>
28 
29 #include "pidentd.h"
30 
31 
32 void
33 s_abort(void)
34 {
35  int *p = (int *) NULL;
36 
37  *p = 4711;
38  abort();
39 }
40 
41 
42 
43 int
44 s_open(const char *path,
45  int oflag,
46  ...)
47 {
48  int s;
49  mode_t mode = 0;
50 
51  if (oflag & O_CREAT)
52  {
53  va_list ap;
54 
55  va_start(ap, oflag);
56  /* FIXME: need to use widened form of mode_t here. */
57  mode = va_arg(ap, int);
58  va_end(ap);
59  }
60 
61  while ((s = open(path, oflag, mode)) < 0 && errno == EINTR)
62  ;
63 
64  if (s < 0 && (errno == EMFILE
65  || errno == ENFILE
66  || errno == ENOMEM
67 #ifdef ENOSR
68  || errno == ENOSR
69 #endif
70  ))
71  {
72  /* Too many open files */
73 
74  syslog(LOG_WARNING, "s_open(\"%s\", 0%o): %m", path, oflag);
75  }
76 
77  return s;
78 }
79 
80 
81 
82 ssize_t
83 s_write(int fd,
84  const char *buf,
85  size_t len)
86 {
87  ssize_t code;
88 
89  while ((code = write(fd, buf, len)) < 0 && errno == EINTR)
90  ;
91 
92  return code;
93 }
94 
95 
96 
97 ssize_t
98 s_read(int fd,
99  char *buf,
100  size_t len)
101 {
102  ssize_t code;
103 
104  while ((code = read(fd, buf, len)) < 0 && errno == EINTR)
105  ;
106 
107  return code;
108 }
109 
110 
111 
112 int
113 s_close(int fd)
114 {
115  int code;
116 
117  while ((code = close(fd)) < 0 && errno == EINTR)
118  ;
119 
120  return code;
121 }
122 
123 
124 
125 /*
126 ** A "safe" malloc, that always succeeds (or logs an
127 ** error to syslog and the abort()'s.
128 **
129 ** The buffer returned is zeroed out.
130 */
131 void *
132 s_malloc(size_t size)
133 {
134  void *p;
135 
136  p = (void *) malloc(size);
137  if (p == NULL)
138  {
139  if (debug)
140  fprintf(stderr, "s_malloc(%lu) failed - aborting\n",
141  (unsigned long) size);
142 
143  syslog(LOG_ERR, "malloc(%lu): %m", (unsigned long) size);
144  s_abort();
145  }
146 
147  memset(p, 0, size);
148  return p;
149 }
150 
151 
152 void
153 s_free(void *p)
154 {
155  if (p != NULL)
156  free(p);
157 }
158 
159 
160 char *
161 s_strdup(const char *s)
162 {
163  char *ns;
164  size_t len;
165 
166 
167  if (s == NULL)
168  return NULL;
169 
170  len = strlen(s)+1;
171  ns = (char *) malloc(len);
172  if (ns == NULL)
173  {
174  syslog(LOG_ERR, "strdup(): malloc(%lu): %m", (unsigned long) len);
175  s_abort();
176  }
177 
178  memcpy(ns, s, len);
179  return ns;
180 }
181 
182 
183 int
184 s_accept(int fd,
185  struct sockaddr *sin,
186  socklen_t *len)
187 {
188  int new_fd;
189 
190 
191  while ((new_fd = accept(fd, sin, len)) < 0 && errno == EINTR)
192  ;
193 
194  return new_fd;
195 }
196 
197 
198 int
200  struct sockaddr *sin,
201  socklen_t *len)
202 {
203  int code;
204 
205 
206  while ((code = getsockname(fd, sin, len)) < 0 && errno == EINTR)
207  ;
208 
209  return code;
210 }
211 
212 
213 int
215  struct sockaddr *sin,
216  socklen_t *len)
217 {
218  int code;
219 
220 
221  while ((code = getpeername(fd, sin, len)) < 0 && errno == EINTR)
222  ;
223 
224  return code;
225 }
226 
227 
228 
231 
232 static void
234 {
235  unsigned int seed;
236 
238 
239  seed = time(NULL);
240 #ifdef HAVE_SRANDOM
241  srandom(seed);
242 #else
243  srand(seed);
244 #endif
245 }
246 
247 
248 long
249 s_random(void)
250 {
251  long res;
252 
254 
256 #ifdef HAVE_RANDOM
257  res = random();
258 #else
259  res = rand();
260 #endif
262 
263  return res;
264 }
265 
266 
267 
268 int
269 s_snprintf(char *buf,
270  size_t bufsize,
271  const char *format,
272  ...)
273 {
274  va_list ap;
275  int retcode;
276 
277 
278  va_start(ap, format);
279 
280  if (bufsize < 1)
281  {
282  if (debug)
283  fprintf(stderr, "s_snprintf(..., %d, ...): illegal bufsize\n",
284  bufsize);
285  syslog(LOG_ERR, "s_snprintf(..., %d, ...): illegal bufsize",
286  bufsize);
287  s_abort();
288  }
289 
290  buf[bufsize-1] = '\0';
291 #ifdef HAVE_VSNPRINTF
292  retcode = vsnprintf(buf, bufsize, format, ap);
293 #else
294 #ifdef SPRINTF_RETVAL_POINTER
295  /* XXX: The reason we check for sprintf()'s return type and not
296  vsprintf() (which we should) is that SunOS 4 doesn't declare
297  vsprintf() in any header files, but it does have the same return
298  value as sprintf(). So expect a compiler warning here. *Sigh* */
299  {
300  char *cp = vsprintf(buf, format, ap);
301  if (cp == NULL)
302  retcode = -1;
303  else
304  retcode = strlen(cp);
305  }
306 #else
307  retcode = vsprintf(buf, format, ap);
308 #endif
309 #endif
310  if (debug > 3)
311  fprintf(stderr, "s_snprintf(%08lx, %d, \"%s\", ...) = %d\n",
312  (unsigned long) buf, bufsize, format, retcode);
313 
314  if (retcode > 0 && (buf[bufsize-1] != '\0' ||
315  retcode > bufsize-1))
316  {
317  if (debug)
318  fprintf(stderr, "s_snprintf(..., %d, ...) = %d: buffer overrun\n",
319  bufsize, retcode);
320  syslog(LOG_ERR, "s_snprintf(..., %d, ...) = %d: buffer overrun\n",
321  bufsize, retcode);
322 
323  s_abort();
324  }
325 
326  va_end(ap);
327 
328  return retcode;
329 }
s_getsockname
int s_getsockname(int fd, struct sockaddr *sin, socklen_t *len)
Definition: safeio.c:199
s_free
void s_free(void *p)
Definition: safeio.c:153
s_strdup
char * s_strdup(const char *s)
Definition: safeio.c:161
pthread_mutex_init
int pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t)
pthread_once
int pthread_once(pthread_once_t *, void(*)(void))
s_snprintf
int s_snprintf(char *buf, size_t bufsize, const char *format,...)
Definition: safeio.c:269
pidentd.h
s_random
long s_random(void)
Definition: safeio.c:249
random_once
static int random_once
Definition: safeio.c:230
PTHREAD_ONCE_INIT
#define PTHREAD_ONCE_INIT
Definition: cma_thr.h:56
random_lock
static int random_lock
Definition: safeio.c:229
s_close
int s_close(int fd)
Definition: safeio.c:113
s_malloc
void * s_malloc(size_t size)
Definition: safeio.c:132
s_getpeername
int s_getpeername(int fd, struct sockaddr *sin, socklen_t *len)
Definition: safeio.c:214
debug
int debug
Definition: gen_osinfo.c:23
cma_t_handle
Definition: hp_pthread.h:26
pthread_mutex_unlock
int pthread_mutex_unlock(pthread_mutex_t *)
s_open
int s_open(const char *path, int oflag,...)
Definition: safeio.c:44
pthread_mutex_lock
int pthread_mutex_lock(pthread_mutex_t *)
s_abort
void s_abort(void)
Definition: safeio.c:33
s_read
ssize_t s_read(int fd, char *buf, size_t len)
Definition: safeio.c:98
s_accept
int s_accept(int fd, struct sockaddr *sin, socklen_t *len)
Definition: safeio.c:184
pthread_once_t
Definition: hp_pthread.h:41
random_lock_init
static void random_lock_init(void)
Definition: safeio.c:233
s_write
ssize_t s_write(int fd, const char *buf, size_t len)
Definition: safeio.c:83
errno
#define errno
Definition: hp_pthread.h:23