1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * wpa_supplicant/hostapd / Internal implementation of OS specific functions 3e5b75505Sopenharmony_ci * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci * 8e5b75505Sopenharmony_ci * This file is an example of operating system specific wrapper functions. 9e5b75505Sopenharmony_ci * This version implements many of the functions internally, so it can be used 10e5b75505Sopenharmony_ci * to fill in missing functions from the target system C libraries. 11e5b75505Sopenharmony_ci * 12e5b75505Sopenharmony_ci * Some of the functions are using standard C library calls in order to keep 13e5b75505Sopenharmony_ci * this file in working condition to allow the functions to be tested on a 14e5b75505Sopenharmony_ci * Linux target. Please note that OS_NO_C_LIB_DEFINES needs to be defined for 15e5b75505Sopenharmony_ci * this file to work correctly. Note that these implementations are only 16e5b75505Sopenharmony_ci * examples and are not optimized for speed. 17e5b75505Sopenharmony_ci */ 18e5b75505Sopenharmony_ci 19e5b75505Sopenharmony_ci#include "includes.h" 20e5b75505Sopenharmony_ci#include <time.h> 21e5b75505Sopenharmony_ci#include <sys/wait.h> 22e5b75505Sopenharmony_ci 23e5b75505Sopenharmony_ci#undef OS_REJECT_C_LIB_FUNCTIONS 24e5b75505Sopenharmony_ci#include "common.h" 25e5b75505Sopenharmony_ci 26e5b75505Sopenharmony_civoid os_sleep(os_time_t sec, os_time_t usec) 27e5b75505Sopenharmony_ci{ 28e5b75505Sopenharmony_ci if (sec) 29e5b75505Sopenharmony_ci sleep(sec); 30e5b75505Sopenharmony_ci if (usec) 31e5b75505Sopenharmony_ci usleep(usec); 32e5b75505Sopenharmony_ci} 33e5b75505Sopenharmony_ci 34e5b75505Sopenharmony_ci 35e5b75505Sopenharmony_ciint os_get_time(struct os_time *t) 36e5b75505Sopenharmony_ci{ 37e5b75505Sopenharmony_ci int res; 38e5b75505Sopenharmony_ci struct timeval tv; 39e5b75505Sopenharmony_ci res = gettimeofday(&tv, NULL); 40e5b75505Sopenharmony_ci t->sec = tv.tv_sec; 41e5b75505Sopenharmony_ci t->usec = tv.tv_usec; 42e5b75505Sopenharmony_ci return res; 43e5b75505Sopenharmony_ci} 44e5b75505Sopenharmony_ci 45e5b75505Sopenharmony_ci 46e5b75505Sopenharmony_ciint os_get_reltime(struct os_reltime *t) 47e5b75505Sopenharmony_ci{ 48e5b75505Sopenharmony_ci int res; 49e5b75505Sopenharmony_ci struct timeval tv; 50e5b75505Sopenharmony_ci res = gettimeofday(&tv, NULL); 51e5b75505Sopenharmony_ci t->sec = tv.tv_sec; 52e5b75505Sopenharmony_ci t->usec = tv.tv_usec; 53e5b75505Sopenharmony_ci return res; 54e5b75505Sopenharmony_ci} 55e5b75505Sopenharmony_ci 56e5b75505Sopenharmony_ci 57e5b75505Sopenharmony_ciint os_mktime(int year, int month, int day, int hour, int min, int sec, 58e5b75505Sopenharmony_ci os_time_t *t) 59e5b75505Sopenharmony_ci{ 60e5b75505Sopenharmony_ci struct tm tm; 61e5b75505Sopenharmony_ci 62e5b75505Sopenharmony_ci if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || 63e5b75505Sopenharmony_ci hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || 64e5b75505Sopenharmony_ci sec > 60) 65e5b75505Sopenharmony_ci return -1; 66e5b75505Sopenharmony_ci 67e5b75505Sopenharmony_ci os_memset(&tm, 0, sizeof(tm)); 68e5b75505Sopenharmony_ci tm.tm_year = year - 1900; 69e5b75505Sopenharmony_ci tm.tm_mon = month - 1; 70e5b75505Sopenharmony_ci tm.tm_mday = day; 71e5b75505Sopenharmony_ci tm.tm_hour = hour; 72e5b75505Sopenharmony_ci tm.tm_min = min; 73e5b75505Sopenharmony_ci tm.tm_sec = sec; 74e5b75505Sopenharmony_ci 75e5b75505Sopenharmony_ci *t = (os_time_t) mktime(&tm); 76e5b75505Sopenharmony_ci return 0; 77e5b75505Sopenharmony_ci} 78e5b75505Sopenharmony_ci 79e5b75505Sopenharmony_ci 80e5b75505Sopenharmony_ciint os_gmtime(os_time_t t, struct os_tm *tm) 81e5b75505Sopenharmony_ci{ 82e5b75505Sopenharmony_ci struct tm *tm2; 83e5b75505Sopenharmony_ci time_t t2 = t; 84e5b75505Sopenharmony_ci 85e5b75505Sopenharmony_ci tm2 = gmtime(&t2); 86e5b75505Sopenharmony_ci if (tm2 == NULL) 87e5b75505Sopenharmony_ci return -1; 88e5b75505Sopenharmony_ci tm->sec = tm2->tm_sec; 89e5b75505Sopenharmony_ci tm->min = tm2->tm_min; 90e5b75505Sopenharmony_ci tm->hour = tm2->tm_hour; 91e5b75505Sopenharmony_ci tm->day = tm2->tm_mday; 92e5b75505Sopenharmony_ci tm->month = tm2->tm_mon + 1; 93e5b75505Sopenharmony_ci tm->year = tm2->tm_year + 1900; 94e5b75505Sopenharmony_ci return 0; 95e5b75505Sopenharmony_ci} 96e5b75505Sopenharmony_ci 97e5b75505Sopenharmony_ci 98e5b75505Sopenharmony_ciint os_daemonize(const char *pid_file) 99e5b75505Sopenharmony_ci{ 100e5b75505Sopenharmony_ci if (daemon(0, 0)) { 101e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); 102e5b75505Sopenharmony_ci return -1; 103e5b75505Sopenharmony_ci } 104e5b75505Sopenharmony_ci 105e5b75505Sopenharmony_ci if (pid_file) { 106e5b75505Sopenharmony_ci FILE *f = fopen(pid_file, "w"); 107e5b75505Sopenharmony_ci if (f) { 108e5b75505Sopenharmony_ci fprintf(f, "%u\n", getpid()); 109e5b75505Sopenharmony_ci fclose(f); 110e5b75505Sopenharmony_ci } 111e5b75505Sopenharmony_ci } 112e5b75505Sopenharmony_ci 113e5b75505Sopenharmony_ci return -0; 114e5b75505Sopenharmony_ci} 115e5b75505Sopenharmony_ci 116e5b75505Sopenharmony_ci 117e5b75505Sopenharmony_civoid os_daemonize_terminate(const char *pid_file) 118e5b75505Sopenharmony_ci{ 119e5b75505Sopenharmony_ci if (pid_file) 120e5b75505Sopenharmony_ci unlink(pid_file); 121e5b75505Sopenharmony_ci} 122e5b75505Sopenharmony_ci 123e5b75505Sopenharmony_ci 124e5b75505Sopenharmony_ciint os_get_random(unsigned char *buf, size_t len) 125e5b75505Sopenharmony_ci{ 126e5b75505Sopenharmony_ci#if defined(TEST_FUZZ) || defined(CONFIG_TEST_RANDOM) 127e5b75505Sopenharmony_ci size_t i; 128e5b75505Sopenharmony_ci 129e5b75505Sopenharmony_ci for (i = 0; i < len; i++) 130e5b75505Sopenharmony_ci buf[i] = i & 0xff; 131e5b75505Sopenharmony_ci return 0; 132e5b75505Sopenharmony_ci#else /* TEST_FUZZ */ 133e5b75505Sopenharmony_ci FILE *f; 134e5b75505Sopenharmony_ci size_t rc; 135e5b75505Sopenharmony_ci 136e5b75505Sopenharmony_ci f = fopen("/dev/urandom", "rb"); 137e5b75505Sopenharmony_ci if (f == NULL) { 138e5b75505Sopenharmony_ci printf("Could not open /dev/urandom.\n"); 139e5b75505Sopenharmony_ci return -1; 140e5b75505Sopenharmony_ci } 141e5b75505Sopenharmony_ci 142e5b75505Sopenharmony_ci rc = fread(buf, 1, len, f); 143e5b75505Sopenharmony_ci fclose(f); 144e5b75505Sopenharmony_ci 145e5b75505Sopenharmony_ci return rc != len ? -1 : 0; 146e5b75505Sopenharmony_ci#endif 147e5b75505Sopenharmony_ci} 148e5b75505Sopenharmony_ci 149e5b75505Sopenharmony_ci 150e5b75505Sopenharmony_ciunsigned long os_random(void) 151e5b75505Sopenharmony_ci{ 152e5b75505Sopenharmony_ci return random(); 153e5b75505Sopenharmony_ci} 154e5b75505Sopenharmony_ci 155e5b75505Sopenharmony_ci 156e5b75505Sopenharmony_cichar * os_rel2abs_path(const char *rel_path) 157e5b75505Sopenharmony_ci{ 158e5b75505Sopenharmony_ci char *buf = NULL, *cwd, *ret; 159e5b75505Sopenharmony_ci size_t len = 128, cwd_len, rel_len, ret_len; 160e5b75505Sopenharmony_ci 161e5b75505Sopenharmony_ci if (rel_path[0] == '/') 162e5b75505Sopenharmony_ci return os_strdup(rel_path); 163e5b75505Sopenharmony_ci 164e5b75505Sopenharmony_ci for (;;) { 165e5b75505Sopenharmony_ci buf = os_malloc(len); 166e5b75505Sopenharmony_ci if (buf == NULL) 167e5b75505Sopenharmony_ci return NULL; 168e5b75505Sopenharmony_ci cwd = getcwd(buf, len); 169e5b75505Sopenharmony_ci if (cwd == NULL) { 170e5b75505Sopenharmony_ci os_free(buf); 171e5b75505Sopenharmony_ci if (errno != ERANGE) { 172e5b75505Sopenharmony_ci return NULL; 173e5b75505Sopenharmony_ci } 174e5b75505Sopenharmony_ci len *= 2; 175e5b75505Sopenharmony_ci } else { 176e5b75505Sopenharmony_ci break; 177e5b75505Sopenharmony_ci } 178e5b75505Sopenharmony_ci } 179e5b75505Sopenharmony_ci 180e5b75505Sopenharmony_ci cwd_len = os_strlen(cwd); 181e5b75505Sopenharmony_ci rel_len = os_strlen(rel_path); 182e5b75505Sopenharmony_ci ret_len = cwd_len + 1 + rel_len + 1; 183e5b75505Sopenharmony_ci ret = os_malloc(ret_len); 184e5b75505Sopenharmony_ci if (ret) { 185e5b75505Sopenharmony_ci os_memcpy(ret, cwd, cwd_len); 186e5b75505Sopenharmony_ci ret[cwd_len] = '/'; 187e5b75505Sopenharmony_ci os_memcpy(ret + cwd_len + 1, rel_path, rel_len); 188e5b75505Sopenharmony_ci ret[ret_len - 1] = '\0'; 189e5b75505Sopenharmony_ci } 190e5b75505Sopenharmony_ci os_free(buf); 191e5b75505Sopenharmony_ci return ret; 192e5b75505Sopenharmony_ci} 193e5b75505Sopenharmony_ci 194e5b75505Sopenharmony_ci 195e5b75505Sopenharmony_ciint os_program_init(void) 196e5b75505Sopenharmony_ci{ 197e5b75505Sopenharmony_ci return 0; 198e5b75505Sopenharmony_ci} 199e5b75505Sopenharmony_ci 200e5b75505Sopenharmony_ci 201e5b75505Sopenharmony_civoid os_program_deinit(void) 202e5b75505Sopenharmony_ci{ 203e5b75505Sopenharmony_ci} 204e5b75505Sopenharmony_ci 205e5b75505Sopenharmony_ci 206e5b75505Sopenharmony_ciint os_setenv(const char *name, const char *value, int overwrite) 207e5b75505Sopenharmony_ci{ 208e5b75505Sopenharmony_ci return setenv(name, value, overwrite); 209e5b75505Sopenharmony_ci} 210e5b75505Sopenharmony_ci 211e5b75505Sopenharmony_ci 212e5b75505Sopenharmony_ciint os_unsetenv(const char *name) 213e5b75505Sopenharmony_ci{ 214e5b75505Sopenharmony_ci#if defined(__FreeBSD__) || defined(__NetBSD__) 215e5b75505Sopenharmony_ci unsetenv(name); 216e5b75505Sopenharmony_ci return 0; 217e5b75505Sopenharmony_ci#else 218e5b75505Sopenharmony_ci return unsetenv(name); 219e5b75505Sopenharmony_ci#endif 220e5b75505Sopenharmony_ci} 221e5b75505Sopenharmony_ci 222e5b75505Sopenharmony_ci 223e5b75505Sopenharmony_cichar * os_readfile(const char *name, size_t *len) 224e5b75505Sopenharmony_ci{ 225e5b75505Sopenharmony_ci FILE *f; 226e5b75505Sopenharmony_ci char *buf; 227e5b75505Sopenharmony_ci 228e5b75505Sopenharmony_ci f = fopen(name, "rb"); 229e5b75505Sopenharmony_ci if (f == NULL) 230e5b75505Sopenharmony_ci return NULL; 231e5b75505Sopenharmony_ci 232e5b75505Sopenharmony_ci fseek(f, 0, SEEK_END); 233e5b75505Sopenharmony_ci *len = ftell(f); 234e5b75505Sopenharmony_ci fseek(f, 0, SEEK_SET); 235e5b75505Sopenharmony_ci 236e5b75505Sopenharmony_ci buf = os_malloc(*len); 237e5b75505Sopenharmony_ci if (buf == NULL) { 238e5b75505Sopenharmony_ci fclose(f); 239e5b75505Sopenharmony_ci return NULL; 240e5b75505Sopenharmony_ci } 241e5b75505Sopenharmony_ci 242e5b75505Sopenharmony_ci if (fread(buf, 1, *len, f) != *len) { 243e5b75505Sopenharmony_ci fclose(f); 244e5b75505Sopenharmony_ci os_free(buf); 245e5b75505Sopenharmony_ci return NULL; 246e5b75505Sopenharmony_ci } 247e5b75505Sopenharmony_ci 248e5b75505Sopenharmony_ci fclose(f); 249e5b75505Sopenharmony_ci 250e5b75505Sopenharmony_ci return buf; 251e5b75505Sopenharmony_ci} 252e5b75505Sopenharmony_ci 253e5b75505Sopenharmony_ci 254e5b75505Sopenharmony_ciint os_fdatasync(FILE *stream) 255e5b75505Sopenharmony_ci{ 256e5b75505Sopenharmony_ci return 0; 257e5b75505Sopenharmony_ci} 258e5b75505Sopenharmony_ci 259e5b75505Sopenharmony_ci 260e5b75505Sopenharmony_civoid * os_zalloc(size_t size) 261e5b75505Sopenharmony_ci{ 262e5b75505Sopenharmony_ci void *n = os_malloc(size); 263e5b75505Sopenharmony_ci if (n) 264e5b75505Sopenharmony_ci os_memset(n, 0, size); 265e5b75505Sopenharmony_ci return n; 266e5b75505Sopenharmony_ci} 267e5b75505Sopenharmony_ci 268e5b75505Sopenharmony_ci 269e5b75505Sopenharmony_civoid * os_malloc(size_t size) 270e5b75505Sopenharmony_ci{ 271e5b75505Sopenharmony_ci return malloc(size); 272e5b75505Sopenharmony_ci} 273e5b75505Sopenharmony_ci 274e5b75505Sopenharmony_ci 275e5b75505Sopenharmony_civoid * os_realloc(void *ptr, size_t size) 276e5b75505Sopenharmony_ci{ 277e5b75505Sopenharmony_ci return realloc(ptr, size); 278e5b75505Sopenharmony_ci} 279e5b75505Sopenharmony_ci 280e5b75505Sopenharmony_ci 281e5b75505Sopenharmony_civoid os_free(void *ptr) 282e5b75505Sopenharmony_ci{ 283e5b75505Sopenharmony_ci free(ptr); 284e5b75505Sopenharmony_ci} 285e5b75505Sopenharmony_ci 286e5b75505Sopenharmony_ci 287e5b75505Sopenharmony_civoid * os_memcpy(void *dest, const void *src, size_t n) 288e5b75505Sopenharmony_ci{ 289e5b75505Sopenharmony_ci char *d = dest; 290e5b75505Sopenharmony_ci const char *s = src; 291e5b75505Sopenharmony_ci while (n--) 292e5b75505Sopenharmony_ci *d++ = *s++; 293e5b75505Sopenharmony_ci return dest; 294e5b75505Sopenharmony_ci} 295e5b75505Sopenharmony_ci 296e5b75505Sopenharmony_ci 297e5b75505Sopenharmony_civoid * os_memmove(void *dest, const void *src, size_t n) 298e5b75505Sopenharmony_ci{ 299e5b75505Sopenharmony_ci if (dest < src) 300e5b75505Sopenharmony_ci os_memcpy(dest, src, n); 301e5b75505Sopenharmony_ci else { 302e5b75505Sopenharmony_ci /* overlapping areas */ 303e5b75505Sopenharmony_ci char *d = (char *) dest + n; 304e5b75505Sopenharmony_ci const char *s = (const char *) src + n; 305e5b75505Sopenharmony_ci while (n--) 306e5b75505Sopenharmony_ci *--d = *--s; 307e5b75505Sopenharmony_ci } 308e5b75505Sopenharmony_ci return dest; 309e5b75505Sopenharmony_ci} 310e5b75505Sopenharmony_ci 311e5b75505Sopenharmony_ci 312e5b75505Sopenharmony_civoid * os_memset(void *s, int c, size_t n) 313e5b75505Sopenharmony_ci{ 314e5b75505Sopenharmony_ci char *p = s; 315e5b75505Sopenharmony_ci while (n--) 316e5b75505Sopenharmony_ci *p++ = c; 317e5b75505Sopenharmony_ci return s; 318e5b75505Sopenharmony_ci} 319e5b75505Sopenharmony_ci 320e5b75505Sopenharmony_ci 321e5b75505Sopenharmony_ciint os_memcmp(const void *s1, const void *s2, size_t n) 322e5b75505Sopenharmony_ci{ 323e5b75505Sopenharmony_ci const unsigned char *p1 = s1, *p2 = s2; 324e5b75505Sopenharmony_ci 325e5b75505Sopenharmony_ci if (n == 0) 326e5b75505Sopenharmony_ci return 0; 327e5b75505Sopenharmony_ci 328e5b75505Sopenharmony_ci while (*p1 == *p2) { 329e5b75505Sopenharmony_ci p1++; 330e5b75505Sopenharmony_ci p2++; 331e5b75505Sopenharmony_ci n--; 332e5b75505Sopenharmony_ci if (n == 0) 333e5b75505Sopenharmony_ci return 0; 334e5b75505Sopenharmony_ci } 335e5b75505Sopenharmony_ci 336e5b75505Sopenharmony_ci return *p1 - *p2; 337e5b75505Sopenharmony_ci} 338e5b75505Sopenharmony_ci 339e5b75505Sopenharmony_ci 340e5b75505Sopenharmony_cichar * os_strdup(const char *s) 341e5b75505Sopenharmony_ci{ 342e5b75505Sopenharmony_ci char *res; 343e5b75505Sopenharmony_ci size_t len; 344e5b75505Sopenharmony_ci if (s == NULL) 345e5b75505Sopenharmony_ci return NULL; 346e5b75505Sopenharmony_ci len = os_strlen(s); 347e5b75505Sopenharmony_ci res = os_malloc(len + 1); 348e5b75505Sopenharmony_ci if (res) 349e5b75505Sopenharmony_ci os_memcpy(res, s, len + 1); 350e5b75505Sopenharmony_ci return res; 351e5b75505Sopenharmony_ci} 352e5b75505Sopenharmony_ci 353e5b75505Sopenharmony_ci 354e5b75505Sopenharmony_cisize_t os_strlen(const char *s) 355e5b75505Sopenharmony_ci{ 356e5b75505Sopenharmony_ci const char *p = s; 357e5b75505Sopenharmony_ci while (*p) 358e5b75505Sopenharmony_ci p++; 359e5b75505Sopenharmony_ci return p - s; 360e5b75505Sopenharmony_ci} 361e5b75505Sopenharmony_ci 362e5b75505Sopenharmony_ci 363e5b75505Sopenharmony_ciint os_strcasecmp(const char *s1, const char *s2) 364e5b75505Sopenharmony_ci{ 365e5b75505Sopenharmony_ci /* 366e5b75505Sopenharmony_ci * Ignoring case is not required for main functionality, so just use 367e5b75505Sopenharmony_ci * the case sensitive version of the function. 368e5b75505Sopenharmony_ci */ 369e5b75505Sopenharmony_ci return os_strcmp(s1, s2); 370e5b75505Sopenharmony_ci} 371e5b75505Sopenharmony_ci 372e5b75505Sopenharmony_ci 373e5b75505Sopenharmony_ciint os_strncasecmp(const char *s1, const char *s2, size_t n) 374e5b75505Sopenharmony_ci{ 375e5b75505Sopenharmony_ci /* 376e5b75505Sopenharmony_ci * Ignoring case is not required for main functionality, so just use 377e5b75505Sopenharmony_ci * the case sensitive version of the function. 378e5b75505Sopenharmony_ci */ 379e5b75505Sopenharmony_ci return os_strncmp(s1, s2, n); 380e5b75505Sopenharmony_ci} 381e5b75505Sopenharmony_ci 382e5b75505Sopenharmony_ci 383e5b75505Sopenharmony_cichar * os_strchr(const char *s, int c) 384e5b75505Sopenharmony_ci{ 385e5b75505Sopenharmony_ci while (*s) { 386e5b75505Sopenharmony_ci if (*s == c) 387e5b75505Sopenharmony_ci return (char *) s; 388e5b75505Sopenharmony_ci s++; 389e5b75505Sopenharmony_ci } 390e5b75505Sopenharmony_ci return NULL; 391e5b75505Sopenharmony_ci} 392e5b75505Sopenharmony_ci 393e5b75505Sopenharmony_ci 394e5b75505Sopenharmony_cichar * os_strrchr(const char *s, int c) 395e5b75505Sopenharmony_ci{ 396e5b75505Sopenharmony_ci const char *p = s; 397e5b75505Sopenharmony_ci while (*p) 398e5b75505Sopenharmony_ci p++; 399e5b75505Sopenharmony_ci p--; 400e5b75505Sopenharmony_ci while (p >= s) { 401e5b75505Sopenharmony_ci if (*p == c) 402e5b75505Sopenharmony_ci return (char *) p; 403e5b75505Sopenharmony_ci p--; 404e5b75505Sopenharmony_ci } 405e5b75505Sopenharmony_ci return NULL; 406e5b75505Sopenharmony_ci} 407e5b75505Sopenharmony_ci 408e5b75505Sopenharmony_ci 409e5b75505Sopenharmony_ciint os_strcmp(const char *s1, const char *s2) 410e5b75505Sopenharmony_ci{ 411e5b75505Sopenharmony_ci while (*s1 == *s2) { 412e5b75505Sopenharmony_ci if (*s1 == '\0') 413e5b75505Sopenharmony_ci break; 414e5b75505Sopenharmony_ci s1++; 415e5b75505Sopenharmony_ci s2++; 416e5b75505Sopenharmony_ci } 417e5b75505Sopenharmony_ci 418e5b75505Sopenharmony_ci return *s1 - *s2; 419e5b75505Sopenharmony_ci} 420e5b75505Sopenharmony_ci 421e5b75505Sopenharmony_ci 422e5b75505Sopenharmony_ciint os_strncmp(const char *s1, const char *s2, size_t n) 423e5b75505Sopenharmony_ci{ 424e5b75505Sopenharmony_ci if (n == 0) 425e5b75505Sopenharmony_ci return 0; 426e5b75505Sopenharmony_ci 427e5b75505Sopenharmony_ci while (*s1 == *s2) { 428e5b75505Sopenharmony_ci if (*s1 == '\0') 429e5b75505Sopenharmony_ci break; 430e5b75505Sopenharmony_ci s1++; 431e5b75505Sopenharmony_ci s2++; 432e5b75505Sopenharmony_ci n--; 433e5b75505Sopenharmony_ci if (n == 0) 434e5b75505Sopenharmony_ci return 0; 435e5b75505Sopenharmony_ci } 436e5b75505Sopenharmony_ci 437e5b75505Sopenharmony_ci return *s1 - *s2; 438e5b75505Sopenharmony_ci} 439e5b75505Sopenharmony_ci 440e5b75505Sopenharmony_ci 441e5b75505Sopenharmony_cisize_t os_strlcpy(char *dest, const char *src, size_t siz) 442e5b75505Sopenharmony_ci{ 443e5b75505Sopenharmony_ci const char *s = src; 444e5b75505Sopenharmony_ci size_t left = siz; 445e5b75505Sopenharmony_ci 446e5b75505Sopenharmony_ci if (left) { 447e5b75505Sopenharmony_ci /* Copy string up to the maximum size of the dest buffer */ 448e5b75505Sopenharmony_ci while (--left != 0) { 449e5b75505Sopenharmony_ci if ((*dest++ = *s++) == '\0') 450e5b75505Sopenharmony_ci break; 451e5b75505Sopenharmony_ci } 452e5b75505Sopenharmony_ci } 453e5b75505Sopenharmony_ci 454e5b75505Sopenharmony_ci if (left == 0) { 455e5b75505Sopenharmony_ci /* Not enough room for the string; force NUL-termination */ 456e5b75505Sopenharmony_ci if (siz != 0) 457e5b75505Sopenharmony_ci *dest = '\0'; 458e5b75505Sopenharmony_ci while (*s++) 459e5b75505Sopenharmony_ci ; /* determine total src string length */ 460e5b75505Sopenharmony_ci } 461e5b75505Sopenharmony_ci 462e5b75505Sopenharmony_ci return s - src - 1; 463e5b75505Sopenharmony_ci} 464e5b75505Sopenharmony_ci 465e5b75505Sopenharmony_ci 466e5b75505Sopenharmony_ciint os_memcmp_const(const void *a, const void *b, size_t len) 467e5b75505Sopenharmony_ci{ 468e5b75505Sopenharmony_ci const u8 *aa = a; 469e5b75505Sopenharmony_ci const u8 *bb = b; 470e5b75505Sopenharmony_ci size_t i; 471e5b75505Sopenharmony_ci u8 res; 472e5b75505Sopenharmony_ci 473e5b75505Sopenharmony_ci for (res = 0, i = 0; i < len; i++) 474e5b75505Sopenharmony_ci res |= aa[i] ^ bb[i]; 475e5b75505Sopenharmony_ci 476e5b75505Sopenharmony_ci return res; 477e5b75505Sopenharmony_ci} 478e5b75505Sopenharmony_ci 479e5b75505Sopenharmony_ci 480e5b75505Sopenharmony_cichar * os_strstr(const char *haystack, const char *needle) 481e5b75505Sopenharmony_ci{ 482e5b75505Sopenharmony_ci size_t len = os_strlen(needle); 483e5b75505Sopenharmony_ci while (*haystack) { 484e5b75505Sopenharmony_ci if (os_strncmp(haystack, needle, len) == 0) 485e5b75505Sopenharmony_ci return (char *) haystack; 486e5b75505Sopenharmony_ci haystack++; 487e5b75505Sopenharmony_ci } 488e5b75505Sopenharmony_ci 489e5b75505Sopenharmony_ci return NULL; 490e5b75505Sopenharmony_ci} 491e5b75505Sopenharmony_ci 492e5b75505Sopenharmony_ci 493e5b75505Sopenharmony_ciint os_snprintf(char *str, size_t size, const char *format, ...) 494e5b75505Sopenharmony_ci{ 495e5b75505Sopenharmony_ci va_list ap; 496e5b75505Sopenharmony_ci int ret; 497e5b75505Sopenharmony_ci 498e5b75505Sopenharmony_ci /* See http://www.ijs.si/software/snprintf/ for portable 499e5b75505Sopenharmony_ci * implementation of snprintf. 500e5b75505Sopenharmony_ci */ 501e5b75505Sopenharmony_ci 502e5b75505Sopenharmony_ci va_start(ap, format); 503e5b75505Sopenharmony_ci ret = vsnprintf(str, size, format, ap); 504e5b75505Sopenharmony_ci va_end(ap); 505e5b75505Sopenharmony_ci if (size > 0) 506e5b75505Sopenharmony_ci str[size - 1] = '\0'; 507e5b75505Sopenharmony_ci return ret; 508e5b75505Sopenharmony_ci} 509e5b75505Sopenharmony_ci 510e5b75505Sopenharmony_ci 511e5b75505Sopenharmony_ciint os_exec(const char *program, const char *arg, int wait_completion) 512e5b75505Sopenharmony_ci{ 513e5b75505Sopenharmony_ci pid_t pid; 514e5b75505Sopenharmony_ci int pid_status; 515e5b75505Sopenharmony_ci 516e5b75505Sopenharmony_ci pid = fork(); 517e5b75505Sopenharmony_ci if (pid < 0) { 518e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "fork: %s", strerror(errno)); 519e5b75505Sopenharmony_ci return -1; 520e5b75505Sopenharmony_ci } 521e5b75505Sopenharmony_ci 522e5b75505Sopenharmony_ci if (pid == 0) { 523e5b75505Sopenharmony_ci /* run the external command in the child process */ 524e5b75505Sopenharmony_ci const int MAX_ARG = 30; 525e5b75505Sopenharmony_ci char *_program, *_arg, *pos; 526e5b75505Sopenharmony_ci char *argv[MAX_ARG + 1]; 527e5b75505Sopenharmony_ci int i; 528e5b75505Sopenharmony_ci 529e5b75505Sopenharmony_ci _program = os_strdup(program); 530e5b75505Sopenharmony_ci _arg = os_strdup(arg); 531e5b75505Sopenharmony_ci 532e5b75505Sopenharmony_ci argv[0] = _program; 533e5b75505Sopenharmony_ci 534e5b75505Sopenharmony_ci i = 1; 535e5b75505Sopenharmony_ci pos = _arg; 536e5b75505Sopenharmony_ci while (i < MAX_ARG && pos && *pos) { 537e5b75505Sopenharmony_ci while (*pos == ' ') 538e5b75505Sopenharmony_ci pos++; 539e5b75505Sopenharmony_ci if (*pos == '\0') 540e5b75505Sopenharmony_ci break; 541e5b75505Sopenharmony_ci argv[i++] = pos; 542e5b75505Sopenharmony_ci pos = os_strchr(pos, ' '); 543e5b75505Sopenharmony_ci if (pos) 544e5b75505Sopenharmony_ci *pos++ = '\0'; 545e5b75505Sopenharmony_ci } 546e5b75505Sopenharmony_ci argv[i] = NULL; 547e5b75505Sopenharmony_ci 548e5b75505Sopenharmony_ci execv(program, argv); 549e5b75505Sopenharmony_ci wpa_printf(MSG_ERROR, "execv: %s", strerror(errno)); 550e5b75505Sopenharmony_ci os_free(_program); 551e5b75505Sopenharmony_ci os_free(_arg); 552e5b75505Sopenharmony_ci exit(0); 553e5b75505Sopenharmony_ci return -1; 554e5b75505Sopenharmony_ci } 555e5b75505Sopenharmony_ci 556e5b75505Sopenharmony_ci if (wait_completion) { 557e5b75505Sopenharmony_ci /* wait for the child process to complete in the parent */ 558e5b75505Sopenharmony_ci waitpid(pid, &pid_status, 0); 559e5b75505Sopenharmony_ci } 560e5b75505Sopenharmony_ci 561e5b75505Sopenharmony_ci return 0; 562e5b75505Sopenharmony_ci} 563