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
= ptr
- sizeof(*a
);
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
= ptr
- sizeof(*a
);
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 */