diff options
Diffstat (limited to 'Utilities')
42 files changed, 491 insertions, 1083 deletions
diff --git a/Utilities/Scripts/update-expat.bash b/Utilities/Scripts/update-expat.bash index a052c0e..53449d0 100755 --- a/Utilities/Scripts/update-expat.bash +++ b/Utilities/Scripts/update-expat.bash @@ -8,7 +8,7 @@ readonly name="expat" readonly ownership="Expat Upstream <kwrobot@kitware.com>" readonly subtree="Utilities/cmexpat" readonly repo="https://github.com/libexpat/libexpat.git" -readonly tag="R_2_4_1" +readonly tag="R_2_4_3" readonly shortlog=false readonly paths=" expat/lib/asciitab.h diff --git a/Utilities/Scripts/update-jsoncpp.bash b/Utilities/Scripts/update-jsoncpp.bash index 5ed00e7..a05dcb8 100755 --- a/Utilities/Scripts/update-jsoncpp.bash +++ b/Utilities/Scripts/update-jsoncpp.bash @@ -8,7 +8,7 @@ readonly name="jsoncpp" readonly ownership="JsonCpp Upstream <kwrobot@kitware.com>" readonly subtree="Utilities/cmjsoncpp" readonly repo="https://github.com/open-source-parsers/jsoncpp.git" -readonly tag="1.9.4" +readonly tag="42e892d96e47b1f6e29844cc705e148ec4856448" readonly shortlog=false readonly paths=" LICENSE diff --git a/Utilities/cmexpat/ConfigureChecks.cmake b/Utilities/cmexpat/ConfigureChecks.cmake index 4da252c..341bab7 100644 --- a/Utilities/cmexpat/ConfigureChecks.cmake +++ b/Utilities/cmexpat/ConfigureChecks.cmake @@ -2,6 +2,7 @@ include(CheckCCompilerFlag) include(CheckCSourceCompiles) include(CheckIncludeFile) include(CheckIncludeFiles) +include(CheckLibraryExists) include(CheckSymbolExists) include(TestBigEndian) diff --git a/Utilities/cmexpat/README.md b/Utilities/cmexpat/README.md index 251dc8a..6fdd614 100644 --- a/Utilities/cmexpat/README.md +++ b/Utilities/cmexpat/README.md @@ -5,7 +5,7 @@ [![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases) -# Expat, Release 2.4.1 +# Expat, Release 2.4.3 This is Expat, a C library for parsing XML, started by [James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997. diff --git a/Utilities/cmexpat/lib/expat.h b/Utilities/cmexpat/lib/expat.h index b7d6d35..0f021e2 100644 --- a/Utilities/cmexpat/lib/expat.h +++ b/Utilities/cmexpat/lib/expat.h @@ -11,7 +11,7 @@ Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org> Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> @@ -1041,7 +1041,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 1 +#define XML_MICRO_VERSION 3 #ifdef __cplusplus } diff --git a/Utilities/cmexpat/lib/xmlparse.c b/Utilities/cmexpat/lib/xmlparse.c index 5ba56eae..b2f5fc6 100644 --- a/Utilities/cmexpat/lib/xmlparse.c +++ b/Utilities/cmexpat/lib/xmlparse.c @@ -1,4 +1,4 @@ -/* 8539b9040d9d901366a62560a064af7cb99811335784b363abc039c5b0ebc416 (2.4.1+) +/* 9ca2a2fedc35bcb13ba9a134ba5e173020bc2ff5f5a311abf742cec7da1ff26a (2.4.3+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -13,7 +13,7 @@ Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> Copyright (c) 2005-2009 Steven Solie <ssolie@users.sourceforge.net> Copyright (c) 2016 Eric Rahm <erahm@mozilla.com> - Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2016 Gaurav <g.gupta@samsung.com> Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr> @@ -32,6 +32,7 @@ Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org> Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org> + Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -54,6 +55,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define XML_BUILDING_EXPAT 1 + +#include <expat_config.h> + #if ! defined(_GNU_SOURCE) # define _GNU_SOURCE 1 /* syscall prototype */ #endif @@ -84,14 +89,10 @@ # include <errno.h> #endif -#define XML_BUILDING_EXPAT 1 - #ifdef _WIN32 # include "winconfig.h" #endif -#include <expat_config.h> - #include "ascii.h" #include "expat.h" #include "siphash.h" @@ -3260,13 +3261,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, /* get the attributes from the tokenizer */ n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); + + /* Detect and prevent integer overflow */ + if (n > INT_MAX - nDefaultAtts) { + return XML_ERROR_NO_MEMORY; + } + if (n + nDefaultAtts > parser->m_attsSize) { int oldAttsSize = parser->m_attsSize; ATTRIBUTE *temp; #ifdef XML_ATTR_INFO XML_AttrInfo *temp2; #endif + + /* Detect and prevent integer overflow */ + if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) + || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { + return XML_ERROR_NO_MEMORY; + } + parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } +#endif + temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); if (temp == NULL) { @@ -3275,6 +3301,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, } parser->m_atts = temp; #ifdef XML_ATTR_INFO + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +# if UINT_MAX >= SIZE_MAX + if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } +# endif + temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); if (temp2 == NULL) { @@ -3413,7 +3450,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, if (nPrefixes) { int j; /* hash table index */ unsigned long version = parser->m_nsAttsVersion; - int nsAttsSize = (int)1 << parser->m_nsAttsPower; + + /* Detect and prevent invalid shift */ + if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { + return XML_ERROR_NO_MEMORY; + } + + unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; unsigned char oldNsAttsPower = parser->m_nsAttsPower; /* size of hash table must be at least 2 * (# of prefixed attributes) */ if ((nPrefixes << 1) @@ -3424,7 +3467,28 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, ; if (parser->m_nsAttsPower < 3) parser->m_nsAttsPower = 3; - nsAttsSize = (int)1 << parser->m_nsAttsPower; + + /* Detect and prevent invalid shift */ + if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } + + nsAttsSize = 1u << parser->m_nsAttsPower; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } +#endif + temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); if (! temp) { @@ -3582,9 +3646,31 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, tagNamePtr->prefixLen = prefixLen; for (i = 0; localPart[i++];) ; /* i includes null terminator */ + + /* Detect and prevent integer overflow */ + if (binding->uriLen > INT_MAX - prefixLen + || i > INT_MAX - (binding->uriLen + prefixLen)) { + return XML_ERROR_NO_MEMORY; + } + n = i + binding->uriLen + prefixLen; if (n > binding->uriAlloc) { TAG *p; + + /* Detect and prevent integer overflow */ + if (n > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); if (! uri) return XML_ERROR_NO_MEMORY; @@ -3680,6 +3766,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (parser->m_freeBindingList) { b = parser->m_freeBindingList; if (len > b->uriAlloc) { + /* Detect and prevent integer overflow */ + if (len > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + XML_Char *temp = (XML_Char *)REALLOC( parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (temp == NULL) @@ -3692,6 +3793,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, b = (BINDING *)MALLOC(parser, sizeof(BINDING)); if (! b) return XML_ERROR_NO_MEMORY; + + /* Detect and prevent integer overflow */ + if (len > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (! b->uri) { @@ -5018,6 +5134,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, if (parser->m_prologState.level >= parser->m_groupSize) { if (parser->m_groupSize) { { + /* Detect and prevent integer overflow */ + if (parser->m_groupSize > (unsigned int)(-1) / 2u) { + return XML_ERROR_NO_MEMORY; + } + char *const new_connector = (char *)REALLOC( parser, parser->m_groupConnector, parser->m_groupSize *= 2); if (new_connector == NULL) { @@ -5028,6 +5149,16 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, } if (dtd->scaffIndex) { + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { + return XML_ERROR_NO_MEMORY; + } +#endif + int *const new_scaff_index = (int *)REALLOC( parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); if (new_scaff_index == NULL) @@ -6098,7 +6229,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, } } else { DEFAULT_ATTRIBUTE *temp; + + /* Detect and prevent integer overflow */ + if (type->allocDefaultAtts > INT_MAX / 2) { + return 0; + } + int count = type->allocDefaultAtts * 2; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { + return 0; + } +#endif + temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); if (temp == NULL) @@ -6749,8 +6897,20 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { /* check for overflow (table is half full) */ if (table->used >> (table->power - 1)) { unsigned char newPower = table->power + 1; + + /* Detect and prevent invalid shift */ + if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { + return NULL; + } + size_t newSize = (size_t)1 << newPower; unsigned long newMask = (unsigned long)newSize - 1; + + /* Detect and prevent integer overflow */ + if (newSize > (size_t)(-1) / sizeof(NAMED *)) { + return NULL; + } + size_t tsize = newSize * sizeof(NAMED *); NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); if (! newV) @@ -7100,6 +7260,20 @@ nextScaffoldPart(XML_Parser parser) { if (dtd->scaffCount >= dtd->scaffSize) { CONTENT_SCAFFOLD *temp; if (dtd->scaffold) { + /* Detect and prevent integer overflow */ + if (dtd->scaffSize > UINT_MAX / 2u) { + return -1; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { + return -1; + } +#endif + temp = (CONTENT_SCAFFOLD *)REALLOC( parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) @@ -7169,8 +7343,26 @@ build_model(XML_Parser parser) { XML_Content *ret; XML_Content *cpos; XML_Char *str; - int allocsize = (dtd->scaffCount * sizeof(XML_Content) - + (dtd->contentStringLen * sizeof(XML_Char))); + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { + return NULL; + } + if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { + return NULL; + } +#endif + if (dtd->scaffCount * sizeof(XML_Content) + > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { + return NULL; + } + + const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) + + (dtd->contentStringLen * sizeof(XML_Char))); ret = (XML_Content *)MALLOC(parser, allocsize); if (! ret) diff --git a/Utilities/cmexpat/lib/xmlrole.c b/Utilities/cmexpat/lib/xmlrole.c index 08173b0..77746ee 100644 --- a/Utilities/cmexpat/lib/xmlrole.c +++ b/Utilities/cmexpat/lib/xmlrole.c @@ -15,6 +15,7 @@ Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> + Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -37,14 +38,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include <expat_config.h> + #include <stddef.h> #ifdef _WIN32 # include "winconfig.h" #endif -#include <expat_config.h> - #include "expat_external.h" #include "internal.h" #include "xmlrole.h" diff --git a/Utilities/cmexpat/lib/xmltok.c b/Utilities/cmexpat/lib/xmltok.c index f2b6b40..502ca1a 100644 --- a/Utilities/cmexpat/lib/xmltok.c +++ b/Utilities/cmexpat/lib/xmltok.c @@ -20,6 +20,7 @@ Copyright (c) 2017 Benbuck Nason <bnason@netflix.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> + Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -42,6 +43,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include <expat_config.h> + #include <stddef.h> #include <string.h> /* memcpy */ #include <stdbool.h> @@ -50,8 +53,6 @@ # include "winconfig.h" #endif -#include <expat_config.h> - #include "expat_external.h" #include "internal.h" #include "xmltok.h" diff --git a/Utilities/cmexpat/lib/xmltok_ns.c b/Utilities/cmexpat/lib/xmltok_ns.c index 5fd8392..fbdd3e3 100644 --- a/Utilities/cmexpat/lib/xmltok_ns.c +++ b/Utilities/cmexpat/lib/xmltok_ns.c @@ -11,7 +11,7 @@ Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -93,7 +93,7 @@ NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, static const ENCODING * NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { # define ENCODING_MAX 128 - char buf[ENCODING_MAX]; + char buf[ENCODING_MAX] = ""; char *p = buf; int i; XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); diff --git a/Utilities/cmjsoncpp/LICENSE b/Utilities/cmjsoncpp/LICENSE index 89280a6..c41a1d1 100644 --- a/Utilities/cmjsoncpp/LICENSE +++ b/Utilities/cmjsoncpp/LICENSE @@ -1,25 +1,25 @@ -The JsonCpp library's source code, including accompanying documentation, +The JsonCpp library's source code, including accompanying documentation, tests and demonstration applications, are licensed under the following conditions... -Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all -jurisdictions which recognize such a disclaimer. In such jurisdictions, +Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, this software is released into the Public Domain. In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and The JsonCpp Authors, and is released under the terms of the MIT License (see below). -In jurisdictions which recognize Public Domain property, the user of this -software may choose to accept it either as 1) Public Domain, 2) under the -conditions of the MIT License (see below), or 3) under the terms of dual +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual Public Domain/MIT License conditions described here, as they choose. The MIT License is about as close to Public Domain as a license can get, and is described in clear, concise terms at: http://en.wikipedia.org/wiki/MIT_License - + The full text of the MIT License follows: ======================================================================== diff --git a/Utilities/cmjsoncpp/README-CMake.txt b/Utilities/cmjsoncpp/README-CMake.txt deleted file mode 100644 index bf74094..0000000 --- a/Utilities/cmjsoncpp/README-CMake.txt +++ /dev/null @@ -1,66 +0,0 @@ -The Utilities/cmjsoncpp directory contains a reduced distribution -of the jsoncpp source tree with only the library source code and -CMake build system. It is not a submodule; the actual content is part -of our source tree and changes can be made and committed directly. - -We update from upstream using Git's "subtree" merge strategy. A -special branch contains commits of upstream jsoncpp snapshots and -nothing else. No Git ref points explicitly to the head of this -branch, but it is merged into our history. - -Update jsoncpp from upstream as follows. Create a local branch to -explicitly reference the upstream snapshot branch head: - - git branch jsoncpp-upstream 53f6ccb0 - -Use a temporary directory to checkout the branch: - - mkdir jsoncpp-tmp - cd jsoncpp-tmp - git init - git pull .. jsoncpp-upstream - rm -rf * - -Now place the (reduced) jsoncpp content in this directory. See -instructions shown by - - git log 53f6ccb0 - -for help extracting the content from the upstream svn repo. Then run -the following commands to commit the new version. Substitute the -appropriate date and version number: - - git add --all - - GIT_AUTHOR_NAME='JsonCpp Upstream' \ - GIT_AUTHOR_EMAIL='kwrobot@kitware.com' \ - GIT_AUTHOR_DATE='Thu Nov 20 08:45:58 2014 -0600' \ - git commit -m 'JsonCpp 1.0.0 (reduced)' && - git commit --amend - -Edit the commit message to describe the procedure used to obtain the -content. Then push the changes back up to the main local repository: - - git push .. HEAD:jsoncpp-upstream - cd .. - rm -rf jsoncpp-tmp - -Create a topic in the main repository on which to perform the update: - - git checkout -b update-jsoncpp master - -Merge the jsoncpp-upstream branch as a subtree: - - git merge -s recursive -X subtree=Utilities/cmjsoncpp \ - jsoncpp-upstream - -If there are conflicts, resolve them and commit. Build and test the -tree. Commit any additional changes needed to succeed. - -Finally, run - - git rev-parse --short=8 jsoncpp-upstream - -to get the commit from which the jsoncpp-upstream branch must be started -on the next update. Edit the "git branch jsoncpp-upstream" line above to -record it, and commit this file. diff --git a/Utilities/cmjsoncpp/include/json/allocator.h b/Utilities/cmjsoncpp/include/json/allocator.h index a685da1..3718df1 100644 --- a/Utilities/cmjsoncpp/include/json/allocator.h +++ b/Utilities/cmjsoncpp/include/json/allocator.h @@ -10,7 +10,8 @@ #include <memory> #if !defined(__SUNPRO_CC) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() #endif namespace Json { @@ -37,11 +38,10 @@ public: * Release memory which was allocated for N items at pointer P. * * The memory block is filled with zeroes before being released. - * The pointer argument is tagged as "volatile" to prevent the - * compiler optimizing out this critical step. */ - void deallocate(volatile pointer p, size_type n) { - std::memset(p, 0, n * sizeof(T)); + void deallocate(pointer p, size_type n) { + // memset_s is used because memset may be optimized away by the compiler + memset_s(p, n * sizeof(T), 0, n * sizeof(T)); // free using "global operator delete" ::operator delete(p); } diff --git a/Utilities/cmjsoncpp/include/json/json_features.h b/Utilities/cmjsoncpp/include/json/json_features.h index 6b99b4d..e1fc983 100644 --- a/Utilities/cmjsoncpp/include/json/json_features.h +++ b/Utilities/cmjsoncpp/include/json/json_features.h @@ -11,7 +11,8 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #if !defined(__SUNPRO_CC) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() #endif namespace Json { diff --git a/Utilities/cmjsoncpp/include/json/reader.h b/Utilities/cmjsoncpp/include/json/reader.h index 7ad0be6..0d444ad 100644 --- a/Utilities/cmjsoncpp/include/json/reader.h +++ b/Utilities/cmjsoncpp/include/json/reader.h @@ -24,7 +24,8 @@ #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #if !defined(__SUNPRO_CC) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() #endif namespace Json { @@ -35,8 +36,7 @@ namespace Json { * deprecated Use CharReader and CharReaderBuilder. */ -class JSONCPP_DEPRECATED( - "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { +class JSON_API Reader { public: using Char = char; using Location = const Char*; @@ -53,13 +53,13 @@ public: }; /** \brief Constructs a Reader allowing all features for parsing. + * deprecated Use CharReader and CharReaderBuilder. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set for parsing. + * deprecated Use CharReader and CharReaderBuilder. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> @@ -326,6 +326,9 @@ public: * - `"allowSpecialFloats": false or true` * - If true, special float values (NaNs and infinities) are allowed and * their values are lossfree restorable. + * - `"skipBom": false or true` + * - If true, if the input starts with the Unicode byte order mark (BOM), + * it is skipped. * * You can examine 'settings_` yourself to see the defaults. You can also * write and read them just like any JSON Value. diff --git a/Utilities/cmjsoncpp/include/json/value.h b/Utilities/cmjsoncpp/include/json/value.h index 952d423..f6ac9e3 100644 --- a/Utilities/cmjsoncpp/include/json/value.h +++ b/Utilities/cmjsoncpp/include/json/value.h @@ -50,11 +50,12 @@ // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma warning(push) -#pragma warning(disable : 4251) +#pragma warning(disable : 4251 4275) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #if !defined(__SUNPRO_CC) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() #endif /** \brief JSON (JavaScript Object Notation). @@ -265,10 +266,10 @@ private: CZString(ArrayIndex index); CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(CZString const& other); - CZString(CZString&& other); + CZString(CZString&& other) noexcept; ~CZString(); CZString& operator=(const CZString& other); - CZString& operator=(CZString&& other); + CZString& operator=(CZString&& other) noexcept; bool operator<(CZString const& other) const; bool operator==(CZString const& other) const; @@ -346,13 +347,13 @@ public: Value(bool value); Value(std::nullptr_t ptr) = delete; Value(const Value& other); - Value(Value&& other); + Value(Value&& other) noexcept; ~Value(); /// \note Overwrite existing comments. To preserve comments, use /// #swapPayload(). Value& operator=(const Value& other); - Value& operator=(Value&& other); + Value& operator=(Value&& other) noexcept; /// Swap everything. void swap(Value& other); @@ -637,9 +638,9 @@ private: public: Comments() = default; Comments(const Comments& that); - Comments(Comments&& that); + Comments(Comments&& that) noexcept; Comments& operator=(const Comments& that); - Comments& operator=(Comments&& that); + Comments& operator=(Comments&& that) noexcept; bool has(CommentPlacement slot) const; String get(CommentPlacement slot) const; void set(CommentPlacement slot, String comment); @@ -920,8 +921,8 @@ public: * because the returned references/pointers can be used * to change state of the base class. */ - reference operator*() { return deref(); } - pointer operator->() { return &deref(); } + reference operator*() const { return const_cast<reference>(deref()); } + pointer operator->() const { return const_cast<pointer>(&deref()); } }; inline void swap(Value& a, Value& b) { a.swap(b); } diff --git a/Utilities/cmjsoncpp/include/json/version.h b/Utilities/cmjsoncpp/include/json/version.h index 5b9783d..e931d03 100644 --- a/Utilities/cmjsoncpp/include/json/version.h +++ b/Utilities/cmjsoncpp/include/json/version.h @@ -9,10 +9,10 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.4" +#define JSONCPP_VERSION_STRING "1.9.5" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 3 +#define JSONCPP_VERSION_PATCH 5 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ diff --git a/Utilities/cmjsoncpp/include/json/writer.h b/Utilities/cmjsoncpp/include/json/writer.h index cc6b78c..2a47d5e 100644 --- a/Utilities/cmjsoncpp/include/json/writer.h +++ b/Utilities/cmjsoncpp/include/json/writer.h @@ -21,7 +21,8 @@ #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #if !defined(__SUNPRO_CC) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() #endif namespace Json { @@ -112,6 +113,8 @@ public: * - Number of precision digits for formatting of real values. * - "precisionType": "significant"(default) or "decimal" * - Type of precision for formatting of real values. + * - "emitUTF8": false or true + * - If true, outputs raw UTF8 strings instead of escaping them. * You can examine 'settings_` yourself * to see the defaults. You can also write and read them just like any @@ -147,7 +150,7 @@ public: /** \brief Abstract class for writers. * deprecated Use StreamWriter. (And really, this is an implementation detail.) */ -class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { +class JSON_API Writer { public: virtual ~Writer(); @@ -167,7 +170,7 @@ public: #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter +class JSON_API FastWriter : public Writer { public: FastWriter(); @@ -217,7 +220,7 @@ private: * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their *#CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -227,7 +230,7 @@ private: #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API +class JSON_API StyledWriter : public Writer { public: StyledWriter(); @@ -286,7 +289,7 @@ private: * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their #CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -296,7 +299,7 @@ private: #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API +class JSON_API StyledStreamWriter { public: /** diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp index e6caf40..5cc718d 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp @@ -12,6 +12,7 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #include <algorithm> #include <cassert> +#include <cmath> #include <cstring> #include <iostream> #include <istream> @@ -104,8 +105,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) { // Since String is reference-counted, this at least does not // create an extra copy. - String doc; - std::getline(is, doc, static_cast<char> EOF); + String doc(std::istreambuf_iterator<char>(is), {}); return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } @@ -601,9 +601,15 @@ bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; String buffer(token.start_, token.end_); IStringStream is(buffer); - if (!(is >> value)) - return addError( + if (!(is >> value)) { + if (value == std::numeric_limits<double>::max()) + value = std::numeric_limits<double>::infinity(); + else if (value == std::numeric_limits<double>::lowest()) + value = -std::numeric_limits<double>::infinity(); + else if (!std::isinf(value)) + return addError( "'" + String(token.start_, token.end_) + "' is not a number.", token); + } decoded = value; return true; } @@ -1608,7 +1614,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { const auto digit(static_cast<Value::UInt>(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If - // a) we've only just touched the limit, meaing value == threshold, + // a) we've only just touched the limit, meaning value == threshold, // b) this is the last digit, or // c) it's small enough to fit in that rounding delta, we're okay. // Otherwise treat this number as a double to avoid overflow. @@ -1648,7 +1654,12 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { const String buffer(token.start_, token.end_); IStringStream is(buffer); if (!(is >> value)) { - return addError( + if (value == std::numeric_limits<double>::max()) + value = std::numeric_limits<double>::infinity(); + else if (value == std::numeric_limits<double>::lowest()) + value = -std::numeric_limits<double>::infinity(); + else if (!std::isinf(value)) + return addError( "'" + String(token.start_, token.end_) + "' is not a number.", token); } decoded = value; @@ -1922,7 +1933,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const { if (valid_keys.count(key)) continue; if (invalid) - (*invalid)[std::move(key)] = *si; + (*invalid)[key] = *si; else return false; } diff --git a/Utilities/cmjsoncpp/src/lib_json/json_tool.h b/Utilities/cmjsoncpp/src/lib_json/json_tool.h index 2d7b7d9..b952c19 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_tool.h +++ b/Utilities/cmjsoncpp/src/lib_json/json_tool.h @@ -116,14 +116,18 @@ template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) { * Return iterator that would be the new end of the range [begin,end), if we * were to delete zeros in the end of string, but not the last zero before '.'. */ -template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) { +template <typename Iter> +Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) { for (; begin != end; --end) { if (*(end - 1) != '0') { return end; } // Don't delete the last zero before the decimal point. - if (begin != (end - 1) && *(end - 2) == '.') { - return end; + if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') { + if (precision) { + return end; + } + return end - 2; } } return end; diff --git a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp index d59b7d9..b496ddf 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp @@ -259,7 +259,7 @@ Value::CZString::CZString(const CZString& other) { storage_.length_ = other.storage_.length_; } -Value::CZString::CZString(CZString&& other) +Value::CZString::CZString(CZString&& other) noexcept : cstr_(other.cstr_), index_(other.index_) { other.cstr_ = nullptr; } @@ -285,7 +285,7 @@ Value::CZString& Value::CZString::operator=(const CZString& other) { return *this; } -Value::CZString& Value::CZString::operator=(CZString&& other) { +Value::CZString& Value::CZString::operator=(CZString&& other) noexcept { cstr_ = other.cstr_; index_ = other.index_; other.cstr_ = nullptr; @@ -433,7 +433,7 @@ Value::Value(const Value& other) { dupMeta(other); } -Value::Value(Value&& other) { +Value::Value(Value&& other) noexcept { initBasic(nullValue); swap(other); } @@ -448,7 +448,7 @@ Value& Value::operator=(const Value& other) { return *this; } -Value& Value::operator=(Value&& other) { +Value& Value::operator=(Value&& other) noexcept { other.swap(*this); return *this; } @@ -912,7 +912,8 @@ void Value::resize(ArrayIndex newSize) { if (newSize == 0) clear(); else if (newSize > oldSize) - this->operator[](newSize - 1); + for (ArrayIndex i = oldSize; i < newSize; ++i) + (*this)[i]; else { for (ArrayIndex index = newSize; index < oldSize; ++index) { value_.map_->erase(index); @@ -1373,14 +1374,15 @@ bool Value::isObject() const { return type() == objectValue; } Value::Comments::Comments(const Comments& that) : ptr_{cloneUnique(that.ptr_)} {} -Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {} +Value::Comments::Comments(Comments&& that) noexcept + : ptr_{std::move(that.ptr_)} {} Value::Comments& Value::Comments::operator=(const Comments& that) { ptr_ = cloneUnique(that.ptr_); return *this; } -Value::Comments& Value::Comments::operator=(Comments&& that) { +Value::Comments& Value::Comments::operator=(Comments&& that) noexcept { ptr_ = std::move(that.ptr_); return *this; } @@ -1396,13 +1398,11 @@ String Value::Comments::get(CommentPlacement slot) const { } void Value::Comments::set(CommentPlacement slot, String comment) { - if (!ptr_) { + if (slot >= CommentPlacement::numberOfCommentPlacement) + return; + if (!ptr_) ptr_ = std::unique_ptr<Array>(new Array()); - } - // check comments array boundry. - if (slot < CommentPlacement::numberOfCommentPlacement) { - (*ptr_)[slot] = std::move(comment); - } + (*ptr_)[slot] = std::move(comment); } void Value::setComment(String comment, CommentPlacement placement) { diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp index 8bf02db..0dd160e 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp @@ -68,7 +68,7 @@ #if !defined(isnan) // IEEE standard states that NaN values will not compare to themselves -#define isnan(x) (x != x) +#define isnan(x) ((x) != (x)) #endif #if !defined(__APPLE__) @@ -154,16 +154,18 @@ String valueToString(double value, bool useSpecialFloats, buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); - // strip the zero padding from the right - if (precisionType == PrecisionType::decimalPlaces) { - buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); - } - // try to ensure we preserve the fact that this was given to us as a double on // input if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { buffer += ".0"; } + + // strip the zero padding from the right + if (precisionType == PrecisionType::decimalPlaces) { + buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end(), precision), + buffer.end()); + } + return buffer; } } // namespace @@ -270,7 +272,7 @@ static void appendHex(String& result, unsigned ch) { result.append("\\u").append(toHex16Bit(ch)); } -static String valueToQuotedStringN(const char* value, unsigned length, +static String valueToQuotedStringN(const char* value, size_t length, bool emitUTF8 = false) { if (value == nullptr) return ""; @@ -348,7 +350,7 @@ static String valueToQuotedStringN(const char* value, unsigned length, } String valueToQuotedString(const char* value) { - return valueToQuotedStringN(value, static_cast<unsigned int>(strlen(value))); + return valueToQuotedStringN(value, strlen(value)); } // Class Writer @@ -397,7 +399,7 @@ void FastWriter::writeValue(const Value& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str)); + document_ += valueToQuotedStringN(str, static_cast<size_t>(end - str)); break; } case booleanValue: @@ -420,8 +422,7 @@ void FastWriter::writeValue(const Value& value) { const String& name = *it; if (it != members.begin()) document_ += ','; - document_ += valueToQuotedStringN(name.data(), - static_cast<unsigned>(name.length())); + document_ += valueToQuotedStringN(name.data(), name.length()); document_ += yamlCompatibilityEnabled_ ? ": " : ":"; writeValue(value[name]); } @@ -466,7 +467,7 @@ void StyledWriter::writeValue(const Value& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + pushValue(valueToQuotedStringN(str, static_cast<size_t>(end - str))); else pushValue(""); break; @@ -507,7 +508,7 @@ void StyledWriter::writeValue(const Value& value) { } void StyledWriter::writeArrayValue(const Value& value) { - unsigned size = value.size(); + size_t size = value.size(); if (size == 0) pushValue("[]"); else { @@ -516,7 +517,7 @@ void StyledWriter::writeArrayValue(const Value& value) { writeWithIndent("["); indent(); bool hasChildValue = !childValues_.empty(); - unsigned index = 0; + ArrayIndex index = 0; for (;;) { const Value& childValue = value[index]; writeCommentBeforeValue(childValue); @@ -539,7 +540,7 @@ void StyledWriter::writeArrayValue(const Value& value) { { assert(childValues_.size() == size); document_ += "[ "; - for (unsigned index = 0; index < size; ++index) { + for (size_t index = 0; index < size; ++index) { if (index > 0) document_ += ", "; document_ += childValues_[index]; @@ -684,7 +685,7 @@ void StyledStreamWriter::writeValue(const Value& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + pushValue(valueToQuotedStringN(str, static_cast<size_t>(end - str))); else pushValue(""); break; @@ -958,8 +959,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str), - emitUTF8_)); + pushValue( + valueToQuotedStringN(str, static_cast<size_t>(end - str), emitUTF8_)); else pushValue(""); break; @@ -982,8 +983,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { String const& name = *it; Value const& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedStringN( - name.data(), static_cast<unsigned>(name.length()), emitUTF8_)); + writeWithIndent( + valueToQuotedStringN(name.data(), name.length(), emitUTF8_)); *sout_ << colonSymbol_; writeValue(childValue); if (++it == members.end()) { @@ -1217,7 +1218,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const { if (valid_keys.count(key)) continue; if (invalid) - (*invalid)[std::move(key)] = *si; + (*invalid)[key] = *si; else return false; } diff --git a/Utilities/cmlibuv/LICENSE b/Utilities/cmlibuv/LICENSE index 28f1733..eb126da 100644 --- a/Utilities/cmlibuv/LICENSE +++ b/Utilities/cmlibuv/LICENSE @@ -64,7 +64,3 @@ The externally maintained libraries used by libuv are: - pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB. Three clause BSD license. - - - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design - Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement - n° 289016). Three clause BSD license. diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index 48213e2..747095f 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -49,6 +49,8 @@ extern "C" { # endif #elif __GNUC__ >= 4 # define UV_EXTERN __attribute__((visibility("default"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) /* Sun Studio >= 8 */ +# define UV_EXTERN __global #else # define UV_EXTERN /* nothing */ #endif @@ -1676,6 +1678,7 @@ UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size); UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size); +UV_EXTERN int uv_ip_name(const struct sockaddr* src, char* dst, size_t size); UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); diff --git a/Utilities/cmlibuv/include/uv/android-ifaddrs.h b/Utilities/cmlibuv/include/uv/android-ifaddrs.h deleted file mode 100644 index 9cd19fe..0000000 --- a/Utilities/cmlibuv/include/uv/android-ifaddrs.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1995, 1999 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp - */ - -#ifndef _IFADDRS_H_ -#define _IFADDRS_H_ - -struct ifaddrs { - struct ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - struct sockaddr *ifa_addr; - struct sockaddr *ifa_netmask; - struct sockaddr *ifa_dstaddr; - void *ifa_data; -}; - -/* - * This may have been defined in <net/if.h>. Note that if <net/if.h> is - * to be included it must be included before this header file. - */ -#ifndef ifa_broadaddr -#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ -#endif - -#include <sys/cdefs.h> - -__BEGIN_DECLS -extern int getifaddrs(struct ifaddrs **ifap); -extern void freeifaddrs(struct ifaddrs *ifa); -__END_DECLS - -#endif diff --git a/Utilities/cmlibuv/include/uv/version.h b/Utilities/cmlibuv/include/uv/version.h index ab5ed00..1934f39 100644 --- a/Utilities/cmlibuv/include/uv/version.h +++ b/Utilities/cmlibuv/include/uv/version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 42 +#define UV_VERSION_MINOR 43 #define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 0 #define UV_VERSION_SUFFIX "dev" diff --git a/Utilities/cmlibuv/include/uv/win.h b/Utilities/cmlibuv/include/uv/win.h index 9b5d5dc..e3fe37d 100644 --- a/Utilities/cmlibuv/include/uv/win.h +++ b/Utilities/cmlibuv/include/uv/win.h @@ -274,21 +274,14 @@ typedef union { } unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */ } uv_cond_t; -typedef union { - struct { - unsigned int num_readers_; - CRITICAL_SECTION num_readers_lock_; - HANDLE write_semaphore_; - } state_; - /* TODO: remove me in v2.x. */ - struct { - SRWLOCK unused_; - } unused1_; - /* TODO: remove me in v2.x. */ - struct { - uv_mutex_t unused1_; - uv_mutex_t unused2_; - } unused2_; +typedef struct { + SRWLOCK read_write_lock_; + /* TODO: retained for ABI compatibility; remove me in v2.x */ +#ifdef _WIN64 + unsigned char padding_[72]; +#else + unsigned char padding_[44]; +#endif } uv_rwlock_t; typedef struct { diff --git a/Utilities/cmlibuv/src/threadpool.c b/Utilities/cmlibuv/src/threadpool.c index 869ae95..e804c7c 100644 --- a/Utilities/cmlibuv/src/threadpool.c +++ b/Utilities/cmlibuv/src/threadpool.c @@ -160,13 +160,20 @@ static void post(QUEUE* q, enum uv__work_kind kind) { } +#ifdef __MVS__ +/* TODO(itodorov) - zos: revisit when Woz compiler is available. */ +__attribute__((destructor)) +#endif void uv__threadpool_cleanup(void) { unsigned int i; if (nthreads == 0) return; +#ifndef __MVS__ + /* TODO(gabylb) - zos: revisit when Woz compiler is available. */ post(&exit_message, UV__WORK_CPU); +#endif for (i = 0; i < nthreads; i++) if (uv_thread_join(threads + i)) diff --git a/Utilities/cmlibuv/src/unix/android-ifaddrs.c b/Utilities/cmlibuv/src/unix/android-ifaddrs.c deleted file mode 100644 index 4765cc0..0000000 --- a/Utilities/cmlibuv/src/unix/android-ifaddrs.c +++ /dev/null @@ -1,713 +0,0 @@ -/* -Copyright (c) 2013, Kenneth MacKay -Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement #289016) -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "uv/android-ifaddrs.h" -#include "uv-common.h" - -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <sys/socket.h> -#include <net/if_arp.h> -#include <netinet/in.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <linux/if_packet.h> - -typedef struct NetlinkList -{ - struct NetlinkList *m_next; - struct nlmsghdr *m_data; - unsigned int m_size; -} NetlinkList; - -static int netlink_socket(pid_t *p_pid) -{ - struct sockaddr_nl l_addr; - socklen_t l_len; - - int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if(l_socket < 0) - { - return -1; - } - - memset(&l_addr, 0, sizeof(l_addr)); - l_addr.nl_family = AF_NETLINK; - if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) - { - close(l_socket); - return -1; - } - - l_len = sizeof(l_addr); - if(getsockname(l_socket, (struct sockaddr *)&l_addr, &l_len) < 0) - { - close(l_socket); - return -1; - } - *p_pid = l_addr.nl_pid; - - return l_socket; -} - -static int netlink_send(int p_socket, int p_request) -{ - char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))]; - - struct nlmsghdr *l_hdr; - struct rtgenmsg *l_msg; - struct sockaddr_nl l_addr; - - memset(l_buffer, 0, sizeof(l_buffer)); - - l_hdr = (struct nlmsghdr *)l_buffer; - l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr); - - l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg)); - l_hdr->nlmsg_type = p_request; - l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; - l_hdr->nlmsg_pid = 0; - l_hdr->nlmsg_seq = p_socket; - l_msg->rtgen_family = AF_UNSPEC; - - memset(&l_addr, 0, sizeof(l_addr)); - l_addr.nl_family = AF_NETLINK; - return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr))); -} - -static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) -{ - struct sockaddr_nl l_addr; - struct msghdr l_msg; - - struct iovec l_iov; - l_iov.iov_base = p_buffer; - l_iov.iov_len = p_len; - - for(;;) - { - int l_result; - l_msg.msg_name = (void *)&l_addr; - l_msg.msg_namelen = sizeof(l_addr); - l_msg.msg_iov = &l_iov; - l_msg.msg_iovlen = 1; - l_msg.msg_control = NULL; - l_msg.msg_controllen = 0; - l_msg.msg_flags = 0; - l_result = recvmsg(p_socket, &l_msg, 0); - - if(l_result < 0) - { - if(errno == EINTR) - { - continue; - } - return -2; - } - - /* Buffer was too small */ - if(l_msg.msg_flags & MSG_TRUNC) - { - return -1; - } - return l_result; - } -} - -static struct nlmsghdr *getNetlinkResponse(int p_socket, pid_t p_pid, int *p_size, int *p_done) -{ - size_t l_size = 4096; - void *l_buffer = NULL; - - for(;;) - { - int l_read; - - uv__free(l_buffer); - l_buffer = uv__malloc(l_size); - if (l_buffer == NULL) - { - return NULL; - } - - l_read = netlink_recv(p_socket, l_buffer, l_size); - *p_size = l_read; - if(l_read == -2) - { - uv__free(l_buffer); - return NULL; - } - if(l_read >= 0) - { - struct nlmsghdr *l_hdr; - for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) - { - if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - *p_done = 1; - break; - } - - if(l_hdr->nlmsg_type == NLMSG_ERROR) - { - uv__free(l_buffer); - return NULL; - } - } - return l_buffer; - } - - l_size *= 2; - } -} - -static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) -{ - NetlinkList *l_item = uv__malloc(sizeof(NetlinkList)); - if (l_item == NULL) - { - return NULL; - } - - l_item->m_next = NULL; - l_item->m_data = p_data; - l_item->m_size = p_size; - return l_item; -} - -static void freeResultList(NetlinkList *p_list) -{ - NetlinkList *l_cur; - while(p_list) - { - l_cur = p_list; - p_list = p_list->m_next; - uv__free(l_cur->m_data); - uv__free(l_cur); - } -} - -static NetlinkList *getResultList(int p_socket, int p_request, pid_t p_pid) -{ - int l_size; - int l_done; - NetlinkList *l_list; - NetlinkList *l_end; - - if(netlink_send(p_socket, p_request) < 0) - { - return NULL; - } - - l_list = NULL; - l_end = NULL; - - l_done = 0; - while(!l_done) - { - NetlinkList *l_item; - - struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, p_pid, &l_size, &l_done); - /* Error */ - if(!l_hdr) - { - freeResultList(l_list); - return NULL; - } - - l_item = newListItem(l_hdr, l_size); - if (!l_item) - { - freeResultList(l_list); - return NULL; - } - if(!l_list) - { - l_list = l_item; - } - else - { - l_end->m_next = l_item; - } - l_end = l_item; - } - return l_list; -} - -static size_t maxSize(size_t a, size_t b) -{ - return (a > b ? a : b); -} - -static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) -{ - switch(p_family) - { - case AF_INET: - return sizeof(struct sockaddr_in); - case AF_INET6: - return sizeof(struct sockaddr_in6); - case AF_PACKET: - return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); - default: - return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize); - } -} - -static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size) -{ - switch(p_family) - { - case AF_INET: - memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size); - break; - case AF_INET6: - memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size); - break; - case AF_PACKET: - memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size); - ((struct sockaddr_ll*)p_dest)->sll_halen = p_size; - break; - default: - memcpy(p_dest->sa_data, p_data, p_size); - break; - } - p_dest->sa_family = p_family; -} - -static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry) -{ - if(!*p_resultList) - { - *p_resultList = p_entry; - } - else - { - struct ifaddrs *l_cur = *p_resultList; - while(l_cur->ifa_next) - { - l_cur = l_cur->ifa_next; - } - l_cur->ifa_next = p_entry; - } -} - -static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList) -{ - struct ifaddrs *l_entry; - - char *l_index; - char *l_name; - char *l_addr; - char *l_data; - - struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr); - - size_t l_nameSize = 0; - size_t l_addrSize = 0; - size_t l_dataSize = 0; - - size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); - struct rtattr *l_rta; - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFLA_ADDRESS: - case IFLA_BROADCAST: - l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize)); - break; - case IFLA_IFNAME: - l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); - break; - case IFLA_STATS: - l_dataSize += NLMSG_ALIGN(l_rtaSize); - break; - default: - break; - } - } - - l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); - if (l_entry == NULL) - { - return -1; - } - memset(l_entry, 0, sizeof(struct ifaddrs)); - l_entry->ifa_name = ""; - - l_index = ((char *)l_entry) + sizeof(struct ifaddrs); - l_name = l_index + sizeof(int); - l_addr = l_name + l_nameSize; - l_data = l_addr + l_addrSize; - - /* Save the interface index so we can look it up when handling the - * addresses. - */ - memcpy(l_index, &l_info->ifi_index, sizeof(int)); - - l_entry->ifa_flags = l_info->ifi_flags; - - l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFLA_ADDRESS: - case IFLA_BROADCAST: - { - size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); - makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); - ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index; - ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type; - if(l_rta->rta_type == IFLA_ADDRESS) - { - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; - } - l_addr += NLMSG_ALIGN(l_addrLen); - break; - } - case IFLA_IFNAME: - strncpy(l_name, l_rtaData, l_rtaDataSize); - l_name[l_rtaDataSize] = '\0'; - l_entry->ifa_name = l_name; - break; - case IFLA_STATS: - memcpy(l_data, l_rtaData, l_rtaDataSize); - l_entry->ifa_data = l_data; - break; - default: - break; - } - } - - addToEnd(p_resultList, l_entry); - return 0; -} - -static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks) -{ - int l_num = 0; - struct ifaddrs *l_cur = *p_links; - while(l_cur && l_num < p_numLinks) - { - char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs); - int l_index; - memcpy(&l_index, l_indexPtr, sizeof(int)); - if(l_index == p_index) - { - return l_cur; - } - - l_cur = l_cur->ifa_next; - ++l_num; - } - return NULL; -} - -static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks) -{ - struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr); - struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks); - - size_t l_nameSize = 0; - size_t l_addrSize = 0; - - int l_addedNetmask = 0; - - size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); - struct rtattr *l_rta; - struct ifaddrs *l_entry; - - char *l_name; - char *l_addr; - - for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - if(l_info->ifa_family == AF_PACKET) - { - continue; - } - - switch(l_rta->rta_type) - { - case IFA_ADDRESS: - case IFA_LOCAL: - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) - { - /* Make room for netmask */ - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - l_addedNetmask = 1; - } - break; - case IFA_BROADCAST: - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - break; - case IFA_LABEL: - l_nameSize += NLMSG_ALIGN(l_rtaDataSize + 1); - break; - default: - break; - } - } - - l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); - if (l_entry == NULL) - { - return -1; - } - memset(l_entry, 0, sizeof(struct ifaddrs)); - l_entry->ifa_name = (l_interface ? l_interface->ifa_name : ""); - - l_name = ((char *)l_entry) + sizeof(struct ifaddrs); - l_addr = l_name + l_nameSize; - - l_entry->ifa_flags = l_info->ifa_flags; - if(l_interface) - { - l_entry->ifa_flags |= l_interface->ifa_flags; - } - - l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); - for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFA_ADDRESS: - case IFA_BROADCAST: - case IFA_LOCAL: - { - size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); - makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); - if(l_info->ifa_family == AF_INET6) - { - if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) - { - ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index; - } - } - - /* Apparently in a point-to-point network IFA_ADDRESS contains - * the dest address and IFA_LOCAL contains the local address - */ - if(l_rta->rta_type == IFA_ADDRESS) - { - if(l_entry->ifa_addr) - { - l_entry->ifa_dstaddr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - } - else if(l_rta->rta_type == IFA_LOCAL) - { - if(l_entry->ifa_addr) - { - l_entry->ifa_dstaddr = l_entry->ifa_addr; - } - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; - } - l_addr += NLMSG_ALIGN(l_addrLen); - break; - } - case IFA_LABEL: - strncpy(l_name, l_rtaData, l_rtaDataSize); - l_name[l_rtaDataSize] = '\0'; - l_entry->ifa_name = l_name; - break; - default: - break; - } - } - - if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) - { - unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); - unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen); - unsigned char l_mask[16] = {0}; - unsigned i; - for(i=0; i<(l_prefix/8); ++i) - { - l_mask[i] = 0xff; - } - if(l_prefix % 8) - { - l_mask[i] = 0xff << (8 - (l_prefix % 8)); - } - - makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8); - l_entry->ifa_netmask = (struct sockaddr *)l_addr; - } - - addToEnd(p_resultList, l_entry); - return 0; -} - -static int interpretLinks(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) -{ - - int l_numLinks = 0; - for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) - { - unsigned int l_nlsize = p_netlinkList->m_size; - struct nlmsghdr *l_hdr; - for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) - { - if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - break; - } - - if(l_hdr->nlmsg_type == RTM_NEWLINK) - { - if(interpretLink(l_hdr, p_resultList) == -1) - { - return -1; - } - ++l_numLinks; - } - } - } - return l_numLinks; -} - -static int interpretAddrs(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) -{ - for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) - { - unsigned int l_nlsize = p_netlinkList->m_size; - struct nlmsghdr *l_hdr; - for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) - { - if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - break; - } - - if(l_hdr->nlmsg_type == RTM_NEWADDR) - { - if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1) - { - return -1; - } - } - } - } - return 0; -} - -int getifaddrs(struct ifaddrs **ifap) -{ - int l_socket; - int l_result; - int l_numLinks; - pid_t l_pid; - NetlinkList *l_linkResults; - NetlinkList *l_addrResults; - - if(!ifap) - { - return -1; - } - *ifap = NULL; - - l_socket = netlink_socket(&l_pid); - if(l_socket < 0) - { - return -1; - } - - l_linkResults = getResultList(l_socket, RTM_GETLINK, l_pid); - if(!l_linkResults) - { - close(l_socket); - return -1; - } - - l_addrResults = getResultList(l_socket, RTM_GETADDR, l_pid); - if(!l_addrResults) - { - close(l_socket); - freeResultList(l_linkResults); - return -1; - } - - l_result = 0; - l_numLinks = interpretLinks(l_socket, l_pid, l_linkResults, ifap); - if(l_numLinks == -1 || interpretAddrs(l_socket, l_pid, l_addrResults, ifap, l_numLinks) == -1) - { - l_result = -1; - } - - freeResultList(l_linkResults); - freeResultList(l_addrResults); - close(l_socket); - return l_result; -} - -void freeifaddrs(struct ifaddrs *ifa) -{ - struct ifaddrs *l_cur; - while(ifa) - { - l_cur = ifa; - ifa = ifa->ifa_next; - uv__free(l_cur); - } -} diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c index 225f775..0793922 100644 --- a/Utilities/cmlibuv/src/unix/core.c +++ b/Utilities/cmlibuv/src/unix/core.c @@ -102,9 +102,9 @@ static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec)); -STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) == +STATIC_ASSERT(sizeof(((uv_buf_t*) 0)->base) == sizeof(((struct iovec*) 0)->iov_base)); -STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) == +STATIC_ASSERT(sizeof(((uv_buf_t*) 0)->len) == sizeof(((struct iovec*) 0)->iov_len)); STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base)); STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len)); diff --git a/Utilities/cmlibuv/src/unix/darwin.c b/Utilities/cmlibuv/src/unix/darwin.c index a7be0dd..62f04d3 100644 --- a/Utilities/cmlibuv/src/unix/darwin.c +++ b/Utilities/cmlibuv/src/unix/darwin.c @@ -280,14 +280,18 @@ static int uv__get_cpu_speed(uint64_t* speed) { NULL, 0); if (freq_ref) { - uint32_t freq; + const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref); CFIndex len = pCFDataGetLength(freq_ref); - CFRange range; - range.location = 0; - range.length = len; + if (len == 8) + memcpy(speed, freq_ref_ptr, 8); + else if (len == 4) { + uint32_t v; + memcpy(&v, freq_ref_ptr, 4); + *speed = v; + } else { + *speed = 0; + } - pCFDataGetBytes(freq_ref, range, (UInt8*)&freq); - *speed = freq; pCFRelease(freq_ref); pCFRelease(data); break; diff --git a/Utilities/cmlibuv/src/unix/dl.c b/Utilities/cmlibuv/src/unix/dl.c index fc1c052..80b3333 100644 --- a/Utilities/cmlibuv/src/unix/dl.c +++ b/Utilities/cmlibuv/src/unix/dl.c @@ -53,7 +53,7 @@ void uv_dlclose(uv_lib_t* lib) { int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { dlerror(); /* Reset error status. */ *ptr = dlsym(lib->handle, name); - return uv__dlerror(lib); + return *ptr ? 0 : uv__dlerror(lib); } diff --git a/Utilities/cmlibuv/src/unix/kqueue.c b/Utilities/cmlibuv/src/unix/kqueue.c index bf183d5..75e9110 100644 --- a/Utilities/cmlibuv/src/unix/kqueue.c +++ b/Utilities/cmlibuv/src/unix/kqueue.c @@ -326,6 +326,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (errno != ENOENT) abort(); } + if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP)) + revents |= UV__POLLRDHUP; } if (ev->filter == EV_OOBAND) { @@ -359,9 +361,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (ev->flags & EV_ERROR) revents |= POLLERR; - if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP)) - revents |= UV__POLLRDHUP; - if (revents == 0) continue; diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c index 8c9bbb7..7b041e6 100644 --- a/Utilities/cmlibuv/src/unix/linux-core.c +++ b/Utilities/cmlibuv/src/unix/linux-core.c @@ -45,6 +45,10 @@ #define HAVE_IFADDRS_H 1 +# if defined(__ANDROID_API__) && __ANDROID_API__ < 24 +# undef HAVE_IFADDRS_H +#endif + #ifdef __UCLIBC__ # if __UCLIBC_MAJOR__ < 0 && __UCLIBC_MINOR__ < 9 && __UCLIBC_SUBLEVEL__ < 32 # undef HAVE_IFADDRS_H @@ -52,11 +56,7 @@ #endif #ifdef HAVE_IFADDRS_H -# if defined(__ANDROID__) -# include "uv/android-ifaddrs.h" -# else -# include <ifaddrs.h> -# endif +# include <ifaddrs.h> # include <sys/socket.h> # include <net/ethernet.h> # include <netpacket/packet.h> @@ -788,7 +788,7 @@ uint64_t uv_get_free_memory(void) { struct sysinfo info; uint64_t rc; - rc = uv__read_proc_meminfo("MemFree:"); + rc = uv__read_proc_meminfo("MemAvailable:"); if (rc != 0) return rc; diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.c b/Utilities/cmlibuv/src/unix/os390-syscalls.c index c191553..a741127 100644 --- a/Utilities/cmlibuv/src/unix/os390-syscalls.c +++ b/Utilities/cmlibuv/src/unix/os390-syscalls.c @@ -136,6 +136,11 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { } +void uv__os390_cleanup(void) { + msgctl(uv_backend_fd(uv_default_loop()), IPC_RMID, NULL); +} + + static void init_message_queue(uv__os390_epoll* lst) { struct { long int header; diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.h b/Utilities/cmlibuv/src/unix/os390-syscalls.h index 7d59b75..9f50417 100644 --- a/Utilities/cmlibuv/src/unix/os390-syscalls.h +++ b/Utilities/cmlibuv/src/unix/os390-syscalls.h @@ -70,5 +70,6 @@ int sem_destroy(UV_PLATFORM_SEM_T* semid); int sem_post(UV_PLATFORM_SEM_T* semid); int sem_trywait(UV_PLATFORM_SEM_T* semid); int sem_wait(UV_PLATFORM_SEM_T* semid); +void uv__os390_cleanup(void); #endif /* UV_OS390_SYSCALL_H_ */ diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c index 4159cdc..52e2b9a 100644 --- a/Utilities/cmlibuv/src/unix/stream.c +++ b/Utilities/cmlibuv/src/unix/stream.c @@ -58,20 +58,6 @@ struct uv__stream_select_s { fd_set* swrite; size_t swrite_sz; }; - -/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite", - * EPROTOTYPE can be returned while trying to write to a socket that is - * shutting down. If we retry the write, we should get the expected EPIPE - * instead. - */ -# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE) -# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \ - (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \ - (errno == EMSGSIZE && send_handle != NULL)) -#else -# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR) -# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \ - (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) #endif /* defined(__APPLE__) */ static void uv__stream_connect(uv_stream_t*); @@ -866,19 +852,33 @@ static int uv__try_write(uv_stream_t* stream, do n = sendmsg(uv__stream_fd(stream), &msg, 0); - while (n == -1 && RETRY_ON_WRITE_ERROR(errno)); + while (n == -1 && errno == EINTR); } else { do n = uv__writev(uv__stream_fd(stream), iov, iovcnt); - while (n == -1 && RETRY_ON_WRITE_ERROR(errno)); + while (n == -1 && errno == EINTR); } if (n >= 0) return n; - if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle)) + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) return UV_EAGAIN; +#ifdef __APPLE__ + /* macOS versions 10.10 and 10.15 - and presumbaly 10.11 to 10.14, too - + * have a bug where a race condition causes the kernel to return EPROTOTYPE + * because the socket isn't fully constructed. It's probably the result of + * the peer closing the connection and that is why libuv translates it to + * ECONNRESET. Previously, libuv retried until the EPROTOTYPE error went + * away but some VPN software causes the same behavior except the error is + * permanent, not transient, turning the retry mechanism into an infinite + * loop. See https://github.com/libuv/libuv/pull/482. + */ + if (errno == EPROTOTYPE) + return UV_ECONNRESET; +#endif /* __APPLE__ */ + return UV__ERR(errno); } @@ -1010,7 +1010,6 @@ uv_handle_type uv__handle_type(int fd) { static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { stream->flags |= UV_HANDLE_READ_EOF; stream->flags &= ~UV_HANDLE_READING; - stream->flags &= ~UV_HANDLE_READABLE; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); @@ -1550,15 +1549,12 @@ int uv__read_start(uv_stream_t* stream, assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || stream->type == UV_TTY); - /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just - * expresses the desired state of the user. - */ + /* The UV_HANDLE_READING flag is irrelevant of the state of the stream - it + * just expresses the desired state of the user. */ stream->flags |= UV_HANDLE_READING; + stream->flags &= ~UV_HANDLE_READ_EOF; /* TODO: try to do the read inline? */ - /* TODO: keep track of tcp state. If we've gotten a EOF then we should - * not start the IO watcher. - */ assert(uv__stream_fd(stream) >= 0); assert(alloc_cb); diff --git a/Utilities/cmlibuv/src/unix/udp.c b/Utilities/cmlibuv/src/unix/udp.c index 71bfbf7..aee8d63 100644 --- a/Utilities/cmlibuv/src/unix/udp.c +++ b/Utilities/cmlibuv/src/unix/udp.c @@ -654,28 +654,71 @@ int uv__udp_connect(uv_udp_t* handle, return 0; } - +/* From https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + * Any of uv supported UNIXs kernel should be standardized, but the kernel + * implementation logic not same, let's use pseudocode to explain the udp + * disconnect behaviors: + * + * Predefined stubs for pseudocode: + * 1. sodisconnect: The function to perform the real udp disconnect + * 2. pru_connect: The function to perform the real udp connect + * 3. so: The kernel object match with socket fd + * 4. addr: The sockaddr parameter from user space + * + * BSDs: + * if(sodisconnect(so) == 0) { // udp disconnect succeed + * if (addr->sa_len != so->addr->sa_len) return EINVAL; + * if (addr->sa_family != so->addr->sa_family) return EAFNOSUPPORT; + * pru_connect(so); + * } + * else return EISCONN; + * + * z/OS (same with Windows): + * if(addr->sa_len < so->addr->sa_len) return EINVAL; + * if (addr->sa_family == AF_UNSPEC) sodisconnect(so); + * + * AIX: + * if(addr->sa_len != sizeof(struct sockaddr)) return EINVAL; // ignore ip proto version + * if (addr->sa_family == AF_UNSPEC) sodisconnect(so); + * + * Linux,Others: + * if(addr->sa_len < sizeof(struct sockaddr)) return EINVAL; + * if (addr->sa_family == AF_UNSPEC) sodisconnect(so); + */ int uv__udp_disconnect(uv_udp_t* handle) { int r; +#if defined(__MVS__) + struct sockaddr_storage addr; +#else struct sockaddr addr; +#endif memset(&addr, 0, sizeof(addr)); - + +#if defined(__MVS__) + addr.ss_family = AF_UNSPEC; +#else addr.sa_family = AF_UNSPEC; - +#endif + do { errno = 0; - r = connect(handle->io_watcher.fd, &addr, sizeof(addr)); + r = connect(handle->io_watcher.fd, (struct sockaddr*) &addr, sizeof(addr)); } while (r == -1 && errno == EINTR); - if (r == -1 && errno != EAFNOSUPPORT) + if (r == -1) { +#if defined(BSD) /* The macro BSD is from sys/param.h */ + if (errno != EAFNOSUPPORT && errno != EINVAL) + return UV__ERR(errno); +#else return UV__ERR(errno); +#endif + } handle->flags &= ~UV_HANDLE_UDP_CONNECTED; return 0; } - int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], diff --git a/Utilities/cmlibuv/src/uv-common.c b/Utilities/cmlibuv/src/uv-common.c index 8bce62e..e88347a 100644 --- a/Utilities/cmlibuv/src/uv-common.c +++ b/Utilities/cmlibuv/src/uv-common.c @@ -275,6 +275,20 @@ int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) { } +int uv_ip_name(const struct sockaddr *src, char *dst, size_t size) { + switch (src->sa_family) { + case AF_INET: + return uv_inet_ntop(AF_INET, &((struct sockaddr_in *)src)->sin_addr, + dst, size); + case AF_INET6: + return uv_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)src)->sin6_addr, + dst, size); + default: + return UV_EAFNOSUPPORT; + } +} + + int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags) { @@ -889,7 +903,12 @@ void uv_library_shutdown(void) { uv__process_title_cleanup(); uv__signal_cleanup(); +#ifdef __MVS__ + /* TODO(itodorov) - zos: revisit when Woz compiler is available. */ + uv__os390_cleanup(); +#else uv__threadpool_cleanup(); +#endif uv__store_relaxed(&was_shutdown, 1); } diff --git a/Utilities/cmlibuv/src/win/pipe.c b/Utilities/cmlibuv/src/win/pipe.c index 912aed9..984b766 100644 --- a/Utilities/cmlibuv/src/win/pipe.c +++ b/Utilities/cmlibuv/src/win/pipe.c @@ -1796,7 +1796,6 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle, * it. */ eof_timer_destroy(handle); - handle->flags &= ~UV_HANDLE_READABLE; uv_read_stop((uv_stream_t*) handle); handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf); diff --git a/Utilities/cmlibuv/src/win/tcp.c b/Utilities/cmlibuv/src/win/tcp.c index cf2dbd8..6ca11e0 100644 --- a/Utilities/cmlibuv/src/win/tcp.c +++ b/Utilities/cmlibuv/src/win/tcp.c @@ -1044,7 +1044,6 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); } - handle->flags &= ~UV_HANDLE_READABLE; buf.base = 0; buf.len = 0; @@ -1081,7 +1080,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, } } else { /* Connection closed */ - handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); + handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); @@ -1651,7 +1650,7 @@ int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int f err = WSAGetLastError(); if (err == ERROR_IO_PENDING) { /* Result should complete immediately, since we already called connect, - * but emperically, we sometimes have to poll the kernel a couple times + * but empirically, we sometimes have to poll the kernel a couple times * until it notices that. */ while (!WSAGetOverlappedResult(client1, &overlap, &bytes, FALSE, &flags)) { err = WSAGetLastError(); diff --git a/Utilities/cmlibuv/src/win/thread.c b/Utilities/cmlibuv/src/win/thread.c index 89c53ad..ea5dc04 100644 --- a/Utilities/cmlibuv/src/win/thread.c +++ b/Utilities/cmlibuv/src/win/thread.c @@ -103,7 +103,7 @@ static UINT __stdcall uv__thread_start(void* arg) { uv__free(ctx_p); uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - uv_key_set(&uv__current_thread_key, (void*) ctx.self); + uv_key_set(&uv__current_thread_key, ctx.self); ctx.entry(ctx.arg); @@ -183,7 +183,18 @@ int uv_thread_create_ex(uv_thread_t* tid, uv_thread_t uv_thread_self(void) { uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - return (uv_thread_t) uv_key_get(&uv__current_thread_key); + uv_thread_t key = uv_key_get(&uv__current_thread_key); + if (key == NULL) { + /* If the thread wasn't started by uv_thread_create (such as the main + * thread), we assign an id to it now. */ + if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &key, 0, + FALSE, DUPLICATE_SAME_ACCESS)) { + uv_fatal_error(GetLastError(), "DuplicateHandle"); + } + uv_key_set(&uv__current_thread_key, key); + } + return key; } @@ -237,113 +248,60 @@ void uv_mutex_unlock(uv_mutex_t* mutex) { LeaveCriticalSection(mutex); } +/* Ensure that the ABI for this type remains stable in v1.x */ +#ifdef _WIN64 +STATIC_ASSERT(sizeof(uv_rwlock_t) == 80); +#else +STATIC_ASSERT(sizeof(uv_rwlock_t) == 48); +#endif int uv_rwlock_init(uv_rwlock_t* rwlock) { - /* Initialize the semaphore that acts as the write lock. */ - HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL); - if (handle == NULL) - return uv_translate_sys_error(GetLastError()); - rwlock->state_.write_semaphore_ = handle; - - /* Initialize the critical section protecting the reader count. */ - InitializeCriticalSection(&rwlock->state_.num_readers_lock_); - - /* Initialize the reader count. */ - rwlock->state_.num_readers_ = 0; + memset(rwlock, 0, sizeof(*rwlock)); + InitializeSRWLock(&rwlock->read_write_lock_); return 0; } void uv_rwlock_destroy(uv_rwlock_t* rwlock) { - DeleteCriticalSection(&rwlock->state_.num_readers_lock_); - CloseHandle(rwlock->state_.write_semaphore_); + /* SRWLock does not need explicit destruction so long as there are no waiting threads + See: https://docs.microsoft.com/windows/win32/api/synchapi/nf-synchapi-initializesrwlock#remarks */ } void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { - /* Acquire the lock that protects the reader count. */ - EnterCriticalSection(&rwlock->state_.num_readers_lock_); - - /* Increase the reader count, and lock for write if this is the first - * reader. - */ - if (++rwlock->state_.num_readers_ == 1) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); - if (r != WAIT_OBJECT_0) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); - } - - /* Release the lock that protects the reader count. */ - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); + AcquireSRWLockShared(&rwlock->read_write_lock_); } int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { - int err; - - if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_)) + if (!TryAcquireSRWLockShared(&rwlock->read_write_lock_)) return UV_EBUSY; - err = 0; - - if (rwlock->state_.num_readers_ == 0) { - /* Currently there are no other readers, which means that the write lock - * needs to be acquired. - */ - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); - if (r == WAIT_OBJECT_0) - rwlock->state_.num_readers_++; - else if (r == WAIT_TIMEOUT) - err = UV_EBUSY; - else if (r == WAIT_FAILED) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); - - } else { - /* The write lock has already been acquired because there are other - * active readers. - */ - rwlock->state_.num_readers_++; - } - - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); - return err; + return 0; } void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { - EnterCriticalSection(&rwlock->state_.num_readers_lock_); - - if (--rwlock->state_.num_readers_ == 0) { - if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) - uv_fatal_error(GetLastError(), "ReleaseSemaphore"); - } - - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); + ReleaseSRWLockShared(&rwlock->read_write_lock_); } void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); - if (r != WAIT_OBJECT_0) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); + AcquireSRWLockExclusive(&rwlock->read_write_lock_); } int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); - if (r == WAIT_OBJECT_0) - return 0; - else if (r == WAIT_TIMEOUT) + if (!TryAcquireSRWLockExclusive(&rwlock->read_write_lock_)) return UV_EBUSY; - else - uv_fatal_error(GetLastError(), "WaitForSingleObject"); + + return 0; } void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { - if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) - uv_fatal_error(GetLastError(), "ReleaseSemaphore"); + ReleaseSRWLockExclusive(&rwlock->read_write_lock_); } diff --git a/Utilities/cmlibuv/src/win/udp.c b/Utilities/cmlibuv/src/win/udp.c index 3043f2d..7b5efa2 100644 --- a/Utilities/cmlibuv/src/win/udp.c +++ b/Utilities/cmlibuv/src/win/udp.c @@ -1083,11 +1083,11 @@ int uv__udp_connect(uv_udp_t* handle, int uv__udp_disconnect(uv_udp_t* handle) { int err; - struct sockaddr addr; + struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); - err = connect(handle->socket, &addr, sizeof(addr)); + err = connect(handle->socket, (struct sockaddr*) &addr, sizeof(addr)); if (err) return uv_translate_sys_error(WSAGetLastError()); |