LCOV - code coverage report
Current view: top level - src/utils - os_unix.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 287 371 77.4 %
Date: 2015-09-27 Functions: 27 27 100.0 %

          Line data    Source code
       1             : /*
       2             :  * OS specific functions for UNIX/POSIX systems
       3             :  * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include <time.h>
      12             : #include <sys/wait.h>
      13             : 
      14             : #ifdef ANDROID
      15             : #include <sys/capability.h>
      16             : #include <sys/prctl.h>
      17             : #include <private/android_filesystem_config.h>
      18             : #endif /* ANDROID */
      19             : 
      20             : #ifdef __MACH__
      21             : #include <CoreServices/CoreServices.h>
      22             : #include <mach/mach.h>
      23             : #include <mach/mach_time.h>
      24             : #endif /* __MACH__ */
      25             : 
      26             : #include "os.h"
      27             : #include "common.h"
      28             : 
      29             : #ifdef WPA_TRACE
      30             : 
      31             : #include "wpa_debug.h"
      32             : #include "trace.h"
      33             : #include "list.h"
      34             : 
      35             : static struct dl_list alloc_list = DL_LIST_HEAD_INIT(alloc_list);
      36             : 
      37             : #define ALLOC_MAGIC 0xa84ef1b2
      38             : #define FREED_MAGIC 0x67fd487a
      39             : 
      40             : struct os_alloc_trace {
      41             :         unsigned int magic;
      42             :         struct dl_list list;
      43             :         size_t len;
      44             :         WPA_TRACE_INFO
      45             : } __attribute__((aligned(16)));
      46             : 
      47             : #endif /* WPA_TRACE */
      48             : 
      49             : 
      50         711 : void os_sleep(os_time_t sec, os_time_t usec)
      51             : {
      52         711 :         if (sec)
      53           1 :                 sleep(sec);
      54         711 :         if (usec)
      55         711 :                 usleep(usec);
      56         711 : }
      57             : 
      58             : 
      59     6017587 : int os_get_time(struct os_time *t)
      60             : {
      61             :         int res;
      62             :         struct timeval tv;
      63     6017587 :         res = gettimeofday(&tv, NULL);
      64     6017587 :         t->sec = tv.tv_sec;
      65     6017587 :         t->usec = tv.tv_usec;
      66     6017587 :         return res;
      67             : }
      68             : 
      69             : 
      70     1639395 : int os_get_reltime(struct os_reltime *t)
      71             : {
      72             : #ifndef __MACH__
      73             : #if defined(CLOCK_BOOTTIME)
      74             :         static clockid_t clock_id = CLOCK_BOOTTIME;
      75             : #elif defined(CLOCK_MONOTONIC)
      76             :         static clockid_t clock_id = CLOCK_MONOTONIC;
      77             : #else
      78             :         static clockid_t clock_id = CLOCK_REALTIME;
      79             : #endif
      80             :         struct timespec ts;
      81             :         int res;
      82             : 
      83             :         while (1) {
      84     1639395 :                 res = clock_gettime(clock_id, &ts);
      85     1639395 :                 if (res == 0) {
      86     1639395 :                         t->sec = ts.tv_sec;
      87     1639395 :                         t->usec = ts.tv_nsec / 1000;
      88     1639395 :                         return 0;
      89             :                 }
      90           0 :                 switch (clock_id) {
      91             : #ifdef CLOCK_BOOTTIME
      92             :                 case CLOCK_BOOTTIME:
      93           0 :                         clock_id = CLOCK_MONOTONIC;
      94           0 :                         break;
      95             : #endif
      96             : #ifdef CLOCK_MONOTONIC
      97             :                 case CLOCK_MONOTONIC:
      98           0 :                         clock_id = CLOCK_REALTIME;
      99           0 :                         break;
     100             : #endif
     101             :                 case CLOCK_REALTIME:
     102           0 :                         return -1;
     103             :                 }
     104           0 :         }
     105             : #else /* __MACH__ */
     106             :         uint64_t abstime, nano;
     107             :         static mach_timebase_info_data_t info = { 0, 0 };
     108             : 
     109             :         if (!info.denom) {
     110             :                 if (mach_timebase_info(&info) != KERN_SUCCESS)
     111             :                         return -1;
     112             :         }
     113             : 
     114             :         abstime = mach_absolute_time();
     115             :         nano = (abstime * info.numer) / info.denom;
     116             : 
     117             :         t->sec = nano / NSEC_PER_SEC;
     118             :         t->usec = (nano - (((uint64_t) t->sec) * NSEC_PER_SEC)) / NSEC_PER_USEC;
     119             : 
     120             :         return 0;
     121             : #endif /* __MACH__ */
     122             : }
     123             : 
     124             : 
     125          14 : int os_mktime(int year, int month, int day, int hour, int min, int sec,
     126             :               os_time_t *t)
     127             : {
     128             :         struct tm tm, *tm1;
     129             :         time_t t_local, t1, t2;
     130             :         os_time_t tz_offset;
     131             : 
     132          14 :         if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
     133           8 :             hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
     134             :             sec > 60)
     135          11 :                 return -1;
     136             : 
     137           3 :         memset(&tm, 0, sizeof(tm));
     138           3 :         tm.tm_year = year - 1900;
     139           3 :         tm.tm_mon = month - 1;
     140           3 :         tm.tm_mday = day;
     141           3 :         tm.tm_hour = hour;
     142           3 :         tm.tm_min = min;
     143           3 :         tm.tm_sec = sec;
     144             : 
     145           3 :         t_local = mktime(&tm);
     146             : 
     147             :         /* figure out offset to UTC */
     148           3 :         tm1 = localtime(&t_local);
     149           3 :         if (tm1) {
     150           3 :                 t1 = mktime(tm1);
     151           3 :                 tm1 = gmtime(&t_local);
     152           3 :                 if (tm1) {
     153           3 :                         t2 = mktime(tm1);
     154           3 :                         tz_offset = t2 - t1;
     155             :                 } else
     156           0 :                         tz_offset = 0;
     157             :         } else
     158           0 :                 tz_offset = 0;
     159             : 
     160           3 :         *t = (os_time_t) t_local - tz_offset;
     161           3 :         return 0;
     162             : }
     163             : 
     164             : 
     165           6 : int os_gmtime(os_time_t t, struct os_tm *tm)
     166             : {
     167             :         struct tm *tm2;
     168           6 :         time_t t2 = t;
     169             : 
     170           6 :         tm2 = gmtime(&t2);
     171           6 :         if (tm2 == NULL)
     172           0 :                 return -1;
     173           6 :         tm->sec = tm2->tm_sec;
     174           6 :         tm->min = tm2->tm_min;
     175           6 :         tm->hour = tm2->tm_hour;
     176           6 :         tm->day = tm2->tm_mday;
     177           6 :         tm->month = tm2->tm_mon + 1;
     178           6 :         tm->year = tm2->tm_year + 1900;
     179           6 :         return 0;
     180             : }
     181             : 
     182             : 
     183             : #ifdef __APPLE__
     184             : #include <fcntl.h>
     185             : static int os_daemon(int nochdir, int noclose)
     186             : {
     187             :         int devnull;
     188             : 
     189             :         if (chdir("/") < 0)
     190             :                 return -1;
     191             : 
     192             :         devnull = open("/dev/null", O_RDWR);
     193             :         if (devnull < 0)
     194             :                 return -1;
     195             : 
     196             :         if (dup2(devnull, STDIN_FILENO) < 0) {
     197             :                 close(devnull);
     198             :                 return -1;
     199             :         }
     200             : 
     201             :         if (dup2(devnull, STDOUT_FILENO) < 0) {
     202             :                 close(devnull);
     203             :                 return -1;
     204             :         }
     205             : 
     206             :         if (dup2(devnull, STDERR_FILENO) < 0) {
     207             :                 close(devnull);
     208             :                 return -1;
     209             :         }
     210             : 
     211             :         return 0;
     212             : }
     213             : #else /* __APPLE__ */
     214             : #define os_daemon daemon
     215             : #endif /* __APPLE__ */
     216             : 
     217             : 
     218           8 : int os_daemonize(const char *pid_file)
     219             : {
     220             : #if defined(__uClinux__) || defined(__sun__)
     221             :         return -1;
     222             : #else /* defined(__uClinux__) || defined(__sun__) */
     223           8 :         if (os_daemon(0, 0)) {
     224           0 :                 perror("daemon");
     225           0 :                 return -1;
     226             :         }
     227             : 
     228           8 :         if (pid_file) {
     229           8 :                 FILE *f = fopen(pid_file, "w");
     230           8 :                 if (f) {
     231           8 :                         fprintf(f, "%u\n", getpid());
     232           8 :                         fclose(f);
     233             :                 }
     234             :         }
     235             : 
     236           8 :         return -0;
     237             : #endif /* defined(__uClinux__) || defined(__sun__) */
     238             : }
     239             : 
     240             : 
     241          38 : void os_daemonize_terminate(const char *pid_file)
     242             : {
     243          38 :         if (pid_file)
     244          26 :                 unlink(pid_file);
     245          38 : }
     246             : 
     247             : 
     248       28453 : int os_get_random(unsigned char *buf, size_t len)
     249             : {
     250             :         FILE *f;
     251             :         size_t rc;
     252             : 
     253       28453 :         if (TEST_FAIL())
     254          19 :                 return -1;
     255             : 
     256       28434 :         f = fopen("/dev/urandom", "rb");
     257       28434 :         if (f == NULL) {
     258           0 :                 printf("Could not open /dev/urandom.\n");
     259           0 :                 return -1;
     260             :         }
     261             : 
     262       28434 :         rc = fread(buf, 1, len, f);
     263       28434 :         fclose(f);
     264             : 
     265       28434 :         return rc != len ? -1 : 0;
     266             : }
     267             : 
     268             : 
     269        5179 : unsigned long os_random(void)
     270             : {
     271        5179 :         return random();
     272             : }
     273             : 
     274             : 
     275         121 : char * os_rel2abs_path(const char *rel_path)
     276             : {
     277         121 :         char *buf = NULL, *cwd, *ret;
     278         121 :         size_t len = 128, cwd_len, rel_len, ret_len;
     279             :         int last_errno;
     280             : 
     281         121 :         if (!rel_path)
     282          34 :                 return NULL;
     283             : 
     284          87 :         if (rel_path[0] == '/')
     285          69 :                 return os_strdup(rel_path);
     286             : 
     287             :         for (;;) {
     288          18 :                 buf = os_malloc(len);
     289          18 :                 if (buf == NULL)
     290           0 :                         return NULL;
     291          18 :                 cwd = getcwd(buf, len);
     292          18 :                 if (cwd == NULL) {
     293           0 :                         last_errno = errno;
     294           0 :                         os_free(buf);
     295           0 :                         if (last_errno != ERANGE)
     296           0 :                                 return NULL;
     297           0 :                         len *= 2;
     298           0 :                         if (len > 2000)
     299           0 :                                 return NULL;
     300             :                 } else {
     301          18 :                         buf[len - 1] = '\0';
     302          18 :                         break;
     303             :                 }
     304           0 :         }
     305             : 
     306          18 :         cwd_len = os_strlen(cwd);
     307          18 :         rel_len = os_strlen(rel_path);
     308          18 :         ret_len = cwd_len + 1 + rel_len + 1;
     309          18 :         ret = os_malloc(ret_len);
     310          18 :         if (ret) {
     311          18 :                 os_memcpy(ret, cwd, cwd_len);
     312          18 :                 ret[cwd_len] = '/';
     313          18 :                 os_memcpy(ret + cwd_len + 1, rel_path, rel_len);
     314          18 :                 ret[ret_len - 1] = '\0';
     315             :         }
     316          18 :         os_free(buf);
     317          18 :         return ret;
     318             : }
     319             : 
     320             : 
     321         207 : int os_program_init(void)
     322             : {
     323             : #ifdef ANDROID
     324             :         /*
     325             :          * We ignore errors here since errors are normal if we
     326             :          * are already running as non-root.
     327             :          */
     328             : #ifdef ANDROID_SETGROUPS_OVERRIDE
     329             :         gid_t groups[] = { ANDROID_SETGROUPS_OVERRIDE };
     330             : #else /* ANDROID_SETGROUPS_OVERRIDE */
     331             :         gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE };
     332             : #endif /* ANDROID_SETGROUPS_OVERRIDE */
     333             :         struct __user_cap_header_struct header;
     334             :         struct __user_cap_data_struct cap;
     335             : 
     336             :         setgroups(ARRAY_SIZE(groups), groups);
     337             : 
     338             :         prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
     339             : 
     340             :         setgid(AID_WIFI);
     341             :         setuid(AID_WIFI);
     342             : 
     343             :         header.version = _LINUX_CAPABILITY_VERSION;
     344             :         header.pid = 0;
     345             :         cap.effective = cap.permitted =
     346             :                 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
     347             :         cap.inheritable = 0;
     348             :         capset(&header, &cap);
     349             : #endif /* ANDROID */
     350             : 
     351         207 :         return 0;
     352             : }
     353             : 
     354             : 
     355         129 : void os_program_deinit(void)
     356             : {
     357             : #ifdef WPA_TRACE
     358             :         struct os_alloc_trace *a;
     359         129 :         unsigned long total = 0;
     360         129 :         dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) {
     361           0 :                 total += a->len;
     362           0 :                 if (a->magic != ALLOC_MAGIC) {
     363           0 :                         wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x "
     364             :                                    "len %lu",
     365             :                                    a, a->magic, (unsigned long) a->len);
     366           0 :                         continue;
     367             :                 }
     368           0 :                 wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu",
     369             :                            a, (unsigned long) a->len);
     370           0 :                 wpa_trace_dump("memleak", a);
     371             :         }
     372         129 :         if (total)
     373           0 :                 wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes",
     374             :                            (unsigned long) total);
     375             : #endif /* WPA_TRACE */
     376         129 : }
     377             : 
     378             : 
     379           2 : int os_setenv(const char *name, const char *value, int overwrite)
     380             : {
     381           2 :         return setenv(name, value, overwrite);
     382             : }
     383             : 
     384             : 
     385           1 : int os_unsetenv(const char *name)
     386             : {
     387             : #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
     388             :     defined(__OpenBSD__)
     389             :         unsetenv(name);
     390             :         return 0;
     391             : #else
     392           1 :         return unsetenv(name);
     393             : #endif
     394             : }
     395             : 
     396             : 
     397          24 : char * os_readfile(const char *name, size_t *len)
     398             : {
     399             :         FILE *f;
     400             :         char *buf;
     401             :         long pos;
     402             : 
     403          24 :         f = fopen(name, "rb");
     404          24 :         if (f == NULL)
     405           3 :                 return NULL;
     406             : 
     407          21 :         if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) {
     408           0 :                 fclose(f);
     409           0 :                 return NULL;
     410             :         }
     411          21 :         *len = pos;
     412          21 :         if (fseek(f, 0, SEEK_SET) < 0) {
     413           0 :                 fclose(f);
     414           0 :                 return NULL;
     415             :         }
     416             : 
     417          21 :         buf = os_malloc(*len);
     418          21 :         if (buf == NULL) {
     419           0 :                 fclose(f);
     420           0 :                 return NULL;
     421             :         }
     422             : 
     423          21 :         if (fread(buf, 1, *len, f) != *len) {
     424           0 :                 fclose(f);
     425           0 :                 os_free(buf);
     426           0 :                 return NULL;
     427             :         }
     428             : 
     429          21 :         fclose(f);
     430             : 
     431          21 :         return buf;
     432             : }
     433             : 
     434             : 
     435           1 : int os_file_exists(const char *fname)
     436             : {
     437           1 :         FILE *f = fopen(fname, "rb");
     438           1 :         if (f == NULL)
     439           1 :                 return 0;
     440           0 :         fclose(f);
     441           0 :         return 1;
     442             : }
     443             : 
     444             : 
     445           5 : int os_fdatasync(FILE *stream)
     446             : {
     447           5 :         if (!fflush(stream)) {
     448             : #ifndef __MACH__
     449           5 :                 return fdatasync(fileno(stream));
     450             : #else /* __MACH__ */
     451             : #ifdef F_FULLFSYNC
     452             :                 /* OS X does not implement fdatasync(). */
     453             :                 return fcntl(fileno(stream), F_FULLFSYNC);
     454             : #else /* F_FULLFSYNC */
     455             : #error Neither fdatasync nor F_FULLSYNC are defined
     456             : #endif /* F_FULLFSYNC */
     457             : #endif /* __MACH__ */
     458             :         }
     459             : 
     460           0 :         return -1;
     461             : }
     462             : 
     463             : 
     464             : #ifndef WPA_TRACE
     465             : void * os_zalloc(size_t size)
     466             : {
     467             :         return calloc(1, size);
     468             : }
     469             : #endif /* WPA_TRACE */
     470             : 
     471             : 
     472      166202 : size_t os_strlcpy(char *dest, const char *src, size_t siz)
     473             : {
     474      166202 :         const char *s = src;
     475      166202 :         size_t left = siz;
     476             : 
     477      166202 :         if (left) {
     478             :                 /* Copy string up to the maximum size of the dest buffer */
     479     1145311 :                 while (--left != 0) {
     480      977107 :                         if ((*dest++ = *s++) == '\0')
     481      164200 :                                 break;
     482             :                 }
     483             :         }
     484             : 
     485      166202 :         if (left == 0) {
     486             :                 /* Not enough room for the string; force NUL-termination */
     487        2002 :                 if (siz != 0)
     488        2002 :                         *dest = '\0';
     489        2002 :                 while (*s++)
     490             :                         ; /* determine total src string length */
     491             :         }
     492             : 
     493      166202 :         return s - src - 1;
     494             : }
     495             : 
     496             : 
     497       27179 : int os_memcmp_const(const void *a, const void *b, size_t len)
     498             : {
     499       27179 :         const u8 *aa = a;
     500       27179 :         const u8 *bb = b;
     501             :         size_t i;
     502             :         u8 res;
     503             : 
     504      454662 :         for (res = 0, i = 0; i < len; i++)
     505      427483 :                 res |= aa[i] ^ bb[i];
     506             : 
     507       27179 :         return res;
     508             : }
     509             : 
     510             : 
     511             : #ifdef WPA_TRACE
     512             : 
     513             : #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
     514             : char wpa_trace_fail_func[256] = { 0 };
     515             : unsigned int wpa_trace_fail_after;
     516             : 
     517     3589565 : static int testing_fail_alloc(void)
     518             : {
     519             :         const char *func[WPA_TRACE_LEN];
     520             :         size_t i, res, len;
     521             :         char *pos, *next;
     522             :         int match;
     523             : 
     524     3589565 :         if (!wpa_trace_fail_after)
     525     3512535 :                 return 0;
     526             : 
     527       77030 :         res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
     528       77030 :         i = 0;
     529       77030 :         if (i < res && os_strcmp(func[i], __func__) == 0)
     530       77030 :                 i++;
     531       77030 :         if (i < res && os_strcmp(func[i], "os_malloc") == 0)
     532       77030 :                 i++;
     533       77030 :         if (i < res && os_strcmp(func[i], "os_zalloc") == 0)
     534       21926 :                 i++;
     535       77030 :         if (i < res && os_strcmp(func[i], "os_calloc") == 0)
     536        2291 :                 i++;
     537       77030 :         if (i < res && os_strcmp(func[i], "os_realloc") == 0)
     538        7285 :                 i++;
     539       77030 :         if (i < res && os_strcmp(func[i], "os_realloc_array") == 0)
     540        7100 :                 i++;
     541       77030 :         if (i < res && os_strcmp(func[i], "os_strdup") == 0)
     542        7756 :                 i++;
     543             : 
     544       77030 :         pos = wpa_trace_fail_func;
     545             : 
     546       77030 :         match = 0;
     547      876459 :         while (i < res) {
     548      751432 :                 int allow_skip = 1;
     549      751432 :                 int maybe = 0;
     550             : 
     551      751432 :                 if (*pos == '=') {
     552        1996 :                         allow_skip = 0;
     553        1996 :                         pos++;
     554      749436 :                 } else if (*pos == '?') {
     555           6 :                         maybe = 1;
     556           6 :                         pos++;
     557             :                 }
     558      751432 :                 next = os_strchr(pos, ';');
     559      751432 :                 if (next)
     560       49758 :                         len = next - pos;
     561             :                 else
     562      701674 :                         len = os_strlen(pos);
     563      751432 :                 if (os_memcmp(pos, func[i], len) != 0) {
     564      722801 :                         if (maybe && next) {
     565           0 :                                 pos = next + 1;
     566           0 :                                 continue;
     567             :                         }
     568      722801 :                         if (allow_skip) {
     569      720891 :                                 i++;
     570      720891 :                                 continue;
     571             :                         }
     572        1910 :                         return 0;
     573             :                 }
     574       28631 :                 if (!next) {
     575       27123 :                         match = 1;
     576       27123 :                         break;
     577             :                 }
     578        1508 :                 pos = next + 1;
     579        1508 :                 i++;
     580             :         }
     581       75120 :         if (!match)
     582       47997 :                 return 0;
     583             : 
     584       27123 :         wpa_trace_fail_after--;
     585       27123 :         if (wpa_trace_fail_after == 0) {
     586         852 :                 wpa_printf(MSG_INFO, "TESTING: fail allocation at %s",
     587             :                            wpa_trace_fail_func);
     588       11550 :                 for (i = 0; i < res; i++)
     589       10698 :                         wpa_printf(MSG_INFO, "backtrace[%d] = %s",
     590             :                                    (int) i, func[i]);
     591         852 :                 return 1;
     592             :         }
     593             : 
     594       26271 :         return 0;
     595             : }
     596             : 
     597             : 
     598             : char wpa_trace_test_fail_func[256] = { 0 };
     599             : unsigned int wpa_trace_test_fail_after;
     600             : 
     601       33247 : int testing_test_fail(void)
     602             : {
     603             :         const char *func[WPA_TRACE_LEN];
     604             :         size_t i, res, len;
     605             :         char *pos, *next;
     606             :         int match;
     607             : 
     608       33247 :         if (!wpa_trace_test_fail_after)
     609       33145 :                 return 0;
     610             : 
     611         102 :         res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
     612         102 :         i = 0;
     613         102 :         if (i < res && os_strcmp(func[i], __func__) == 0)
     614         102 :                 i++;
     615             : 
     616         102 :         pos = wpa_trace_test_fail_func;
     617             : 
     618         102 :         match = 0;
     619        1232 :         while (i < res) {
     620        1050 :                 int allow_skip = 1;
     621        1050 :                 int maybe = 0;
     622             : 
     623        1050 :                 if (*pos == '=') {
     624           0 :                         allow_skip = 0;
     625           0 :                         pos++;
     626        1050 :                 } else if (*pos == '?') {
     627           0 :                         maybe = 1;
     628           0 :                         pos++;
     629             :                 }
     630        1050 :                 next = os_strchr(pos, ';');
     631        1050 :                 if (next)
     632         225 :                         len = next - pos;
     633             :                 else
     634         825 :                         len = os_strlen(pos);
     635        1050 :                 if (os_memcmp(pos, func[i], len) != 0) {
     636         936 :                         if (maybe && next) {
     637           0 :                                 pos = next + 1;
     638           0 :                                 continue;
     639             :                         }
     640         936 :                         if (allow_skip) {
     641         936 :                                 i++;
     642         936 :                                 continue;
     643             :                         }
     644           0 :                         return 0;
     645             :                 }
     646         114 :                 if (!next) {
     647          22 :                         match = 1;
     648          22 :                         break;
     649             :                 }
     650          92 :                 pos = next + 1;
     651          92 :                 i++;
     652             :         }
     653         102 :         if (!match)
     654          80 :                 return 0;
     655             : 
     656          22 :         wpa_trace_test_fail_after--;
     657          22 :         if (wpa_trace_test_fail_after == 0) {
     658          21 :                 wpa_printf(MSG_INFO, "TESTING: fail at %s",
     659             :                            wpa_trace_test_fail_func);
     660         301 :                 for (i = 0; i < res; i++)
     661         280 :                         wpa_printf(MSG_INFO, "backtrace[%d] = %s",
     662             :                                    (int) i, func[i]);
     663          21 :                 return 1;
     664             :         }
     665             : 
     666           1 :         return 0;
     667             : }
     668             : 
     669             : #else
     670             : 
     671             : static inline int testing_fail_alloc(void)
     672             : {
     673             :         return 0;
     674             : }
     675             : #endif
     676             : 
     677     3589565 : void * os_malloc(size_t size)
     678             : {
     679             :         struct os_alloc_trace *a;
     680             : 
     681     3589565 :         if (testing_fail_alloc())
     682         852 :                 return NULL;
     683             : 
     684     3588713 :         a = malloc(sizeof(*a) + size);
     685     3588713 :         if (a == NULL)
     686           0 :                 return NULL;
     687     3588713 :         a->magic = ALLOC_MAGIC;
     688     3588713 :         dl_list_add(&alloc_list, &a->list);
     689     3588713 :         a->len = size;
     690     3588713 :         wpa_trace_record(a);
     691     3588713 :         return a + 1;
     692             : }
     693             : 
     694             : 
     695      650034 : void * os_realloc(void *ptr, size_t size)
     696             : {
     697             :         struct os_alloc_trace *a;
     698             :         size_t copy_len;
     699             :         void *n;
     700             : 
     701      650034 :         if (ptr == NULL)
     702       63368 :                 return os_malloc(size);
     703             : 
     704      586666 :         a = (struct os_alloc_trace *) ptr - 1;
     705      586666 :         if (a->magic != ALLOC_MAGIC) {
     706           0 :                 wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s",
     707             :                            a, a->magic,
     708           0 :                            a->magic == FREED_MAGIC ? " (already freed)" : "");
     709           0 :                 wpa_trace_show("Invalid os_realloc() call");
     710           0 :                 abort();
     711             :         }
     712      586666 :         n = os_malloc(size);
     713      586666 :         if (n == NULL)
     714          24 :                 return NULL;
     715      586642 :         copy_len = a->len;
     716      586642 :         if (copy_len > size)
     717        2771 :                 copy_len = size;
     718      586642 :         os_memcpy(n, a + 1, copy_len);
     719      586642 :         os_free(ptr);
     720      586642 :         return n;
     721             : }
     722             : 
     723             : 
     724     4326908 : void os_free(void *ptr)
     725             : {
     726             :         struct os_alloc_trace *a;
     727             : 
     728     4326908 :         if (ptr == NULL)
     729     5065115 :                 return;
     730     3588701 :         a = (struct os_alloc_trace *) ptr - 1;
     731     3588701 :         if (a->magic != ALLOC_MAGIC) {
     732           0 :                 wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s",
     733             :                            a, a->magic,
     734           0 :                            a->magic == FREED_MAGIC ? " (already freed)" : "");
     735           0 :                 wpa_trace_show("Invalid os_free() call");
     736           0 :                 abort();
     737             :         }
     738     3588701 :         dl_list_del(&a->list);
     739     3588701 :         a->magic = FREED_MAGIC;
     740             : 
     741     3588701 :         wpa_trace_check_ref(ptr);
     742     3588701 :         free(a);
     743             : }
     744             : 
     745             : 
     746      700584 : void * os_zalloc(size_t size)
     747             : {
     748      700584 :         void *ptr = os_malloc(size);
     749      700584 :         if (ptr)
     750      700206 :                 os_memset(ptr, 0, size);
     751      700584 :         return ptr;
     752             : }
     753             : 
     754             : 
     755      249725 : char * os_strdup(const char *s)
     756             : {
     757             :         size_t len;
     758             :         char *d;
     759      249725 :         len = os_strlen(s);
     760      249725 :         d = os_malloc(len + 1);
     761      249725 :         if (d == NULL)
     762          68 :                 return NULL;
     763      249657 :         os_memcpy(d, s, len);
     764      249657 :         d[len] = '\0';
     765      249657 :         return d;
     766             : }
     767             : 
     768             : #endif /* WPA_TRACE */
     769             : 
     770             : 
     771           1 : int os_exec(const char *program, const char *arg, int wait_completion)
     772             : {
     773             :         pid_t pid;
     774             :         int pid_status;
     775             : 
     776           1 :         pid = fork();
     777           1 :         if (pid < 0) {
     778           0 :                 perror("fork");
     779           0 :                 return -1;
     780             :         }
     781             : 
     782           1 :         if (pid == 0) {
     783             :                 /* run the external command in the child process */
     784           0 :                 const int MAX_ARG = 30;
     785             :                 char *_program, *_arg, *pos;
     786           0 :                 char *argv[MAX_ARG + 1];
     787             :                 int i;
     788             : 
     789           0 :                 _program = os_strdup(program);
     790           0 :                 _arg = os_strdup(arg);
     791             : 
     792           0 :                 argv[0] = _program;
     793             : 
     794           0 :                 i = 1;
     795           0 :                 pos = _arg;
     796           0 :                 while (i < MAX_ARG && pos && *pos) {
     797           0 :                         while (*pos == ' ')
     798           0 :                                 pos++;
     799           0 :                         if (*pos == '\0')
     800           0 :                                 break;
     801           0 :                         argv[i++] = pos;
     802           0 :                         pos = os_strchr(pos, ' ');
     803           0 :                         if (pos)
     804           0 :                                 *pos++ = '\0';
     805             :                 }
     806           0 :                 argv[i] = NULL;
     807             : 
     808           0 :                 execv(program, argv);
     809           0 :                 perror("execv");
     810           0 :                 os_free(_program);
     811           0 :                 os_free(_arg);
     812           0 :                 exit(0);
     813             :                 return -1;
     814             :         }
     815             : 
     816           1 :         if (wait_completion) {
     817             :                 /* wait for the child process to complete in the parent */
     818           1 :                 waitpid(pid, &pid_status, 0);
     819             :         }
     820             : 
     821           1 :         return 0;
     822             : }

Generated by: LCOV version 1.10