diff options
Diffstat (limited to 'Radio/HW/BladeRF/common/src/windows')
-rw-r--r-- | Radio/HW/BladeRF/common/src/windows/clock_gettime.c | 58 | ||||
-rw-r--r-- | Radio/HW/BladeRF/common/src/windows/getopt_long.c | 326 | ||||
-rw-r--r-- | Radio/HW/BladeRF/common/src/windows/gettimeofday.c | 49 | ||||
-rw-r--r-- | Radio/HW/BladeRF/common/src/windows/mkdtemp.c | 250 | ||||
-rw-r--r-- | Radio/HW/BladeRF/common/src/windows/nanosleep.c | 41 | ||||
-rw-r--r-- | Radio/HW/BladeRF/common/src/windows/setenv.c | 50 |
6 files changed, 774 insertions, 0 deletions
diff --git a/Radio/HW/BladeRF/common/src/windows/clock_gettime.c b/Radio/HW/BladeRF/common/src/windows/clock_gettime.c new file mode 100644 index 0000000..803799e --- /dev/null +++ b/Radio/HW/BladeRF/common/src/windows/clock_gettime.c @@ -0,0 +1,58 @@ +/* + * This file is part of the bladeRF project: + * http://www.github.com/nuand/bladeRF + * + * Copyright (c) 2013 Nuand LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef WIN32 +# error "This file is intended for use with WIN32 systems only." +#endif + +#include <Windows.h> +#include <errno.h> +#include "clock_gettime.h" +#include "ptw32_timespec.h" + +int clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + BOOL success; + FILETIME file_time; + SYSTEMTIME system_time; + + if (clk_id != CLOCK_REALTIME) { + errno = EINVAL; + return -1; + } + + GetSystemTime(&system_time); + success = SystemTimeToFileTime(&system_time, &file_time); + + if (!success) { + /* For lack of a better or more compliant return value... */ + errno = EINVAL; + return -1; + } + + ptw32_filetime_to_timespec(&file_time, tp); + + return 0; +} + diff --git a/Radio/HW/BladeRF/common/src/windows/getopt_long.c b/Radio/HW/BladeRF/common/src/windows/getopt_long.c new file mode 100644 index 0000000..7a683fb --- /dev/null +++ b/Radio/HW/BladeRF/common/src/windows/getopt_long.c @@ -0,0 +1,326 @@ +/** @file getopt_long.c + ** @brief getopt_long - Definition + ** @author Andrea Vedaldi + **/ + +/* +Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson. +All rights reserved. + +This file is part of the VLFeat library and is made available under +the terms of the BSD license (see legal/licenses/LICENSE.BSD.vlfeat). + +*/ + +/** +@file getopt_long.h +@brief getopt_long +@author Andrea Vedaldi + +This is a drop-in replacament of GNU getopt_long meant to be used +on platforms that do not support such functionality. +**/ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "getopt.h" + +int opterr = 1 ; +int optind = 1 ; +int optopt ; +char * optarg ; +int optreset ; + +#define BADCH '?' +#define BADARG ':' +#define EEND -1 +#define EMSG "" + +/** @brief Parse long options (BSD style) + ** @param argc number of arguments. + ** @param argv pointer to the vector of arguments. + ** @param optstring list of abbreviated options + ** @param longopts list of long options. + ** @param longindex index of current option in @a longopts. + ** @return the code of the next option. + ** + ** This function extract long and short options from the argument + ** list @a argv of @a argc entries. + ** + ** A short options sequence is introduced by a single dash character + ** @c -. Each short option is described by a single character in the + ** string @a optstring, possibly followed by a @c : character to + ** denote a (mandatory) argument of the short option. A short option + ** with an argument cannot appear in the middle of a short option + ** sequence, but only at the end. + ** + ** A long option is introduced by a double dash @c --. Each long + ** option is described by an instance of the ::option structure in + ** the @a longopts table (the last entry must be filled with zeroes + ** to denote the end). + ** + ** Illegal options and missing arguments cause the function to skip + ** the option and return '?'. If ::opterr is @c true (default), the + ** function prints an error message to @a stderr. Finally, if @a + ** optstring has a leading @c :, then error messages are suppressed + ** and a missing argument causes @a : to be returned. + ** + ** @remark The function is currently <em>not</em> thread safe. + **/ + +VL_EXPORT int +getopt_long(int argc, char *const argv[], + const char *optstring, + const struct option * longopts, + int *longindex) +{ + static char *place = EMSG; /* option letter processing */ + static int optbegin = 0 ; + static int optend = 0 ; + const char *oli; /* option letter list index */ + int has_colon = 0 ; + int ret_val = 0 ; + + /* + A semicolon at the beginning of optstring has a special meaning. + If we find one, we annote and remove it. + */ + has_colon = optstring && optstring[0] == ':' ; + if (has_colon) ++ optstring ; + + /* + Here we are either processing a short option sequence or + we start processing a new option. This is indicated by optreset. + */ + + if (optreset || *place == '\0') { + + /* --------------------------------------------------------------- + * Look for next short/long option + * ------------------------------------------------------------ */ + optreset = 0 ; + + /* no more arguments ? */ + if (optind >= argc) { + place = EMSG ; + return -1 ; + } + + /* next argument that may hold an option */ + optbegin = optind ; + + /* --------------------------------------------------------------- + * Look for an option to parse + * ------------------------------------------------------------ */ + + parse_option_at_optbegin : + + /* place points to the candidate option */ + place = argv [optbegin] ; + + /* an option is introduced by '-' */ + if (place [0] != '-') { + /* this argument is not an option: try next argument */ + ++ optbegin ; + if (optbegin >= argc) { + /* no more arguments to look for options */ + place = EMSG ; + return -1 ; + } + goto parse_option_at_optbegin ; + } + + /* consume leading `-' */ + ++ place ; + + /* assume the option is composed of one argument only */ + optend = optbegin + 1 ; + + /* assume no argument */ + optarg = 0 ; + + /* --------------------------------------------------------------- + * option `--' + * ------------------------------------------------------------ */ + + /* this special option (void long option) ends the option processing */ + if (place[0] && + place[0] == '-' && + place[1] == '\0') { + + optind = optend ; + place = EMSG ; + ret_val = -1 ; + goto done_option ; + } + + /* --------------------------------------------------------------- + * long option + * ------------------------------------------------------------ */ + + if (place[0] && + place[0] == '-' && + place[1] ) { + + size_t namelen ; + int i ; + + /* consume second `-' */ + ++ place ; + + /* count characters before `=' */ + namelen = strcspn(place, "=") ; + + /* scan longopts for this option */ + for (i = 0 ; longopts[i].name != NULL ; ++ i) { + + if (strlen ( longopts[i].name) == namelen && + strncmp (place, longopts[i].name, namelen) == 0 ) { + + /* save back long option index */ + if (longindex) *longindex = i ; + + /* process long option argument */ + if (longopts[i].has_arg == required_argument || + longopts[i].has_arg == optional_argument) { + + /* --option=value style */ + if (place[namelen] == '=') { + optarg = place + namelen + 1 ; + } + + /* --option value style (only required_argument) */ + else if (longopts[i].has_arg == required_argument) { + /* missing argument ? */ + if (optbegin >= argc - 1) { + if (! has_colon && opterr) + fprintf(stderr, + "%s: option requires an argument -- %s\n", + argv[0], place); + place = EMSG ; + ret_val = has_colon ? BADARG : BADCH ; + goto done_option ; + } + optarg = argv [optend] ; + ++ optend ; + } + } + + /* determine return value */ + if (longopts[i].flag == NULL) { + ret_val = longopts[i].val ; + } + else { + *longopts[i].flag = longopts[i].val; + ret_val = 0 ; + } + + /* mark sequence closed */ + place = EMSG ; + goto done_option ; + } /* if match */ + + } /* scan longoptions */ + + /* no matching option found */ + if (! has_colon && opterr) + fprintf(stderr, + "%s: illegal option -- %s\n", argv[0], place) ; + place = EMSG ; + ret_val = BADCH ; + goto done_option ; + } + } /* end new option */ + + /* ----------------------------------------------------------------- + * Finish short option sequence + * -------------------------------------------------------------- */ + optopt = (int) *place++ ; + + /* search charcater in option list */ + oli = strchr(optstring, optopt); + + /* short option not found */ + if (!oli) { + + if (! has_colon && opterr) + fprintf(stderr, + "%s: illegal option -- %c\n", + argv[0], optopt); + + if (*place) { + /* more short options in the list */ + return BADCH ; + } + + else { + /* error occured as last option in the list */ + place = EMSG ; + ret_val = BADCH ; + goto done_option ; + } + } /* end short option not found */ + + if (oli[1] != ':') { + /* short option with no argument */ + + if (*place) { + /* more short options in the list */ + return optopt ; + } + else { + /* last option in the list */ + place = EMSG ; + ret_val = optopt ; + goto done_option ; + } + + } else { + /* short option with argument */ + + /* -ovalue style */ + if (*place) { + optarg = place ; + place = EMSG ; + ret_val = optopt ; + goto done_option ; + } + /* -o value style: missing argument */ + else if (optbegin >= argc - 1) { + if (! has_colon && opterr) + fprintf(stderr, + "%s: option requires an argument -- %c\n", + argv[0], optopt); + place = EMSG ; + ret_val = has_colon ? BADARG : BADCH ; + goto done_option ; + } + + /* -o value style: process argument */ + optarg = argv [optend] ; + ++ optend ; + place = EMSG ; + ret_val = optopt ; + goto done_option ; + } /* short with argument */ + + done_option : + { + int pos = optend - optbegin ; /* n of circular shifts */ + int c = pos ; + + while (c --) { + int i ; + char *tmp = argv [optend - 1] ; + for (i = optend - 1 ; i > optind ; -- i) { + ((char**)argv) [i] = argv [i-1] ; + } + ((char**)argv) [optind] = tmp ; + } + optind += pos ; + } + + return ret_val ; +} diff --git a/Radio/HW/BladeRF/common/src/windows/gettimeofday.c b/Radio/HW/BladeRF/common/src/windows/gettimeofday.c new file mode 100644 index 0000000..144ee2f --- /dev/null +++ b/Radio/HW/BladeRF/common/src/windows/gettimeofday.c @@ -0,0 +1,49 @@ +/* + * This file is part of the bladeRF project: + * http://www.github.com/nuand/bladeRF + * + * Copyright (c) 2023 Nuand LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef WIN32 +#error "This file is intended for use with WIN32 systems only." +#endif + +#include <windows.h> +#include <stdint.h> +int gettimeofday(struct timeval *tp, struct timezone *tzp) +{ + // Note: some broken versions only have 8 trailing zero's, the correct epoch + // has 9 trailing zero's + static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tp->tv_sec = (long)((time - EPOCH) / 10000000L); + tp->tv_usec = (long)(system_time.wMilliseconds * 1000); + return 0; +} diff --git a/Radio/HW/BladeRF/common/src/windows/mkdtemp.c b/Radio/HW/BladeRF/common/src/windows/mkdtemp.c new file mode 100644 index 0000000..0e2f804 --- /dev/null +++ b/Radio/HW/BladeRF/common/src/windows/mkdtemp.c @@ -0,0 +1,250 @@ +/* + * This file is part of the bladeRF project: + * http://www.github.com/Nuand/bladeRF + * + * Copyright (c) 2018 Nuand LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// _CRT_RAND_S must be defined before including stdlib.h, to enable rand_s +#define _CRT_RAND_S +#include <stdlib.h> + +#ifdef WINDOWS_MKDTEMP_TEST_SUITE +// Running in standalone test mode + +#include <stdbool.h> +#include <stdio.h> +#define __debug(...) fprintf(stderr, __VA_ARGS__) + +#ifndef WIN32 +// Running standalone test on non-Windows OS +#include <time.h> +#include <unistd.h> +#define errno_t int +errno_t rand_s(unsigned int *randomValue) +{ + *randomValue = rand(); + return 0; +} +#endif // WIN32 + +#else +// Building as part of a library + +#ifndef WIN32 +#error "This file is intended for use with WIN32 systems only." +#endif // WIN32 + +#define __debug(...) + +#endif // WINDOWS_MKDTEMP_TEST_SUITE + +#include <errno.h> +#include <string.h> +#include <sys/stat.h> +#include "host_config.h" + +// The concepts of F_OK and S_IRWXU do not exist on Win32 +#ifndef F_OK +#define F_OK 0 +#endif + +#ifndef S_IRWXU +#define S_IRWXU 00700 +#endif + +/* h/t https://stackoverflow.com/a/14598879 */ +static int random_number(int min_num, int max_num) +{ + int result = 0, low_num = 0, hi_num = 0; + unsigned int randomValue; + + if (min_num < max_num) { + low_num = min_num; + hi_num = max_num + 1; // include max_num in output + } else { + low_num = max_num + 1; // include max_num in output + hi_num = min_num; + } + + // Use rand_s() on Windows, so that we don't have to deal with srand() + errno_t err = rand_s(&randomValue); + if (0 != err) { + return -1; + } + + result = (randomValue % (hi_num - low_num)) + low_num; + return result; +} + +char *mkdtemp(char *template) +{ + size_t const TEMPL_LEN = 6; + char const TEMPL_CHAR = 'X'; + + if (strlen(template) <= TEMPL_LEN) { + // template is too short + errno = EINVAL; + goto error; + } + + // Loop through the end of the template, replacing 'X' with random char + for (size_t i = strlen(template) - TEMPL_LEN; i < strlen(template); ++i) { + // The last TEMPL_LEN characters MUST be 'X' + if (template[i] != TEMPL_CHAR) { + errno = EINVAL; + goto error; + } + + // Pick a random letter + if (random_number(0, 1)) { + template[i] = (char)random_number('A', 'Z'); + } else { + template[i] = (char)random_number('a', 'z'); + } + } + + // Error out if the file already exists + if (access(template, F_OK) != -1) { + __debug("%s: failed: %s exists\n", __FUNCTION__, template); + errno = EEXIST; + goto error; + } + + // Try to create the directory... + if (0 != mkdir(template, S_IRWXU)) { + int errsv = errno; + __debug("%s: mkdir() failed: %s\n", __FUNCTION__, strerror(errsv)); + goto error; + } + + // Success! + errno = 0; + return template; + +error: + return NULL; +} + +#ifdef WINDOWS_MKDTEMP_TEST_SUITE +/** + * These functions are intended to verify proper operation of the test suite. + */ +static bool test(char *template, bool expect_success) +{ + char *rv = mkdtemp(template); + + if (NULL == rv) { + int errsv = errno; + printf("%s: mkdtemp failed: %s\n", __FUNCTION__, strerror(errsv)); + return (false == expect_success); + } else { + printf("%s: mkdtemp created: %s\n", __FUNCTION__, rv); + + if (0 != rmdir(rv)) { + int errsv = errno; + printf("%s: rmdir failed: %s\n", __FUNCTION__, strerror(errsv)); + } + + return (true == expect_success); + } +} + +int main(int argc, char *argv[]) +{ +#ifndef WIN32 + srand(time(NULL)); +#endif // WIN32 + + int success = 0, failure = 0; + + // Normal: should pass + char template1[] = "/tmp/asdf.XXXXXX"; + if (test(template1, true)) { + printf("*** Test case 1: PASS\n"); + ++success; + } else { + printf("*** Test case 1: FAIL\n"); + ++failure; + } + + // Too short: should fail + char template2[] = "XXXXXX"; + if (test(template2, false)) { + printf("*** Test case 2: PASS\n"); + ++success; + } else { + printf("*** Test case 2: FAIL\n"); + ++failure; + } + + // Not enough replacement Xs: should fail + char template3[] = "/tmp/asdf.XXXXX"; + if (test(template3, false)) { + printf("*** Test case 3: PASS\n"); + ++success; + } else { + printf("*** Test case 3: FAIL\n"); + ++failure; + } + + // Make sure it only replaces the end: should pass + char template4[] = "/tmp/asdfXXXXXX.XXXXXX"; + if (test(template4, true)) { + printf("*** Test case 4: PASS\n"); + ++success; + } else { + printf("*** Test case 4: FAIL\n"); + ++failure; + } + + // Really long: should fail + char template5[] = "/tmp/asdfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXXXXXX"; + if (test(template5, false)) { + printf("*** Test case 5: PASS\n"); + ++success; + } else { + printf("*** Test case 5: FAIL\n"); + ++failure; + } + + // Unwriteable path: should fail + char template6[] = "/asdfkjavblkjadv/asdf.XXXX"; + if (test(template6, false)) { + printf("*** Test case 6: PASS\n"); + ++success; + } else { + printf("*** Test case 6: FAIL\n"); + ++failure; + } + + printf("TEST SUMMARY: Success=%d, Failure=%d\n", success, failure); + + return failure; +} +#endif // WINDOWS_MKDTEMP_TEST_SUITE diff --git a/Radio/HW/BladeRF/common/src/windows/nanosleep.c b/Radio/HW/BladeRF/common/src/windows/nanosleep.c new file mode 100644 index 0000000..12d470a --- /dev/null +++ b/Radio/HW/BladeRF/common/src/windows/nanosleep.c @@ -0,0 +1,41 @@ +/* + * This file is part of the bladeRF project: + * http://www.github.com/nuand/bladeRF + * + * Copyright (c) 2018 Nuand LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef WIN32 +#error "This file is intended for use with WIN32 systems only." +#endif + +#include "nanosleep.h" +#include <windows.h> + +int nanosleep(const struct timespec *req, struct timespec *rem) +{ + DWORD sleep_ms; + + sleep_ms = ((DWORD)req->tv_sec * 1000) + ((DWORD)req->tv_nsec / 1000000); + + Sleep(sleep_ms); + + return 0; +} diff --git a/Radio/HW/BladeRF/common/src/windows/setenv.c b/Radio/HW/BladeRF/common/src/windows/setenv.c new file mode 100644 index 0000000..1f7eb8c --- /dev/null +++ b/Radio/HW/BladeRF/common/src/windows/setenv.c @@ -0,0 +1,50 @@ +/* + * This file is part of the bladeRF project: + * http://www.github.com/Nuand/bladeRF + * + * Copyright (c) 2018 Nuand LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef WIN32 +#error "This file is intended for use with WIN32 systems only." +#endif // WIN32 + +#include <stdlib.h> + +int setenv(const char *name, const char *value, int overwrite) +{ + errno_t rv = 0; + size_t envsize = 0; + + if (!overwrite) { + // Test for existence + rv = getenv_s(&envsize, NULL, 0, name); + if (rv != 0 || envsize != 0) { + return rv; + } + } + return _putenv_s(name, value); +} + +int unsetenv(const char *name) +{ + return _putenv_s(name, ""); +} |