18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * OS specific functions for UNIX/POSIX systems 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include <time.h> 12772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen#include <sys/wait.h> 131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 15a562b19dfc52d80b60d485c5661f36d9d6b40911Nick Kralevich#include <sys/capability.h> 160f4fce149db4f45a9eb6776186c1858f8083e6f4Elliott Hughes#include <sys/prctl.h> 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <private/android_filesystem_config.h> 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "os.h" 2168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt#include "common.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_debug.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "trace.h" 271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "list.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 297f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidtstatic struct dl_list alloc_list = DL_LIST_HEAD_INIT(alloc_list); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define ALLOC_MAGIC 0xa84ef1b2 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define FREED_MAGIC 0x67fd487a 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct os_alloc_trace { 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int magic; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct dl_list list; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_TRACE_INFO 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid os_sleep(os_time_t sec, os_time_t usec) 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sec) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sleep(sec); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (usec) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usleep(usec); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_get_time(struct os_time *t) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct timeval tv; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gettimeofday(&tv, NULL); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t->sec = tv.tv_sec; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t->usec = tv.tv_usec; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidtint os_get_reltime(struct os_reltime *t) 65fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt{ 66fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#if defined(CLOCK_BOOTTIME) 67fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt static clockid_t clock_id = CLOCK_BOOTTIME; 68fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#elif defined(CLOCK_MONOTONIC) 69fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt static clockid_t clock_id = CLOCK_MONOTONIC; 70fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#else 71fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt static clockid_t clock_id = CLOCK_REALTIME; 72fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif 73fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt struct timespec ts; 74fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt int res; 75fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 76fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt while (1) { 77fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt res = clock_gettime(clock_id, &ts); 78fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt if (res == 0) { 79fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt t->sec = ts.tv_sec; 80fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt t->usec = ts.tv_nsec / 1000; 81fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return 0; 82fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 83fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt switch (clock_id) { 84fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifdef CLOCK_BOOTTIME 85fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt case CLOCK_BOOTTIME: 86fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt clock_id = CLOCK_MONOTONIC; 87fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt break; 88fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif 89fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#ifdef CLOCK_MONOTONIC 90fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt case CLOCK_MONOTONIC: 91fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt clock_id = CLOCK_REALTIME; 92fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt break; 93fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif 94fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt case CLOCK_REALTIME: 95fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return -1; 96fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 97fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 98fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt} 99fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 100fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_mktime(int year, int month, int day, int hour, int min, int sec, 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_t *t) 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tm tm, *tm1; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt time_t t_local, t1, t2; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_t tz_offset; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec > 60) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&tm, 0, sizeof(tm)); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm.tm_year = year - 1900; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm.tm_mon = month - 1; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm.tm_mday = day; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm.tm_hour = hour; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm.tm_min = min; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm.tm_sec = sec; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t_local = mktime(&tm); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* figure out offset to UTC */ 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm1 = localtime(&t_local); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tm1) { 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t1 = mktime(tm1); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tm1 = gmtime(&t_local); 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tm1) { 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t2 = mktime(tm1); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tz_offset = t2 - t1; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tz_offset = 0; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tz_offset = 0; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *t = (os_time_t) t_local - tz_offset; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint os_gmtime(os_time_t t, struct os_tm *tm) 1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 1431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct tm *tm2; 1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt time_t t2 = t; 1451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm2 = gmtime(&t2); 1471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tm2 == NULL) 1481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm->sec = tm2->tm_sec; 1501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm->min = tm2->tm_min; 1511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm->hour = tm2->tm_hour; 1521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm->day = tm2->tm_mday; 1531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm->month = tm2->tm_mon + 1; 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tm->year = tm2->tm_year + 1900; 1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __APPLE__ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <fcntl.h> 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int os_daemon(int nochdir, int noclose) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int devnull; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (chdir("/") < 0) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devnull = open("/dev/null", O_RDWR); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (devnull < 0) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dup2(devnull, STDIN_FILENO) < 0) { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(devnull); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dup2(devnull, STDOUT_FILENO) < 0) { 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(devnull); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dup2(devnull, STDERR_FILENO) < 0) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(devnull); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* __APPLE__ */ 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define os_daemon daemon 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __APPLE__ */ 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_daemonize(const char *pid_file) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(__uClinux__) || defined(__sun__) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* defined(__uClinux__) || defined(__sun__) */ 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_daemon(0, 0)) { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("daemon"); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pid_file) { 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f = fopen(pid_file, "w"); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f) { 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(f, "%u\n", getpid()); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -0; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* defined(__uClinux__) || defined(__sun__) */ 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid os_daemonize_terminate(const char *pid_file) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pid_file) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(pid_file); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_get_random(unsigned char *buf, size_t len) 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rc; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen("/dev/urandom", "rb"); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) { 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not open /dev/urandom.\n"); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc = fread(buf, 1, len, f); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return rc != len ? -1 : 0; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned long os_random(void) 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return random(); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * os_rel2abs_path(const char *rel_path) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf = NULL, *cwd, *ret; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = 128, cwd_len, rel_len, ret_len; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int last_errno; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25464f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt if (!rel_path) 25564f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt return NULL; 25664f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rel_path[0] == '/') 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strdup(rel_path); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cwd = getcwd(buf, len); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cwd == NULL) { 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last_errno = errno; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last_errno != ERANGE) 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len *= 2; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > 2000) 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[len - 1] = '\0'; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cwd_len = os_strlen(cwd); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rel_len = os_strlen(rel_path); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret_len = cwd_len + 1 + rel_len + 1; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_malloc(ret_len); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ret, cwd, cwd_len); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret[cwd_len] = '/'; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret[ret_len - 1] = '\0'; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_program_init(void) 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef ANDROID 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * We ignore errors here since errors are normal if we 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are already running as non-root. 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 301f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef ANDROID_SETGROUPS_OVERRIDE 302f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt gid_t groups[] = { ANDROID_SETGROUPS_OVERRIDE }; 303f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#else /* ANDROID_SETGROUPS_OVERRIDE */ 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE }; 305f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* ANDROID_SETGROUPS_OVERRIDE */ 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct __user_cap_header_struct header; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct __user_cap_data_struct cap; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt setgroups(ARRAY_SIZE(groups), groups); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt setgid(AID_WIFI); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt setuid(AID_WIFI); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt header.version = _LINUX_CAPABILITY_VERSION; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt header.pid = 0; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cap.effective = cap.permitted = 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cap.inheritable = 0; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capset(&header, &cap); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* ANDROID */ 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid os_program_deinit(void) 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_alloc_trace *a; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long total = 0; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt total += a->len; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->magic != ALLOC_MAGIC) { 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x " 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len %lu", 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a, a->magic, (unsigned long) a->len); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu", 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a, (unsigned long) a->len); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_dump("memleak", a); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (total) 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes", 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) total); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_setenv(const char *name, const char *value, int overwrite) 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return setenv(name, value, overwrite); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint os_unsetenv(const char *name) 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \ 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt defined(__OpenBSD__) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsetenv(name); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return unsetenv(name); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * os_readfile(const char *name, size_t *len) 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt long pos; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(name, "rb"); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) { 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = pos; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fseek(f, 0, SEEK_SET) < 0) { 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(*len); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fread(buf, 1, *len, f) != *len) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtint os_file_exists(const char *fname) 409d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 410d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt FILE *f = fopen(fname, "rb"); 411d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (f == NULL) 412d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 413d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt fclose(f); 414d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 1; 415d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 416d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 417d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 418447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Willsint os_fsync(FILE *stream) 419447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills{ 420447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills if (!fflush(stream)) 421447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills return fsync(fileno(stream)); 422447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills return -1; 423447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills} 424447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills 425447c7ff83da0d89ffa70c378be2a4a58f9b14d3bMitchell Wills 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPA_TRACE 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * os_zalloc(size_t size) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return calloc(1, size); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsize_t os_strlcpy(char *dest, const char *src, size_t siz) 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *s = src; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left = siz; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left) { 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Copy string up to the maximum size of the dest buffer */ 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (--left != 0) { 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((*dest++ = *s++) == '\0') 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left == 0) { 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Not enough room for the string; force NUL-termination */ 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (siz != 0) 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dest = '\0'; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*s++) 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; /* determine total src string length */ 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return s - src - 1; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 459c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtint os_memcmp_const(const void *a, const void *b, size_t len) 460c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{ 461c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt const u8 *aa = a; 462c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt const u8 *bb = b; 463c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt size_t i; 464c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt u8 res; 465c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 466c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt for (res = 0, i = 0; i < len; i++) 467c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt res |= aa[i] ^ bb[i]; 468c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 469c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt return res; 470c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt} 471c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 472c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 475ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) 476ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtchar wpa_trace_fail_func[256] = { 0 }; 477ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtunsigned int wpa_trace_fail_after; 478ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 479ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int testing_fail_alloc(void) 480ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 481ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt const char *func[WPA_TRACE_LEN]; 482ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt size_t i, res, len; 483ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt char *pos, *next; 484ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int match; 485ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 486ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!wpa_trace_fail_after) 487ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 488ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 489ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = wpa_trace_calling_func(func, WPA_TRACE_LEN); 490ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i = 0; 491ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], __func__) == 0) 492ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 493ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], "os_malloc") == 0) 494ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 495ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], "os_zalloc") == 0) 496ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 497ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], "os_calloc") == 0) 498ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 499ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], "os_realloc") == 0) 500ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 501ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], "os_realloc_array") == 0) 502ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 503ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < res && os_strcmp(func[i], "os_strdup") == 0) 504ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 505ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 506ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt pos = wpa_trace_fail_func; 507ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 508ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt match = 0; 509ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt while (i < res) { 510ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int allow_skip = 1; 511ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int maybe = 0; 512ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 513ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (*pos == '=') { 514ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt allow_skip = 0; 515ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt pos++; 516ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (*pos == '?') { 517ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt maybe = 1; 518ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt pos++; 519ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 520ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt next = os_strchr(pos, ';'); 521ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (next) 522ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt len = next - pos; 523ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt else 524ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt len = os_strlen(pos); 525ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (os_memcmp(pos, func[i], len) != 0) { 526ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (maybe && next) { 527ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt pos = next + 1; 528ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt continue; 529ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 530ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (allow_skip) { 531ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 532ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt continue; 533ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 534ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 535ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 536ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!next) { 537ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt match = 1; 538ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt break; 539ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 540ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt pos = next + 1; 541ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i++; 542ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 543ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!match) 544ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 545ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 546ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_trace_fail_after--; 547ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (wpa_trace_fail_after == 0) { 548ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "TESTING: fail allocation at %s", 549ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_trace_fail_func); 550ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt for (i = 0; i < res; i++) 551ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "backtrace[%d] = %s", 552ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (int) i, func[i]); 553ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 1; 554ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 555ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 556ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 557ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 558ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 559ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else 560ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 561ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic inline int testing_fail_alloc(void) 562ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 563ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 564ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 565ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif 566ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * os_malloc(size_t size) 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_alloc_trace *a; 570ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 571ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (testing_fail_alloc()) 572ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return NULL; 573ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = malloc(sizeof(*a) + size); 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a == NULL) 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a->magic = ALLOC_MAGIC; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_add(&alloc_list, &a->list); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a->len = size; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_record(a); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return a + 1; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * os_realloc(void *ptr, size_t size) 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_alloc_trace *a; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t copy_len; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *n; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ptr == NULL) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_malloc(size); 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = (struct os_alloc_trace *) ptr - 1; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->magic != ALLOC_MAGIC) { 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s", 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a, a->magic, 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a->magic == FREED_MAGIC ? " (already freed)" : ""); 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_show("Invalid os_realloc() call"); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort(); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n = os_malloc(size); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (n == NULL) 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt copy_len = a->len; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (copy_len > size) 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt copy_len = size; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(n, a + 1, copy_len); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ptr); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return n; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid os_free(void *ptr) 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_alloc_trace *a; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ptr == NULL) 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = (struct os_alloc_trace *) ptr - 1; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a->magic != ALLOC_MAGIC) { 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s", 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a, a->magic, 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a->magic == FREED_MAGIC ? " (already freed)" : ""); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_show("Invalid os_free() call"); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort(); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dl_list_del(&a->list); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a->magic = FREED_MAGIC; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_check_ref(ptr); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(a); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * os_zalloc(size_t size) 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ptr = os_malloc(size); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ptr) 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(ptr, 0, size); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ptr; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * os_strdup(const char *s) 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *d; 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(s); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d = os_malloc(len + 1); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (d == NULL) 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(d, s, len); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt d[len] = '\0'; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return d; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 659772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 660772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 661772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinenint os_exec(const char *program, const char *arg, int wait_completion) 662772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen{ 663772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen pid_t pid; 664772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen int pid_status; 665772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 666772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen pid = fork(); 667772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen if (pid < 0) { 668772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen perror("fork"); 669772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen return -1; 670772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen } 671772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 672772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen if (pid == 0) { 673772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen /* run the external command in the child process */ 674772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen const int MAX_ARG = 30; 675772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen char *_program, *_arg, *pos; 676772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen char *argv[MAX_ARG + 1]; 677772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen int i; 678772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 679772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen _program = os_strdup(program); 680772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen _arg = os_strdup(arg); 681772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 682772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen argv[0] = _program; 683772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 684772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen i = 1; 685772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen pos = _arg; 686772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen while (i < MAX_ARG && pos && *pos) { 687772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen while (*pos == ' ') 688772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen pos++; 689772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen if (*pos == '\0') 690772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen break; 691772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen argv[i++] = pos; 692772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen pos = os_strchr(pos, ' '); 693772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen if (pos) 694772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen *pos++ = '\0'; 695772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen } 696772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen argv[i] = NULL; 697772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 698772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen execv(program, argv); 699772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen perror("execv"); 700772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen os_free(_program); 701772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen os_free(_arg); 702772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen exit(0); 703772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen return -1; 704772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen } 705772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 706772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen if (wait_completion) { 707772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen /* wait for the child process to complete in the parent */ 708772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen waitpid(pid, &pid_status, 0); 709772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen } 710772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen 711772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen return 0; 712772e12cfed81754a9fd890be7bc77bc602a549b5Jouni Malinen} 713