"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/safeio.c" (18 Jan 2000, 5259 Bytes) of package /linux/misc/old/pidentd-3.0.19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "safeio.c" see the Fossies "Dox" file reference documentation.

    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
  199 s_getsockname(int fd,
  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
  214 s_getpeername(int fd,
  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 
  229 static pthread_mutex_t random_lock;
  230 static pthread_once_t random_once = PTHREAD_ONCE_INIT;
  231 
  232 static void
  233 random_lock_init(void)
  234 {
  235     unsigned int seed;
  236     
  237     pthread_mutex_init(&random_lock, NULL);
  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     
  253     pthread_once(&random_once, random_lock_init);
  254     
  255     pthread_mutex_lock(&random_lock);
  256 #ifdef HAVE_RANDOM
  257     res = random();
  258 #else
  259     res = rand();
  260 #endif
  261     pthread_mutex_unlock(&random_lock);
  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 }