2 * OS specific functions for UNIX/POSIX systems
3 * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
23 #include "wpa_debug.h"
26 static struct dl_list alloc_list;
28 #define ALLOC_MAGIC 0xa84ef1b2
29 #define FREED_MAGIC 0x67fd487a
31 struct os_alloc_trace {
38 #endif /* WPA_TRACE */
41 void os_sleep(os_time_t sec, os_time_t usec)
50 int os_get_time(struct os_time *t)
54 res = gettimeofday(&tv, NULL);
61 int os_mktime(int year, int month, int day, int hour, int min, int sec,
65 time_t t_local, t1, t2;
68 if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
69 hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
73 memset(&tm, 0, sizeof(tm));
74 tm.tm_year = year - 1900;
75 tm.tm_mon = month - 1;
81 t_local = mktime(&tm);
83 /* figure out offset to UTC */
84 tm1 = localtime(&t_local);
87 tm1 = gmtime(&t_local);
96 *t = (os_time_t) t_local - tz_offset;
103 static int os_daemon(int nochdir, int noclose)
110 devnull = open("/dev/null", O_RDWR);
114 if (dup2(devnull, STDIN_FILENO) < 0) {
119 if (dup2(devnull, STDOUT_FILENO) < 0) {
124 if (dup2(devnull, STDERR_FILENO) < 0) {
131 #else /* __APPLE__ */
132 #define os_daemon daemon
133 #endif /* __APPLE__ */
136 int os_daemonize(const char *pid_file)
140 #else /* __uClinux__ */
141 if (os_daemon(0, 0)) {
147 FILE *f = fopen(pid_file, "w");
149 fprintf(f, "%u\n", getpid());
155 #endif /* __uClinux__ */
159 void os_daemonize_terminate(const char *pid_file)
166 int os_get_random(unsigned char *buf, size_t len)
171 f = fopen("/dev/urandom", "rb");
173 printf("Could not open /dev/urandom.\n");
177 rc = fread(buf, 1, len, f);
180 return rc != len ? -1 : 0;
184 unsigned long os_random(void)
190 char * os_rel2abs_path(const char *rel_path)
192 char *buf = NULL, *cwd, *ret;
193 size_t len = 128, cwd_len, rel_len, ret_len;
196 if (rel_path[0] == '/')
197 return os_strdup(rel_path);
200 buf = os_malloc(len);
203 cwd = getcwd(buf, len);
207 if (last_errno != ERANGE)
218 cwd_len = os_strlen(cwd);
219 rel_len = os_strlen(rel_path);
220 ret_len = cwd_len + 1 + rel_len + 1;
221 ret = os_malloc(ret_len);
223 os_memcpy(ret, cwd, cwd_len);
225 os_memcpy(ret + cwd_len + 1, rel_path, rel_len);
226 ret[ret_len - 1] = '\0';
233 int os_program_init(void)
236 dl_list_init(&alloc_list);
237 #endif /* WPA_TRACE */
242 void os_program_deinit(void)
245 struct os_alloc_trace *a;
246 unsigned long total = 0;
247 dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) {
249 if (a->magic != ALLOC_MAGIC) {
250 wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x "
252 a, a->magic, (unsigned long) a->len);
255 wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu",
256 a, (unsigned long) a->len);
257 wpa_trace_dump("memleak", a);
260 wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes",
261 (unsigned long) total);
262 #endif /* WPA_TRACE */
266 int os_setenv(const char *name, const char *value, int overwrite)
268 return setenv(name, value, overwrite);
272 int os_unsetenv(const char *name)
274 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
279 return unsetenv(name);
284 char * os_readfile(const char *name, size_t *len)
289 f = fopen(name, "rb");
293 fseek(f, 0, SEEK_END);
295 fseek(f, 0, SEEK_SET);
297 buf = os_malloc(*len);
303 if (fread(buf, 1, *len, f) != *len) {
316 void * os_zalloc(size_t size)
318 return calloc(1, size);
320 #endif /* WPA_TRACE */
323 size_t os_strlcpy(char *dest, const char *src, size_t siz)
329 /* Copy string up to the maximum size of the dest buffer */
330 while (--left != 0) {
331 if ((*dest++ = *s++) == '\0')
337 /* Not enough room for the string; force NUL-termination */
341 ; /* determine total src string length */
350 void * os_malloc(size_t size)
352 struct os_alloc_trace *a;
353 a = malloc(sizeof(*a) + size);
356 a->magic = ALLOC_MAGIC;
357 dl_list_add(&alloc_list, &a->list);
364 void * os_realloc(void *ptr, size_t size)
366 struct os_alloc_trace *a;
371 return os_malloc(size);
373 a = (struct os_alloc_trace *) ptr - 1;
374 if (a->magic != ALLOC_MAGIC) {
375 wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s",
377 a->magic == FREED_MAGIC ? " (already freed)" : "");
378 wpa_trace_show("Invalid os_realloc() call");
387 os_memcpy(n, a + 1, copy_len);
393 void os_free(void *ptr)
395 struct os_alloc_trace *a;
399 a = (struct os_alloc_trace *) ptr - 1;
400 if (a->magic != ALLOC_MAGIC) {
401 wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s",
403 a->magic == FREED_MAGIC ? " (already freed)" : "");
404 wpa_trace_show("Invalid os_free() call");
407 dl_list_del(&a->list);
408 a->magic = FREED_MAGIC;
410 wpa_trace_check_ref(ptr);
415 void * os_zalloc(size_t size)
417 void *ptr = os_malloc(size);
419 os_memset(ptr, 0, size);
424 char * os_strdup(const char *s)
429 d = os_malloc(len + 1);
432 os_memcpy(d, s, len);
437 #endif /* WPA_TRACE */