"Fossies" - the Fresh Open Source Software Archive

Member "opendnssec-2.1.4/common/locks.c" (16 May 2019, 7736 Bytes) of package /linux/misc/dns/opendnssec-2.1.4.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 "locks.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 2009 NLNet Labs. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  *
   25  */
   26 
   27 /**
   28  * Threading and locking.
   29  *
   30  */
   31 
   32 #include "config.h"
   33 #include "locks.h"
   34 #include "log.h"
   35 
   36 #include <stdio.h>
   37 #include <stdarg.h>
   38 #include <limits.h>
   39 #include <syslog.h>
   40 #include <unistd.h>
   41 #include <errno.h>
   42 #include <signal.h> /* sigfillset(), sigprocmask() */
   43 #include <string.h> /* strerror() */
   44 #include <time.h> /* gettimeofday() */
   45 
   46 static const char* lock_str = "lock";
   47 
   48 int
   49 ods_thread_wait(pthread_cond_t* cond, pthread_mutex_t* lock, time_t wait)
   50 {
   51     struct timespec ts;
   52 
   53     if (wait <= 0)
   54         return pthread_cond_wait(cond, lock);
   55 
   56     if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
   57         ods_log_error("[%s] clock_gettime() error: %s", lock_str,
   58             strerror(errno));
   59         return 1;
   60     }
   61 
   62     ts.tv_sec += wait;
   63     return pthread_cond_timedwait(cond, lock, &ts);
   64 }
   65 
   66 janitor_threadclass_t detachedthreadclass;
   67 janitor_threadclass_t workerthreadclass;
   68 janitor_threadclass_t handlerthreadclass;
   69 janitor_threadclass_t cmdhandlerthreadclass;
   70 
   71 struct alertbuffer_struct {
   72     char buffer[1024];
   73     int index;
   74 };
   75 static void alert(struct alertbuffer_struct* buffer, const char *format, ...)
   76 #ifdef HAVE___ATTRIBUTE__
   77      __attribute__ ((format (printf, 2, 3)))
   78 #endif
   79 ;
   80 static void alertsyslog(const char* format, ...)
   81 #ifdef HAVE___ATTRIBUTE__
   82      __attribute__ ((format (printf, 1, 2)))
   83 #endif
   84 ;
   85 
   86 inline static int
   87 alertoutput(struct alertbuffer_struct* buffer, int ch)
   88 {
   89     if (buffer->index < sizeof(buffer->buffer)) {
   90         buffer->buffer[buffer->index++] = ch;
   91         return 0;
   92     } else
   93         return -1;
   94 }
   95 
   96 static void
   97 alertinteger(struct alertbuffer_struct* buffer, unsigned long value, int base)
   98 {
   99     char ch;
  100     if (value > base - 1)
  101         alertinteger(buffer, value / base, base);
  102     ch = "0123456789abcdef"[value % base];
  103     alertoutput(buffer, ch);
  104 }
  105 
  106 static void
  107 valert(struct alertbuffer_struct* buffer, const char* format, va_list args)
  108 {
  109     int idx, len;
  110     const char* stringarg;
  111     void* pointerarg;
  112     int integerarg;
  113     long longarg;
  114     idx = 0;
  115     while (format[idx]) {
  116         if (format[idx] == '%') {
  117             switch (format[idx + 1]) {
  118                 case '%':
  119                     alertoutput(buffer, '%');
  120                     idx += 2;
  121                     break;
  122                 case 's':
  123                     stringarg = va_arg(args, char*);
  124                     if (stringarg == NULL)
  125                         stringarg = "(null)";
  126                     while(*stringarg)
  127                         if(alertoutput(buffer, *(stringarg++)))
  128                             break;
  129                     idx += 2;
  130                     break;
  131                 case 'p':
  132                     pointerarg = va_arg(args, void*);
  133                     if (pointerarg == NULL) {
  134                         stringarg = "(null)";
  135                         while(stringarg)
  136                             alertoutput(buffer, *(stringarg++));
  137                     } else {
  138                         alertoutput(buffer, '0');
  139                         alertoutput(buffer, 'x');
  140                         alertinteger(buffer, (unsigned long) pointerarg, 16);
  141                     }
  142                     idx += 2;
  143                     break;
  144                 case 'l':
  145                     switch (format[idx + 2]) {
  146                         case 'd':
  147                             longarg = va_arg(args, long);
  148                             if (longarg < 0) {
  149                                 alertoutput(buffer, '-');
  150                                 alertinteger(buffer, 1UL + ~((unsigned long) longarg), 10);
  151                             } else
  152                                 alertinteger(buffer, longarg, 10);
  153                             idx += 3;
  154                             break;
  155                         case '\0':
  156                             alertoutput(buffer, format[idx++]);
  157                             break;
  158                         default:
  159                             alertoutput(buffer, format[idx++]);
  160                             alertoutput(buffer, format[idx++]);
  161                             alertoutput(buffer, format[idx++]);
  162                     }
  163                     break;
  164                 case 'd':
  165                     integerarg = va_arg(args, int);
  166                     alertinteger(buffer, (long) integerarg, 10);
  167                     idx += 2;
  168                     break;
  169                 case '\0':
  170                     alertoutput(buffer, '%');
  171                     idx += 1;
  172                     break;
  173                 default:
  174                     alertoutput(buffer, format[idx++]);
  175                     alertoutput(buffer, format[idx++]);
  176             }
  177         } else {
  178             alertoutput(buffer, format[idx++]);
  179         }
  180     }
  181 }
  182 
  183 static void
  184 alertsyslog(const char* format, ...)
  185 {
  186     va_list args;
  187     struct alertbuffer_struct buffer;
  188     va_start(args, format);
  189     buffer.index = 0;
  190     valert(&buffer, format, args);
  191     va_end(args);
  192     if (buffer.index < sizeof(buffer.buffer)) {
  193         buffer.buffer[buffer.index] = '\0';
  194     } else {
  195         strcpy(&buffer.buffer[buffer.index - strlen("...\n") -1], "...\n");
  196     }
  197     (void)write(2, buffer.buffer, strlen(buffer.buffer));
  198     syslog(LOG_CRIT, "%s", buffer.buffer);
  199 }
  200 
  201 void
  202 ods_janitor_initialize(char*argv0)
  203 {
  204     janitor_initialize(alertsyslog, ods_log_error);
  205 
  206     janitor_threadclass_create(&detachedthreadclass, "daemonthreads");
  207     janitor_threadclass_setautorun(detachedthreadclass);
  208     janitor_threadclass_setblockedsignals(detachedthreadclass);
  209     janitor_threadclass_setdetached(detachedthreadclass);
  210     janitor_threadclass_setminstacksize(detachedthreadclass, ODS_MINIMUM_STACKSIZE);
  211 
  212     janitor_threadclass_create(&workerthreadclass, "workerthreads");
  213     janitor_threadclass_setautorun(workerthreadclass);
  214     janitor_threadclass_setblockedsignals(workerthreadclass);
  215     janitor_threadclass_setminstacksize(workerthreadclass, ODS_MINIMUM_STACKSIZE);
  216 
  217     janitor_threadclass_create(&handlerthreadclass, "handlerthreads");
  218     janitor_threadclass_setautorun(handlerthreadclass);
  219     janitor_threadclass_setminstacksize(handlerthreadclass, ODS_MINIMUM_STACKSIZE);
  220 
  221     janitor_threadclass_create(&cmdhandlerthreadclass, "cmdhandlerthreads");
  222     janitor_threadclass_setautorun(cmdhandlerthreadclass);
  223     janitor_threadclass_setblockedsignals(workerthreadclass);
  224     janitor_threadclass_setminstacksize(cmdhandlerthreadclass, ODS_MINIMUM_STACKSIZE);
  225 
  226     janitor_trapsignals(argv0);
  227 }