1 1.1 pooka /* 2 1.1 pooka * dhcpcd - DHCP client daemon 3 1.1 pooka * Copyright (c) 2006-2009 Roy Marples <roy (at) marples.name> 4 1.1 pooka * All rights reserved 5 1.1 pooka 6 1.1 pooka * Redistribution and use in source and binary forms, with or without 7 1.1 pooka * modification, are permitted provided that the following conditions 8 1.1 pooka * are met: 9 1.1 pooka * 1. Redistributions of source code must retain the above copyright 10 1.1 pooka * notice, this list of conditions and the following disclaimer. 11 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 pooka * notice, this list of conditions and the following disclaimer in the 13 1.1 pooka * documentation and/or other materials provided with the distribution. 14 1.1 pooka * 15 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 1.1 pooka * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 1.1 pooka * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 1.1 pooka * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 1.1 pooka * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 pooka * SUCH DAMAGE. 26 1.1 pooka */ 27 1.1 pooka 28 1.1 pooka /* Needed define to get at getline for glibc and FreeBSD */ 29 1.1 pooka #ifndef _GNU_SOURCE 30 1.1 pooka # define _GNU_SOURCE 31 1.1 pooka #endif 32 1.1 pooka 33 1.1 pooka #include <sys/cdefs.h> 34 1.1 pooka 35 1.1 pooka #ifdef __APPLE__ 36 1.1 pooka # include <mach/mach_time.h> 37 1.1 pooka # include <mach/kern_return.h> 38 1.1 pooka #endif 39 1.1 pooka 40 1.1 pooka #include <sys/param.h> 41 1.1 pooka #include <sys/time.h> 42 1.1 pooka 43 1.1 pooka #include <errno.h> 44 1.1 pooka #include <fcntl.h> 45 1.1 pooka #include <limits.h> 46 1.1 pooka #ifdef BSD 47 1.1 pooka # include <paths.h> 48 1.1 pooka #endif 49 1.1 pooka #include <stdint.h> 50 1.1 pooka #include <stdio.h> 51 1.1 pooka #include <stdlib.h> 52 1.1 pooka #include <string.h> 53 1.1 pooka #include <time.h> 54 1.1 pooka #include <unistd.h> 55 1.1 pooka 56 1.1 pooka #include "common.h" 57 1.1 pooka 58 1.1 pooka #ifndef _PATH_DEVNULL 59 1.1 pooka # define _PATH_DEVNULL "/dev/null" 60 1.1 pooka #endif 61 1.1 pooka 62 1.1 pooka int clock_monotonic; 63 1.1 pooka #ifdef DEBUG_MEMORY 64 1.1 pooka static char lbuf_set; 65 1.1 pooka #endif 66 1.1 pooka 67 1.1 pooka #ifdef DEBUG_MEMORY 68 1.1 pooka static void 69 1.1 pooka free_lbuf(void) 70 1.1 pooka { 71 1.1 pooka free(lbuf); 72 1.1 pooka lbuf = NULL; 73 1.1 pooka } 74 1.1 pooka #endif 75 1.1 pooka 76 1.1 pooka /* Handy function to get the time. 77 1.1 pooka * We only care about time advancements, not the actual time itself 78 1.1 pooka * Which is why we use CLOCK_MONOTONIC, but it is not available on all 79 1.1 pooka * platforms. 80 1.1 pooka */ 81 1.1 pooka #define NO_MONOTONIC "host does not support a monotonic clock - timing can skew" 82 1.1 pooka int 83 1.1 pooka get_monotonic(struct timeval *tp) 84 1.1 pooka { 85 1.1 pooka static int posix_clock_set = 0; 86 1.1 pooka #if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) 87 1.1 pooka struct timespec ts; 88 1.1 pooka static clockid_t posix_clock; 89 1.1 pooka 90 1.1 pooka if (!posix_clock_set) { 91 1.1 pooka if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 92 1.1 pooka posix_clock = CLOCK_MONOTONIC; 93 1.1 pooka clock_monotonic = posix_clock_set = 1; 94 1.1 pooka } 95 1.1 pooka } 96 1.1 pooka 97 1.1 pooka if (clock_monotonic) { 98 1.1 pooka if (clock_gettime(posix_clock, &ts) == 0) { 99 1.1 pooka tp->tv_sec = ts.tv_sec; 100 1.1 pooka tp->tv_usec = ts.tv_nsec / 1000; 101 1.1 pooka return 0; 102 1.1 pooka } 103 1.1 pooka } 104 1.1 pooka #elif defined(__APPLE__) 105 1.1 pooka #define NSEC_PER_SEC 1000000000 106 1.1 pooka /* We can use mach kernel functions here. 107 1.1 pooka * This is crap though - why can't they implement clock_gettime?*/ 108 1.1 pooka static struct mach_timebase_info info = { 0, 0 }; 109 1.1 pooka static double factor = 0.0; 110 1.1 pooka uint64_t nano; 111 1.1 pooka long rem; 112 1.1 pooka 113 1.1 pooka if (!posix_clock_set) { 114 1.1 pooka if (mach_timebase_info(&info) == KERN_SUCCESS) { 115 1.1 pooka factor = (double)info.numer / (double)info.denom; 116 1.1 pooka clock_monotonic = posix_clock_set = 1; 117 1.1 pooka } 118 1.1 pooka } 119 1.1 pooka if (clock_monotonic) { 120 1.1 pooka nano = mach_absolute_time(); 121 1.1 pooka if ((info.denom != 1 || info.numer != 1) && factor != 0.0) 122 1.1 pooka nano *= factor; 123 1.1 pooka tp->tv_sec = nano / NSEC_PER_SEC; 124 1.1 pooka rem = nano % NSEC_PER_SEC; 125 1.1 pooka if (rem < 0) { 126 1.1 pooka tp->tv_sec--; 127 1.1 pooka rem += NSEC_PER_SEC; 128 1.1 pooka } 129 1.1 pooka tp->tv_usec = rem / 1000; 130 1.1 pooka return 0; 131 1.1 pooka } 132 1.1 pooka #endif 133 1.1 pooka 134 1.1 pooka /* Something above failed, so fall back to gettimeofday */ 135 1.1 pooka if (!posix_clock_set) { 136 1.1 pooka posix_clock_set = 1; 137 1.1 pooka } 138 1.1 pooka return gettimeofday(tp, NULL); 139 1.1 pooka } 140 1.1 pooka 141 1.1 pooka time_t 142 1.1 pooka uptime(void) 143 1.1 pooka { 144 1.1 pooka struct timeval tv; 145 1.1 pooka 146 1.1 pooka if (get_monotonic(&tv) == -1) 147 1.1 pooka return -1; 148 1.1 pooka return tv.tv_sec; 149 1.1 pooka } 150 1.1 pooka 151 1.1 pooka void * 152 1.1 pooka xmalloc(size_t s) 153 1.1 pooka { 154 1.1 pooka void *value = malloc(s); 155 1.1 pooka 156 1.1 pooka if (value != NULL) 157 1.1 pooka return value; 158 1.1 pooka abort(); 159 1.1 pooka /* NOTREACHED */ 160 1.1 pooka } 161 1.1 pooka 162 1.1 pooka void * 163 1.1 pooka xzalloc(size_t s) 164 1.1 pooka { 165 1.1 pooka void *value = xmalloc(s); 166 1.1 pooka 167 1.1 pooka memset(value, 0, s); 168 1.1 pooka return value; 169 1.1 pooka } 170 1.1 pooka 171 1.1 pooka void * 172 1.1 pooka xrealloc(void *ptr, size_t s) 173 1.1 pooka { 174 1.1 pooka void *value = realloc(ptr, s); 175 1.1 pooka 176 1.1 pooka if (value != NULL) 177 1.1 pooka return value; 178 1.1 pooka abort(); 179 1.1 pooka /* NOTREACHED */ 180 1.1 pooka } 181 1.1 pooka 182 1.1 pooka char * 183 1.1 pooka xstrdup(const char *str) 184 1.1 pooka { 185 1.1 pooka char *value; 186 1.1 pooka 187 1.1 pooka if (str == NULL) 188 1.1 pooka return NULL; 189 1.1 pooka 190 1.1 pooka if ((value = strdup(str)) != NULL) 191 1.1 pooka return value; 192 1.1 pooka 193 1.1 pooka abort(); 194 1.1 pooka /* NOTREACHED */ 195 1.1 pooka } 196