diff --git a/gating.yaml b/gating.yaml index b6a718a..9be3596 100644 --- a/gating.yaml +++ b/gating.yaml @@ -12,4 +12,3 @@ product_versions: decision_context: osci_compose_gate rules: - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional} - - !PassingTestCaseRule {test_case_name: baseos-qe.brew-build.scratch-build.validation} diff --git a/glibc-c-utf8-locale-1.patch b/glibc-c-utf8-locale-1.patch new file mode 100644 index 0000000..3b80064 --- /dev/null +++ b/glibc-c-utf8-locale-1.patch @@ -0,0 +1,980 @@ +commit f5117c6504888fab5423282a4607c552b90fd3f9 +Author: Carlos O'Donell +Date: Thu Jul 29 22:45:39 2021 -0400 + + Add 'codepoint_collation' support for LC_COLLATE. + + Support a new directive 'codepoint_collation' in the LC_COLLATE + section of a locale source file. This new directive causes all + collation rules to be dropped and instead STRCMP (strcmp or + wcscmp) is used for collation of the input character set. This + is required to allow for a C.UTF-8 that contains zero collation + rules (minimal size) and sorts using code point sorting. + + To date the only implementation of a locale with zero collation + rules is the C/POSIX locale. The C/POSIX locale provides + identity tables for _NL_COLLATE_COLLSEQMB and + _NL_COLLATE_COLLSEQWC that map to ASCII even though it has zero + rules. This has lead to existing fnmatch, regexec, and regcomp + implementations that require these tables. It is not correct + to use these tables when nrules == 0, but the conservative fix + is to provide these tables when nrules == 0. This assures that + existing static applications using a new C.UTF-8 locale with + 'codepoint_collation' at least have functional range expressions + with ASCII e.g. [0-9] or [a-z]. Such static applications would + not have the fixes to fnmatch, regexec and regcomp that avoid + the use of the tables when nrules == 0. Future fixes to fnmatch, + regexec, and regcomp would allow range expressions to use the + full set of code points for such ranges. + + Tested on x86_64 and i686 without regression. + + Reviewed-by: Florian Weimer + +diff --git a/locale/C-collate-seq.c b/locale/C-collate-seq.c +new file mode 100644 +index 0000000000000000..4fb82cb8357936b6 +--- /dev/null ++++ b/locale/C-collate-seq.c +@@ -0,0 +1,100 @@ ++/* Copyright (C) 1995-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++static const char collseqmb[] = ++{ ++ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', ++ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', ++ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', ++ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', ++ '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', ++ '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', ++ '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', ++ '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', ++ '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', ++ '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', ++ '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', ++ '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', ++ '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', ++ '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', ++ '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', ++ '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', ++ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', ++ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', ++ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', ++ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', ++ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', ++ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', ++ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', ++ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', ++ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', ++ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', ++ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', ++ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', ++ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', ++ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', ++ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', ++ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' ++}; ++ ++/* This table must be 256 bytes in size. We index bytes into the ++ table to find the collation sequence. */ ++_Static_assert (sizeof (collseqmb) == 256); ++ ++static const uint32_t collseqwc[] = ++{ ++ 8, 1, 8, 0x0, 0xff, ++ /* 1st-level table */ ++ 6 * sizeof (uint32_t), ++ /* 2nd-level table */ ++ 7 * sizeof (uint32_t), ++ /* 3rd-level table */ ++ L'\x00', L'\x01', L'\x02', L'\x03', L'\x04', L'\x05', L'\x06', L'\x07', ++ L'\x08', L'\x09', L'\x0a', L'\x0b', L'\x0c', L'\x0d', L'\x0e', L'\x0f', ++ L'\x10', L'\x11', L'\x12', L'\x13', L'\x14', L'\x15', L'\x16', L'\x17', ++ L'\x18', L'\x19', L'\x1a', L'\x1b', L'\x1c', L'\x1d', L'\x1e', L'\x1f', ++ L'\x20', L'\x21', L'\x22', L'\x23', L'\x24', L'\x25', L'\x26', L'\x27', ++ L'\x28', L'\x29', L'\x2a', L'\x2b', L'\x2c', L'\x2d', L'\x2e', L'\x2f', ++ L'\x30', L'\x31', L'\x32', L'\x33', L'\x34', L'\x35', L'\x36', L'\x37', ++ L'\x38', L'\x39', L'\x3a', L'\x3b', L'\x3c', L'\x3d', L'\x3e', L'\x3f', ++ L'\x40', L'\x41', L'\x42', L'\x43', L'\x44', L'\x45', L'\x46', L'\x47', ++ L'\x48', L'\x49', L'\x4a', L'\x4b', L'\x4c', L'\x4d', L'\x4e', L'\x4f', ++ L'\x50', L'\x51', L'\x52', L'\x53', L'\x54', L'\x55', L'\x56', L'\x57', ++ L'\x58', L'\x59', L'\x5a', L'\x5b', L'\x5c', L'\x5d', L'\x5e', L'\x5f', ++ L'\x60', L'\x61', L'\x62', L'\x63', L'\x64', L'\x65', L'\x66', L'\x67', ++ L'\x68', L'\x69', L'\x6a', L'\x6b', L'\x6c', L'\x6d', L'\x6e', L'\x6f', ++ L'\x70', L'\x71', L'\x72', L'\x73', L'\x74', L'\x75', L'\x76', L'\x77', ++ L'\x78', L'\x79', L'\x7a', L'\x7b', L'\x7c', L'\x7d', L'\x7e', L'\x7f', ++ L'\x80', L'\x81', L'\x82', L'\x83', L'\x84', L'\x85', L'\x86', L'\x87', ++ L'\x88', L'\x89', L'\x8a', L'\x8b', L'\x8c', L'\x8d', L'\x8e', L'\x8f', ++ L'\x90', L'\x91', L'\x92', L'\x93', L'\x94', L'\x95', L'\x96', L'\x97', ++ L'\x98', L'\x99', L'\x9a', L'\x9b', L'\x9c', L'\x9d', L'\x9e', L'\x9f', ++ L'\xa0', L'\xa1', L'\xa2', L'\xa3', L'\xa4', L'\xa5', L'\xa6', L'\xa7', ++ L'\xa8', L'\xa9', L'\xaa', L'\xab', L'\xac', L'\xad', L'\xae', L'\xaf', ++ L'\xb0', L'\xb1', L'\xb2', L'\xb3', L'\xb4', L'\xb5', L'\xb6', L'\xb7', ++ L'\xb8', L'\xb9', L'\xba', L'\xbb', L'\xbc', L'\xbd', L'\xbe', L'\xbf', ++ L'\xc0', L'\xc1', L'\xc2', L'\xc3', L'\xc4', L'\xc5', L'\xc6', L'\xc7', ++ L'\xc8', L'\xc9', L'\xca', L'\xcb', L'\xcc', L'\xcd', L'\xce', L'\xcf', ++ L'\xd0', L'\xd1', L'\xd2', L'\xd3', L'\xd4', L'\xd5', L'\xd6', L'\xd7', ++ L'\xd8', L'\xd9', L'\xda', L'\xdb', L'\xdc', L'\xdd', L'\xde', L'\xdf', ++ L'\xe0', L'\xe1', L'\xe2', L'\xe3', L'\xe4', L'\xe5', L'\xe6', L'\xe7', ++ L'\xe8', L'\xe9', L'\xea', L'\xeb', L'\xec', L'\xed', L'\xee', L'\xef', ++ L'\xf0', L'\xf1', L'\xf2', L'\xf3', L'\xf4', L'\xf5', L'\xf6', L'\xf7', ++ L'\xf8', L'\xf9', L'\xfa', L'\xfb', L'\xfc', L'\xfd', L'\xfe', L'\xff' ++}; +diff --git a/locale/C-collate.c b/locale/C-collate.c +index 76d9373683314943..120ce0a40aeb9a0f 100644 +--- a/locale/C-collate.c ++++ b/locale/C-collate.c +@@ -20,83 +20,7 @@ + #include + #include "localeinfo.h" + +-static const char collseqmb[] = +-{ +- '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', +- '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', +- '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', +- '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', +- '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', +- '\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', +- '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', +- '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', +- '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', +- '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', +- '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', +- '\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f', +- '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', +- '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', +- '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', +- '\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f', +- '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', +- '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', +- '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', +- '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', +- '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', +- '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', +- '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', +- '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', +- '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', +- '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', +- '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', +- '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', +- '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', +- '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', +- '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', +- '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' +-}; +- +-static const uint32_t collseqwc[] = +-{ +- 8, 1, 8, 0x0, 0xff, +- /* 1st-level table */ +- 6 * sizeof (uint32_t), +- /* 2nd-level table */ +- 7 * sizeof (uint32_t), +- /* 3rd-level table */ +- L'\x00', L'\x01', L'\x02', L'\x03', L'\x04', L'\x05', L'\x06', L'\x07', +- L'\x08', L'\x09', L'\x0a', L'\x0b', L'\x0c', L'\x0d', L'\x0e', L'\x0f', +- L'\x10', L'\x11', L'\x12', L'\x13', L'\x14', L'\x15', L'\x16', L'\x17', +- L'\x18', L'\x19', L'\x1a', L'\x1b', L'\x1c', L'\x1d', L'\x1e', L'\x1f', +- L'\x20', L'\x21', L'\x22', L'\x23', L'\x24', L'\x25', L'\x26', L'\x27', +- L'\x28', L'\x29', L'\x2a', L'\x2b', L'\x2c', L'\x2d', L'\x2e', L'\x2f', +- L'\x30', L'\x31', L'\x32', L'\x33', L'\x34', L'\x35', L'\x36', L'\x37', +- L'\x38', L'\x39', L'\x3a', L'\x3b', L'\x3c', L'\x3d', L'\x3e', L'\x3f', +- L'\x40', L'\x41', L'\x42', L'\x43', L'\x44', L'\x45', L'\x46', L'\x47', +- L'\x48', L'\x49', L'\x4a', L'\x4b', L'\x4c', L'\x4d', L'\x4e', L'\x4f', +- L'\x50', L'\x51', L'\x52', L'\x53', L'\x54', L'\x55', L'\x56', L'\x57', +- L'\x58', L'\x59', L'\x5a', L'\x5b', L'\x5c', L'\x5d', L'\x5e', L'\x5f', +- L'\x60', L'\x61', L'\x62', L'\x63', L'\x64', L'\x65', L'\x66', L'\x67', +- L'\x68', L'\x69', L'\x6a', L'\x6b', L'\x6c', L'\x6d', L'\x6e', L'\x6f', +- L'\x70', L'\x71', L'\x72', L'\x73', L'\x74', L'\x75', L'\x76', L'\x77', +- L'\x78', L'\x79', L'\x7a', L'\x7b', L'\x7c', L'\x7d', L'\x7e', L'\x7f', +- L'\x80', L'\x81', L'\x82', L'\x83', L'\x84', L'\x85', L'\x86', L'\x87', +- L'\x88', L'\x89', L'\x8a', L'\x8b', L'\x8c', L'\x8d', L'\x8e', L'\x8f', +- L'\x90', L'\x91', L'\x92', L'\x93', L'\x94', L'\x95', L'\x96', L'\x97', +- L'\x98', L'\x99', L'\x9a', L'\x9b', L'\x9c', L'\x9d', L'\x9e', L'\x9f', +- L'\xa0', L'\xa1', L'\xa2', L'\xa3', L'\xa4', L'\xa5', L'\xa6', L'\xa7', +- L'\xa8', L'\xa9', L'\xaa', L'\xab', L'\xac', L'\xad', L'\xae', L'\xaf', +- L'\xb0', L'\xb1', L'\xb2', L'\xb3', L'\xb4', L'\xb5', L'\xb6', L'\xb7', +- L'\xb8', L'\xb9', L'\xba', L'\xbb', L'\xbc', L'\xbd', L'\xbe', L'\xbf', +- L'\xc0', L'\xc1', L'\xc2', L'\xc3', L'\xc4', L'\xc5', L'\xc6', L'\xc7', +- L'\xc8', L'\xc9', L'\xca', L'\xcb', L'\xcc', L'\xcd', L'\xce', L'\xcf', +- L'\xd0', L'\xd1', L'\xd2', L'\xd3', L'\xd4', L'\xd5', L'\xd6', L'\xd7', +- L'\xd8', L'\xd9', L'\xda', L'\xdb', L'\xdc', L'\xdd', L'\xde', L'\xdf', +- L'\xe0', L'\xe1', L'\xe2', L'\xe3', L'\xe4', L'\xe5', L'\xe6', L'\xe7', +- L'\xe8', L'\xe9', L'\xea', L'\xeb', L'\xec', L'\xed', L'\xee', L'\xef', +- L'\xf0', L'\xf1', L'\xf2', L'\xf3', L'\xf4', L'\xf5', L'\xf6', L'\xf7', +- L'\xf8', L'\xf9', L'\xfa', L'\xfb', L'\xfc', L'\xfd', L'\xfe', L'\xff' +-}; ++#include "C-collate-seq.c" + + const struct __locale_data _nl_C_LC_COLLATE attribute_hidden = + { +diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c +index b6406b775d3a81ad..0f314e40c4305dea 100644 +--- a/locale/programs/ld-collate.c ++++ b/locale/programs/ld-collate.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "localedef.h" + #include "charmap.h" +@@ -195,6 +196,9 @@ struct name_list + /* The real definition of the struct for the LC_COLLATE locale. */ + struct locale_collate_t + { ++ /* Does the locale use code points to compare the encoding? */ ++ bool codepoint_collation; ++ + int col_weight_max; + int cur_weight_max; + +@@ -1510,6 +1514,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale, + obstack_init (&collate->mempool); + + collate->col_weight_max = -1; ++ collate->codepoint_collation = false; + } + else + /* Reuse the copy_locale's data structures. */ +@@ -1568,6 +1573,10 @@ collate_finish (struct localedef_t *locale, const struct charmap_t *charmap) + return; + } + ++ /* No data required. */ ++ if (collate->codepoint_collation) ++ return; ++ + /* If this assertion is hit change the type in `element_t'. */ + assert (nrules <= sizeof (runp->used_in_level) * 8); + +@@ -2092,6 +2101,10 @@ add_to_tablewc (uint32_t ch, struct element_t *runp) + } + } + ++/* Include the C locale identity tables for _NL_COLLATE_COLLSEQMB and ++ _NL_COLLATE_COLLSEQWC. */ ++#include "C-collate-seq.c" ++ + void + collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + const char *output_path) +@@ -2115,7 +2128,7 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + add_locale_uint32 (&file, nrules); + + /* If we have no LC_COLLATE data emit only the number of rules as zero. */ +- if (collate == NULL) ++ if (collate == NULL || collate->codepoint_collation) + { + size_t idx; + for (idx = 1; idx < nelems; idx++) +@@ -2123,6 +2136,17 @@ collate_output (struct localedef_t *locale, const struct charmap_t *charmap, + /* The words have to be handled specially. */ + if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB)) + add_locale_uint32 (&file, 0); ++ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_CODESET) ++ && collate != NULL) ++ /* A valid LC_COLLATE must have a code set name. */ ++ add_locale_string (&file, charmap->code_set_name); ++ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB) ++ && collate != NULL) ++ add_locale_raw_data (&file, collseqmb, sizeof (collseqmb)); ++ else if (idx == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC) ++ && collate != NULL) ++ add_locale_uint32_array (&file, collseqwc, ++ array_length (collseqwc)); + else + add_locale_empty (&file); + } +@@ -2672,6 +2696,10 @@ collate_read (struct linereader *ldfile, struct localedef_t *result, + + switch (nowtok) + { ++ case tok_codepoint_collation: ++ collate->codepoint_collation = true; ++ break; ++ + case tok_copy: + /* Allow copying other locales. */ + now = lr_token (ldfile, charmap, result, NULL, verbose); +@@ -3742,9 +3770,11 @@ error while adding equivalent collating symbol")); + /* Next we assume `LC_COLLATE'. */ + if (!ignore_content) + { +- if (state == 0 && copy_locale == NULL) ++ if (state == 0 ++ && copy_locale == NULL ++ && !collate->codepoint_collation) + /* We must either see a copy statement or have +- ordering values. */ ++ ordering values, or codepoint_collation. */ + lr_error (ldfile, + _("%s: empty category description not allowed"), + "LC_COLLATE"); +diff --git a/locale/programs/locfile-kw.gperf b/locale/programs/locfile-kw.gperf +index bcded15ddb4c44bb..2e59eb9ac014134b 100644 +--- a/locale/programs/locfile-kw.gperf ++++ b/locale/programs/locfile-kw.gperf +@@ -54,6 +54,7 @@ translit_end, tok_translit_end, 0 + translit_ignore, tok_translit_ignore, 0 + default_missing, tok_default_missing, 0 + LC_COLLATE, tok_lc_collate, 0 ++codepoint_collation, tok_codepoint_collation, 0 + coll_weight_max, tok_coll_weight_max, 0 + section-symbol, tok_section_symbol, 0 + collating-element, tok_collating_element, 0 +diff --git a/locale/programs/locfile-kw.h b/locale/programs/locfile-kw.h +index bc1cb8f0845852ad..fe6335692bd422cd 100644 +--- a/locale/programs/locfile-kw.h ++++ b/locale/programs/locfile-kw.h +@@ -54,7 +54,7 @@ + #line 24 "locfile-kw.gperf" + struct keyword_t ; + +-#define TOTAL_KEYWORDS 178 ++#define TOTAL_KEYWORDS 179 + #define MIN_WORD_LENGTH 3 + #define MAX_WORD_LENGTH 22 + #define MIN_HASH_VALUE 3 +@@ -134,92 +134,92 @@ locfile_hash (register const char *str, register size_t len) + #line 31 "locfile-kw.gperf" + {"END", tok_end, 0}, + {""}, {""}, +-#line 70 "locfile-kw.gperf" ++#line 71 "locfile-kw.gperf" + {"IGNORE", tok_ignore, 0}, +-#line 129 "locfile-kw.gperf" ++#line 130 "locfile-kw.gperf" + {"LC_TIME", tok_lc_time, 0}, + #line 30 "locfile-kw.gperf" + {"LC_CTYPE", tok_lc_ctype, 0}, + {""}, +-#line 168 "locfile-kw.gperf" ++#line 169 "locfile-kw.gperf" + {"LC_ADDRESS", tok_lc_address, 0}, +-#line 153 "locfile-kw.gperf" ++#line 154 "locfile-kw.gperf" + {"LC_MESSAGES", tok_lc_messages, 0}, +-#line 161 "locfile-kw.gperf" ++#line 162 "locfile-kw.gperf" + {"LC_NAME", tok_lc_name, 0}, +-#line 158 "locfile-kw.gperf" ++#line 159 "locfile-kw.gperf" + {"LC_PAPER", tok_lc_paper, 0}, +-#line 186 "locfile-kw.gperf" ++#line 187 "locfile-kw.gperf" + {"LC_MEASUREMENT", tok_lc_measurement, 0}, + #line 56 "locfile-kw.gperf" + {"LC_COLLATE", tok_lc_collate, 0}, + {""}, +-#line 188 "locfile-kw.gperf" ++#line 189 "locfile-kw.gperf" + {"LC_IDENTIFICATION", tok_lc_identification, 0}, +-#line 201 "locfile-kw.gperf" ++#line 202 "locfile-kw.gperf" + {"revision", tok_revision, 0}, +-#line 69 "locfile-kw.gperf" ++#line 70 "locfile-kw.gperf" + {"UNDEFINED", tok_undefined, 0}, +-#line 125 "locfile-kw.gperf" ++#line 126 "locfile-kw.gperf" + {"LC_NUMERIC", tok_lc_numeric, 0}, +-#line 82 "locfile-kw.gperf" ++#line 83 "locfile-kw.gperf" + {"LC_MONETARY", tok_lc_monetary, 0}, +-#line 181 "locfile-kw.gperf" ++#line 182 "locfile-kw.gperf" + {"LC_TELEPHONE", tok_lc_telephone, 0}, + {""}, {""}, {""}, +-#line 75 "locfile-kw.gperf" ++#line 76 "locfile-kw.gperf" + {"define", tok_define, 0}, +-#line 154 "locfile-kw.gperf" ++#line 155 "locfile-kw.gperf" + {"yesexpr", tok_yesexpr, 0}, +-#line 141 "locfile-kw.gperf" ++#line 142 "locfile-kw.gperf" + {"era_year", tok_era_year, 0}, + {""}, + #line 54 "locfile-kw.gperf" + {"translit_ignore", tok_translit_ignore, 0}, +-#line 156 "locfile-kw.gperf" ++#line 157 "locfile-kw.gperf" + {"yesstr", tok_yesstr, 0}, + {""}, +-#line 89 "locfile-kw.gperf" ++#line 90 "locfile-kw.gperf" + {"negative_sign", tok_negative_sign, 0}, + {""}, +-#line 137 "locfile-kw.gperf" ++#line 138 "locfile-kw.gperf" + {"t_fmt", tok_t_fmt, 0}, +-#line 159 "locfile-kw.gperf" ++#line 160 "locfile-kw.gperf" + {"height", tok_height, 0}, + {""}, {""}, + #line 52 "locfile-kw.gperf" + {"translit_start", tok_translit_start, 0}, +-#line 136 "locfile-kw.gperf" ++#line 137 "locfile-kw.gperf" + {"d_fmt", tok_d_fmt, 0}, + {""}, + #line 53 "locfile-kw.gperf" + {"translit_end", tok_translit_end, 0}, +-#line 94 "locfile-kw.gperf" ++#line 95 "locfile-kw.gperf" + {"n_cs_precedes", tok_n_cs_precedes, 0}, +-#line 144 "locfile-kw.gperf" ++#line 145 "locfile-kw.gperf" + {"era_t_fmt", tok_era_t_fmt, 0}, + #line 39 "locfile-kw.gperf" + {"space", tok_space, 0}, +-#line 72 "locfile-kw.gperf" +- {"reorder-end", tok_reorder_end, 0}, + #line 73 "locfile-kw.gperf" ++ {"reorder-end", tok_reorder_end, 0}, ++#line 74 "locfile-kw.gperf" + {"reorder-sections-after", tok_reorder_sections_after, 0}, + {""}, +-#line 142 "locfile-kw.gperf" ++#line 143 "locfile-kw.gperf" + {"era_d_fmt", tok_era_d_fmt, 0}, +-#line 189 "locfile-kw.gperf" ++#line 190 "locfile-kw.gperf" + {"title", tok_title, 0}, + {""}, {""}, +-#line 149 "locfile-kw.gperf" ++#line 150 "locfile-kw.gperf" + {"timezone", tok_timezone, 0}, + {""}, +-#line 74 "locfile-kw.gperf" ++#line 75 "locfile-kw.gperf" + {"reorder-sections-end", tok_reorder_sections_end, 0}, + {""}, {""}, {""}, +-#line 95 "locfile-kw.gperf" ++#line 96 "locfile-kw.gperf" + {"n_sep_by_space", tok_n_sep_by_space, 0}, + {""}, {""}, +-#line 100 "locfile-kw.gperf" ++#line 101 "locfile-kw.gperf" + {"int_n_cs_precedes", tok_int_n_cs_precedes, 0}, + {""}, {""}, {""}, + #line 26 "locfile-kw.gperf" +@@ -233,147 +233,147 @@ locfile_hash (register const char *str, register size_t len) + {"print", tok_print, 0}, + #line 44 "locfile-kw.gperf" + {"xdigit", tok_xdigit, 0}, +-#line 110 "locfile-kw.gperf" ++#line 111 "locfile-kw.gperf" + {"duo_n_cs_precedes", tok_duo_n_cs_precedes, 0}, +-#line 127 "locfile-kw.gperf" ++#line 128 "locfile-kw.gperf" + {"thousands_sep", tok_thousands_sep, 0}, +-#line 197 "locfile-kw.gperf" ++#line 198 "locfile-kw.gperf" + {"territory", tok_territory, 0}, + #line 36 "locfile-kw.gperf" + {"digit", tok_digit, 0}, + {""}, {""}, +-#line 92 "locfile-kw.gperf" ++#line 93 "locfile-kw.gperf" + {"p_cs_precedes", tok_p_cs_precedes, 0}, + {""}, {""}, +-#line 62 "locfile-kw.gperf" ++#line 63 "locfile-kw.gperf" + {"script", tok_script, 0}, + #line 29 "locfile-kw.gperf" + {"include", tok_include, 0}, + {""}, +-#line 78 "locfile-kw.gperf" ++#line 79 "locfile-kw.gperf" + {"else", tok_else, 0}, +-#line 184 "locfile-kw.gperf" ++#line 185 "locfile-kw.gperf" + {"int_select", tok_int_select, 0}, + {""}, {""}, {""}, +-#line 132 "locfile-kw.gperf" ++#line 133 "locfile-kw.gperf" + {"week", tok_week, 0}, + #line 33 "locfile-kw.gperf" + {"upper", tok_upper, 0}, + {""}, {""}, +-#line 194 "locfile-kw.gperf" ++#line 195 "locfile-kw.gperf" + {"tel", tok_tel, 0}, +-#line 93 "locfile-kw.gperf" ++#line 94 "locfile-kw.gperf" + {"p_sep_by_space", tok_p_sep_by_space, 0}, +-#line 160 "locfile-kw.gperf" ++#line 161 "locfile-kw.gperf" + {"width", tok_width, 0}, + {""}, +-#line 98 "locfile-kw.gperf" ++#line 99 "locfile-kw.gperf" + {"int_p_cs_precedes", tok_int_p_cs_precedes, 0}, + {""}, {""}, + #line 41 "locfile-kw.gperf" + {"punct", tok_punct, 0}, + {""}, {""}, +-#line 101 "locfile-kw.gperf" ++#line 102 "locfile-kw.gperf" + {"int_n_sep_by_space", tok_int_n_sep_by_space, 0}, + {""}, {""}, {""}, +-#line 108 "locfile-kw.gperf" ++#line 109 "locfile-kw.gperf" + {"duo_p_cs_precedes", tok_duo_p_cs_precedes, 0}, + #line 48 "locfile-kw.gperf" + {"charconv", tok_charconv, 0}, + {""}, + #line 47 "locfile-kw.gperf" + {"class", tok_class, 0}, +-#line 114 "locfile-kw.gperf" +- {"duo_int_n_cs_precedes", tok_duo_int_n_cs_precedes, 0}, + #line 115 "locfile-kw.gperf" ++ {"duo_int_n_cs_precedes", tok_duo_int_n_cs_precedes, 0}, ++#line 116 "locfile-kw.gperf" + {"duo_int_n_sep_by_space", tok_duo_int_n_sep_by_space, 0}, +-#line 111 "locfile-kw.gperf" ++#line 112 "locfile-kw.gperf" + {"duo_n_sep_by_space", tok_duo_n_sep_by_space, 0}, +-#line 119 "locfile-kw.gperf" ++#line 120 "locfile-kw.gperf" + {"duo_int_n_sign_posn", tok_duo_int_n_sign_posn, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, +-#line 58 "locfile-kw.gperf" ++#line 59 "locfile-kw.gperf" + {"section-symbol", tok_section_symbol, 0}, +-#line 185 "locfile-kw.gperf" ++#line 186 "locfile-kw.gperf" + {"int_prefix", tok_int_prefix, 0}, + {""}, {""}, {""}, {""}, + #line 42 "locfile-kw.gperf" + {"graph", tok_graph, 0}, + {""}, {""}, +-#line 99 "locfile-kw.gperf" ++#line 100 "locfile-kw.gperf" + {"int_p_sep_by_space", tok_int_p_sep_by_space, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 112 "locfile-kw.gperf" +- {"duo_int_p_cs_precedes", tok_duo_int_p_cs_precedes, 0}, + #line 113 "locfile-kw.gperf" ++ {"duo_int_p_cs_precedes", tok_duo_int_p_cs_precedes, 0}, ++#line 114 "locfile-kw.gperf" + {"duo_int_p_sep_by_space", tok_duo_int_p_sep_by_space, 0}, +-#line 109 "locfile-kw.gperf" ++#line 110 "locfile-kw.gperf" + {"duo_p_sep_by_space", tok_duo_p_sep_by_space, 0}, +-#line 118 "locfile-kw.gperf" ++#line 119 "locfile-kw.gperf" + {"duo_int_p_sign_posn", tok_duo_int_p_sign_posn, 0}, +-#line 157 "locfile-kw.gperf" ++#line 158 "locfile-kw.gperf" + {"nostr", tok_nostr, 0}, + {""}, {""}, +-#line 140 "locfile-kw.gperf" ++#line 141 "locfile-kw.gperf" + {"era", tok_era, 0}, + {""}, +-#line 84 "locfile-kw.gperf" ++#line 85 "locfile-kw.gperf" + {"currency_symbol", tok_currency_symbol, 0}, + {""}, +-#line 167 "locfile-kw.gperf" ++#line 168 "locfile-kw.gperf" + {"name_ms", tok_name_ms, 0}, +-#line 165 "locfile-kw.gperf" +- {"name_mrs", tok_name_mrs, 0}, + #line 166 "locfile-kw.gperf" ++ {"name_mrs", tok_name_mrs, 0}, ++#line 167 "locfile-kw.gperf" + {"name_miss", tok_name_miss, 0}, +-#line 83 "locfile-kw.gperf" ++#line 84 "locfile-kw.gperf" + {"int_curr_symbol", tok_int_curr_symbol, 0}, +-#line 190 "locfile-kw.gperf" ++#line 191 "locfile-kw.gperf" + {"source", tok_source, 0}, +-#line 164 "locfile-kw.gperf" ++#line 165 "locfile-kw.gperf" + {"name_mr", tok_name_mr, 0}, +-#line 163 "locfile-kw.gperf" ++#line 164 "locfile-kw.gperf" + {"name_gen", tok_name_gen, 0}, +-#line 202 "locfile-kw.gperf" ++#line 203 "locfile-kw.gperf" + {"date", tok_date, 0}, + {""}, {""}, +-#line 191 "locfile-kw.gperf" ++#line 192 "locfile-kw.gperf" + {"address", tok_address, 0}, +-#line 162 "locfile-kw.gperf" ++#line 163 "locfile-kw.gperf" + {"name_fmt", tok_name_fmt, 0}, + #line 32 "locfile-kw.gperf" + {"copy", tok_copy, 0}, +-#line 103 "locfile-kw.gperf" ++#line 104 "locfile-kw.gperf" + {"int_n_sign_posn", tok_int_n_sign_posn, 0}, + {""}, {""}, +-#line 131 "locfile-kw.gperf" ++#line 132 "locfile-kw.gperf" + {"day", tok_day, 0}, +-#line 105 "locfile-kw.gperf" ++#line 106 "locfile-kw.gperf" + {"duo_currency_symbol", tok_duo_currency_symbol, 0}, + {""}, {""}, {""}, +-#line 150 "locfile-kw.gperf" ++#line 151 "locfile-kw.gperf" + {"date_fmt", tok_date_fmt, 0}, +-#line 64 "locfile-kw.gperf" ++#line 65 "locfile-kw.gperf" + {"order_end", tok_order_end, 0}, +-#line 117 "locfile-kw.gperf" ++#line 118 "locfile-kw.gperf" + {"duo_n_sign_posn", tok_duo_n_sign_posn, 0}, + {""}, +-#line 170 "locfile-kw.gperf" ++#line 171 "locfile-kw.gperf" + {"country_name", tok_country_name, 0}, +-#line 71 "locfile-kw.gperf" ++#line 72 "locfile-kw.gperf" + {"reorder-after", tok_reorder_after, 0}, + {""}, {""}, +-#line 155 "locfile-kw.gperf" ++#line 156 "locfile-kw.gperf" + {"noexpr", tok_noexpr, 0}, + #line 50 "locfile-kw.gperf" + {"tolower", tok_tolower, 0}, +-#line 198 "locfile-kw.gperf" ++#line 199 "locfile-kw.gperf" + {"audience", tok_audience, 0}, + {""}, {""}, {""}, + #line 49 "locfile-kw.gperf" + {"toupper", tok_toupper, 0}, +-#line 68 "locfile-kw.gperf" ++#line 69 "locfile-kw.gperf" + {"position", tok_position, 0}, + {""}, + #line 40 "locfile-kw.gperf" +@@ -381,196 +381,197 @@ locfile_hash (register const char *str, register size_t len) + {""}, + #line 27 "locfile-kw.gperf" + {"comment_char", tok_comment_char, 0}, +-#line 88 "locfile-kw.gperf" ++#line 89 "locfile-kw.gperf" + {"positive_sign", tok_positive_sign, 0}, + {""}, {""}, {""}, {""}, +-#line 61 "locfile-kw.gperf" ++#line 62 "locfile-kw.gperf" + {"symbol-equivalence", tok_symbol_equivalence, 0}, + {""}, +-#line 102 "locfile-kw.gperf" ++#line 103 "locfile-kw.gperf" + {"int_p_sign_posn", tok_int_p_sign_posn, 0}, +-#line 175 "locfile-kw.gperf" ++#line 176 "locfile-kw.gperf" + {"country_car", tok_country_car, 0}, + {""}, {""}, +-#line 104 "locfile-kw.gperf" ++#line 105 "locfile-kw.gperf" + {"duo_int_curr_symbol", tok_duo_int_curr_symbol, 0}, + {""}, {""}, +-#line 135 "locfile-kw.gperf" ++#line 136 "locfile-kw.gperf" + {"d_t_fmt", tok_d_t_fmt, 0}, + {""}, {""}, +-#line 116 "locfile-kw.gperf" ++#line 117 "locfile-kw.gperf" + {"duo_p_sign_posn", tok_duo_p_sign_posn, 0}, +-#line 187 "locfile-kw.gperf" ++#line 188 "locfile-kw.gperf" + {"measurement", tok_measurement, 0}, +-#line 176 "locfile-kw.gperf" ++#line 177 "locfile-kw.gperf" + {"country_isbn", tok_country_isbn, 0}, + #line 37 "locfile-kw.gperf" + {"outdigit", tok_outdigit, 0}, + {""}, {""}, +-#line 143 "locfile-kw.gperf" ++#line 144 "locfile-kw.gperf" + {"era_d_t_fmt", tok_era_d_t_fmt, 0}, + {""}, {""}, {""}, + #line 34 "locfile-kw.gperf" + {"lower", tok_lower, 0}, +-#line 183 "locfile-kw.gperf" ++#line 184 "locfile-kw.gperf" + {"tel_dom_fmt", tok_tel_dom_fmt, 0}, +-#line 171 "locfile-kw.gperf" ++#line 172 "locfile-kw.gperf" + {"country_post", tok_country_post, 0}, +-#line 148 "locfile-kw.gperf" ++#line 149 "locfile-kw.gperf" + {"cal_direction", tok_cal_direction, 0}, +- {""}, +-#line 139 "locfile-kw.gperf" ++#line 57 "locfile-kw.gperf" ++ {"codepoint_collation", tok_codepoint_collation, 0}, ++#line 140 "locfile-kw.gperf" + {"t_fmt_ampm", tok_t_fmt_ampm, 0}, +-#line 91 "locfile-kw.gperf" ++#line 92 "locfile-kw.gperf" + {"frac_digits", tok_frac_digits, 0}, + {""}, {""}, +-#line 177 "locfile-kw.gperf" ++#line 178 "locfile-kw.gperf" + {"lang_name", tok_lang_name, 0}, +-#line 90 "locfile-kw.gperf" ++#line 91 "locfile-kw.gperf" + {"int_frac_digits", tok_int_frac_digits, 0}, + {""}, +-#line 121 "locfile-kw.gperf" ++#line 122 "locfile-kw.gperf" + {"uno_valid_to", tok_uno_valid_to, 0}, +-#line 126 "locfile-kw.gperf" ++#line 127 "locfile-kw.gperf" + {"decimal_point", tok_decimal_point, 0}, + {""}, +-#line 133 "locfile-kw.gperf" ++#line 134 "locfile-kw.gperf" + {"abmon", tok_abmon, 0}, + {""}, {""}, {""}, {""}, +-#line 107 "locfile-kw.gperf" ++#line 108 "locfile-kw.gperf" + {"duo_frac_digits", tok_duo_frac_digits, 0}, +-#line 182 "locfile-kw.gperf" ++#line 183 "locfile-kw.gperf" + {"tel_int_fmt", tok_tel_int_fmt, 0}, +-#line 123 "locfile-kw.gperf" ++#line 124 "locfile-kw.gperf" + {"duo_valid_to", tok_duo_valid_to, 0}, +-#line 146 "locfile-kw.gperf" ++#line 147 "locfile-kw.gperf" + {"first_weekday", tok_first_weekday, 0}, + {""}, +-#line 130 "locfile-kw.gperf" ++#line 131 "locfile-kw.gperf" + {"abday", tok_abday, 0}, + {""}, +-#line 200 "locfile-kw.gperf" ++#line 201 "locfile-kw.gperf" + {"abbreviation", tok_abbreviation, 0}, +-#line 147 "locfile-kw.gperf" ++#line 148 "locfile-kw.gperf" + {"first_workday", tok_first_workday, 0}, + {""}, {""}, +-#line 97 "locfile-kw.gperf" ++#line 98 "locfile-kw.gperf" + {"n_sign_posn", tok_n_sign_posn, 0}, + {""}, {""}, {""}, +-#line 145 "locfile-kw.gperf" ++#line 146 "locfile-kw.gperf" + {"alt_digits", tok_alt_digits, 0}, + {""}, {""}, +-#line 128 "locfile-kw.gperf" ++#line 129 "locfile-kw.gperf" + {"grouping", tok_grouping, 0}, + {""}, + #line 45 "locfile-kw.gperf" + {"blank", tok_blank, 0}, + {""}, {""}, +-#line 196 "locfile-kw.gperf" ++#line 197 "locfile-kw.gperf" + {"language", tok_language, 0}, +-#line 120 "locfile-kw.gperf" ++#line 121 "locfile-kw.gperf" + {"uno_valid_from", tok_uno_valid_from, 0}, + {""}, +-#line 199 "locfile-kw.gperf" ++#line 200 "locfile-kw.gperf" + {"application", tok_application, 0}, + {""}, +-#line 80 "locfile-kw.gperf" ++#line 81 "locfile-kw.gperf" + {"elifndef", tok_elifndef, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 122 "locfile-kw.gperf" ++#line 123 "locfile-kw.gperf" + {"duo_valid_from", tok_duo_valid_from, 0}, +-#line 57 "locfile-kw.gperf" ++#line 58 "locfile-kw.gperf" + {"coll_weight_max", tok_coll_weight_max, 0}, + {""}, +-#line 79 "locfile-kw.gperf" ++#line 80 "locfile-kw.gperf" + {"elifdef", tok_elifdef, 0}, +-#line 67 "locfile-kw.gperf" ++#line 68 "locfile-kw.gperf" + {"backward", tok_backward, 0}, +-#line 106 "locfile-kw.gperf" ++#line 107 "locfile-kw.gperf" + {"duo_int_frac_digits", tok_duo_int_frac_digits, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, +-#line 96 "locfile-kw.gperf" ++#line 97 "locfile-kw.gperf" + {"p_sign_posn", tok_p_sign_posn, 0}, + {""}, +-#line 203 "locfile-kw.gperf" ++#line 204 "locfile-kw.gperf" + {"category", tok_category, 0}, + {""}, {""}, {""}, {""}, +-#line 134 "locfile-kw.gperf" ++#line 135 "locfile-kw.gperf" + {"mon", tok_mon, 0}, + {""}, +-#line 124 "locfile-kw.gperf" ++#line 125 "locfile-kw.gperf" + {"conversion_rate", tok_conversion_rate, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 63 "locfile-kw.gperf" ++#line 64 "locfile-kw.gperf" + {"order_start", tok_order_start, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 178 "locfile-kw.gperf" ++#line 179 "locfile-kw.gperf" + {"lang_ab", tok_lang_ab, 0}, +-#line 180 "locfile-kw.gperf" ++#line 181 "locfile-kw.gperf" + {"lang_lib", tok_lang_lib, 0}, + {""}, {""}, {""}, +-#line 192 "locfile-kw.gperf" ++#line 193 "locfile-kw.gperf" + {"contact", tok_contact, 0}, + {""}, {""}, {""}, +-#line 173 "locfile-kw.gperf" ++#line 174 "locfile-kw.gperf" + {"country_ab3", tok_country_ab3, 0}, + {""}, {""}, {""}, +-#line 193 "locfile-kw.gperf" ++#line 194 "locfile-kw.gperf" + {"email", tok_email, 0}, +-#line 172 "locfile-kw.gperf" ++#line 173 "locfile-kw.gperf" + {"country_ab2", tok_country_ab2, 0}, + {""}, {""}, {""}, + #line 55 "locfile-kw.gperf" + {"default_missing", tok_default_missing, 0}, + {""}, {""}, +-#line 195 "locfile-kw.gperf" ++#line 196 "locfile-kw.gperf" + {"fax", tok_fax, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 174 "locfile-kw.gperf" ++#line 175 "locfile-kw.gperf" + {"country_num", tok_country_num, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, + #line 51 "locfile-kw.gperf" + {"map", tok_map, 0}, +-#line 65 "locfile-kw.gperf" ++#line 66 "locfile-kw.gperf" + {"from", tok_from, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 86 "locfile-kw.gperf" ++#line 87 "locfile-kw.gperf" + {"mon_thousands_sep", tok_mon_thousands_sep, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, +-#line 81 "locfile-kw.gperf" ++#line 82 "locfile-kw.gperf" + {"endif", tok_endif, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 151 "locfile-kw.gperf" ++#line 152 "locfile-kw.gperf" + {"alt_mon", tok_alt_mon, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 76 "locfile-kw.gperf" ++#line 77 "locfile-kw.gperf" + {"undef", tok_undef, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 59 "locfile-kw.gperf" ++#line 60 "locfile-kw.gperf" + {"collating-element", tok_collating_element, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 152 "locfile-kw.gperf" ++#line 153 "locfile-kw.gperf" + {"ab_alt_mon", tok_ab_alt_mon, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 66 "locfile-kw.gperf" ++#line 67 "locfile-kw.gperf" + {"forward", tok_forward, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, +-#line 85 "locfile-kw.gperf" ++#line 86 "locfile-kw.gperf" + {"mon_decimal_point", tok_mon_decimal_point, 0}, + {""}, {""}, +-#line 169 "locfile-kw.gperf" ++#line 170 "locfile-kw.gperf" + {"postal_fmt", tok_postal_fmt, 0}, + {""}, {""}, {""}, {""}, {""}, +-#line 60 "locfile-kw.gperf" ++#line 61 "locfile-kw.gperf" + {"collating-symbol", tok_collating_symbol, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +@@ -583,15 +584,15 @@ locfile_hash (register const char *str, register size_t len) + #line 38 "locfile-kw.gperf" + {"alnum", tok_alnum, 0}, + {""}, +-#line 87 "locfile-kw.gperf" ++#line 88 "locfile-kw.gperf" + {"mon_grouping", tok_mon_grouping, 0}, + {""}, +-#line 179 "locfile-kw.gperf" ++#line 180 "locfile-kw.gperf" + {"lang_term", tok_lang_term, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +-#line 77 "locfile-kw.gperf" ++#line 78 "locfile-kw.gperf" + {"ifdef", tok_ifdef, 0}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +@@ -599,7 +600,7 @@ locfile_hash (register const char *str, register size_t len) + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +-#line 138 "locfile-kw.gperf" ++#line 139 "locfile-kw.gperf" + {"am_pm", tok_am_pm, 0} + }; + +diff --git a/locale/programs/locfile-token.h b/locale/programs/locfile-token.h +index 414ad3076223e971..f57d594e8d25c06f 100644 +--- a/locale/programs/locfile-token.h ++++ b/locale/programs/locfile-token.h +@@ -91,6 +91,7 @@ enum token_t + tok_translit_ignore, + tok_default_missing, + tok_lc_collate, ++ tok_codepoint_collation, + tok_coll_weight_max, + tok_section_symbol, + tok_collating_element, diff --git a/glibc-c-utf8-locale-2.patch b/glibc-c-utf8-locale-2.patch new file mode 100644 index 0000000..7064b8e --- /dev/null +++ b/glibc-c-utf8-locale-2.patch @@ -0,0 +1,1437 @@ +commit 466f2be6c08070e9113ae2fdc7acd5d8828cba50 +Author: Carlos O'Donell +Date: Wed Sep 1 15:19:19 2021 -0400 + + Add generic C.UTF-8 locale (Bug 17318) + + We add a new C.UTF-8 locale. This locale is not builtin to glibc, but + is provided as a distinct locale. The locale provides full support for + UTF-8 and this includes full code point sorting via STRCMP-based + collation (strcmp or wcscmp). + + The collation uses a new keyword 'codepoint_collation' which drops all + collation rules and generates an empty zero rules collation to enable + STRCMP usage in collation. This ensures that we get full code point + sorting for C.UTF-8 with a minimal 1406 bytes of overhead (LC_COLLATE + structure information and ASCII collating tables). + + The new locale is added to SUPPORTED. Minimal test data for specific + code points (minus those not supported by collate-test) is provided in + C.UTF-8.in, and this verifies code point sorting is working reasonably + across the range. The locale was tested manually with the full set of + code points without failure. + + The locale is harmonized with locales already shipping in various + downstream distributions. A new tst-iconv9 test is added which verifies + the C.UTF-8 locale is generally usable. + + Testing for fnmatch, regexec, and recomp is provided by extending + bug-regex1, bugregex19, bug-regex4, bug-regex6, transbug, tst-fnmatch, + tst-regcomp-truncated, and tst-regex to use C.UTF-8. + + Tested on x86_64 or i686 without regression. + + Reviewed-by: Florian Weimer + +diff --git a/iconv/Makefile b/iconv/Makefile +index 07d77c9ecaafba1f..9993f2d3f3cd7498 100644 +--- a/iconv/Makefile ++++ b/iconv/Makefile +@@ -43,8 +43,19 @@ CFLAGS-charmap.c += -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \ + CFLAGS-linereader.c += -DNO_TRANSLITERATION + CFLAGS-simple-hash.c += -I../locale + +-tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \ +- tst-iconv7 tst-iconv8 tst-iconv-mt tst-iconv-opt ++tests = \ ++ tst-iconv1 \ ++ tst-iconv2 \ ++ tst-iconv3 \ ++ tst-iconv4 \ ++ tst-iconv5 \ ++ tst-iconv6 \ ++ tst-iconv7 \ ++ tst-iconv8 \ ++ tst-iconv9 \ ++ tst-iconv-mt \ ++ tst-iconv-opt \ ++ # tests + + others = iconv_prog iconvconfig + install-others-programs = $(inst_bindir)/iconv +@@ -83,10 +94,15 @@ endif + include ../Rules + + ifeq ($(run-built-tests),yes) +-LOCALES := en_US.UTF-8 ++# We have to generate locales (list sorted alphabetically) ++LOCALES := \ ++ C.UTF-8 \ ++ en_US.UTF-8 \ ++ # LOCALES + include ../gen-locales.mk + + $(objpfx)tst-iconv-opt.out: $(gen-locales) ++$(objpfx)tst-iconv9.out: $(gen-locales) + endif + + $(inst_bindir)/iconv: $(objpfx)iconv_prog $(+force) +diff --git a/iconv/tst-iconv9.c b/iconv/tst-iconv9.c +new file mode 100644 +index 0000000000000000..c46b1833d87b8e55 +--- /dev/null ++++ b/iconv/tst-iconv9.c +@@ -0,0 +1,87 @@ ++/* Verify that using C.UTF-8 works. ++ ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* This test does two things: ++ (1) Verify that we have likely included translit_combining in C.UTF-8. ++ (2) Verify default_missing is '?' as expected. */ ++ ++/* ISO-8859-1 encoding of "für". */ ++char iso88591_in[] = { 0x66, 0xfc, 0x72, 0x0 }; ++/* ASCII transliteration is "fur" with C.UTF-8 translit_combining. */ ++char ascii_exp[] = { 0x66, 0x75, 0x72, 0x0 }; ++ ++/* First 3-byte UTF-8 code point. */ ++char utf8_in[] = { 0xe0, 0xa0, 0x80, 0x0 }; ++/* There is no ASCII transliteration for SAMARITAN LETTER ALAF ++ so we get default_missing used which is '?'. */ ++char default_missing_exp[] = { 0x3f, 0x0 }; ++ ++static int ++do_test (void) ++{ ++ char ascii_out[5]; ++ iconv_t cd; ++ char *inbuf; ++ char *outbuf; ++ size_t inbytes; ++ size_t outbytes; ++ size_t n; ++ ++ /* The C.UTF-8 locale should include translit_combining, which provides ++ the transliteration for "LATIN SMALL LETTER U WITH DIAERESIS" which ++ is not provided by locale/C-translit.h.in. */ ++ xsetlocale (LC_ALL, "C.UTF-8"); ++ ++ /* From ISO-8859-1 to ASCII. */ ++ cd = iconv_open ("ASCII//TRANSLIT,IGNORE", "ISO-8859-1"); ++ TEST_VERIFY (cd != (iconv_t) -1); ++ inbuf = iso88591_in; ++ inbytes = 3; ++ outbuf = ascii_out; ++ outbytes = 3; ++ n = iconv (cd, &inbuf, &inbytes, &outbuf, &outbytes); ++ TEST_VERIFY (n != -1); ++ *outbuf = '\0'; ++ TEST_COMPARE_BLOB (ascii_out, 3, ascii_exp, 3); ++ TEST_VERIFY (iconv_close (cd) == 0); ++ ++ /* From UTF-8 to ASCII. */ ++ cd = iconv_open ("ASCII//TRANSLIT,IGNORE", "UTF-8"); ++ TEST_VERIFY (cd != (iconv_t) -1); ++ inbuf = utf8_in; ++ inbytes = 3; ++ outbuf = ascii_out; ++ outbytes = 3; ++ n = iconv (cd, &inbuf, &inbytes, &outbuf, &outbytes); ++ TEST_VERIFY (n != -1); ++ *outbuf = '\0'; ++ TEST_COMPARE_BLOB (ascii_out, 1, default_missing_exp, 1); ++ TEST_VERIFY (iconv_close (cd) == 0); ++ ++ return 0; ++} ++ ++#include +diff --git a/localedata/C.UTF-8.in b/localedata/C.UTF-8.in +new file mode 100644 +index 0000000000000000..c31dcc2aa045ee61 +--- /dev/null ++++ b/localedata/C.UTF-8.in +@@ -0,0 +1,157 @@ ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; ++! ; ++" ; ++# ; ++$ ; ++% ; ++& ; ++' ; ++) ; ++* ; +++ ; ++, ; ++- ; ++. ; ++/ ; ++0 ; ++1 ; ++2 ; ++3 ; ++4 ; ++5 ; ++6 ; ++7 ; ++8 ; ++9 ; ++< ; ++= ; ++> ; ++? ; ++@ ; ++A ; ++B ; ++C ; ++D ; ++E ; ++F ; ++G ; ++H ; ++I ; ++J ; ++K ; ++L ; ++M ; ++N ; ++O ; ++P ; ++Q ; ++R ; ++S ; ++T ; ++U ; ++V ; ++W ; ++X ; ++Y ; ++Z ; ++[ ; ++\ ; ++] ; ++^ ; ++_ ; ++` ; ++a ; ++b ; ++c ; ++d ; ++e ; ++f ; ++g ; ++h ; ++i ; ++j ; ++k ; ++l ; ++m ; ++n ; ++o ; ++p ; ++q ; ++r ; ++s ; ++t ; ++u ; ++v ; ++w ; ++x ; ++y ; ++z ; ++{ ; ++| ; ++} ; ++~ ; ++ ; ++€ ; ++ÿ ; ++Ā ; ++࿿ ; ++က ; ++� ; ++￿ ; ++𐀀 ; ++🿿 ; ++𠀀 ; ++𯿿 ; ++𰀀 ; ++𿿾 ; ++񀀀 ; ++񏿿 ; ++񐀀 ; ++񟿿 ; ++񠀀 ; ++񯿿 ; ++񰀀 ; ++񿿿 ; ++򀀀 ; ++򏿿 ; ++򐀀 ; ++򟿿 ; ++򠀀 ; ++򯿿 ; ++򰀀 ; ++򿿿 ; ++󀀁 ; ++󏿌 ; ++󐀎 ; ++󟿿 ; ++󠀁 ; ++󯿿 ; ++󰀁 ; ++󿿿 ; ++􀀁 ; ++􏿿 ; +diff --git a/localedata/Makefile b/localedata/Makefile +index 0341528b0407ae3b..c9dd5a954e8194cc 100644 +--- a/localedata/Makefile ++++ b/localedata/Makefile +@@ -47,6 +47,7 @@ test-input := \ + bg_BG.UTF-8 \ + br_FR.UTF-8 \ + bs_BA.UTF-8 \ ++ C.UTF-8 \ + ckb_IQ.UTF-8 \ + cmn_TW.UTF-8 \ + crh_UA.UTF-8 \ +@@ -206,6 +207,7 @@ LOCALES := \ + bg_BG.UTF-8 \ + br_FR.UTF-8 \ + bs_BA.UTF-8 \ ++ C.UTF-8 \ + ckb_IQ.UTF-8 \ + cmn_TW.UTF-8 \ + crh_UA.UTF-8 \ +diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED +index 34f7a7c3fe2b6526..546ce6cea16a8fdb 100644 +--- a/localedata/SUPPORTED ++++ b/localedata/SUPPORTED +@@ -79,6 +79,7 @@ brx_IN/UTF-8 \ + bs_BA.UTF-8/UTF-8 \ + bs_BA/ISO-8859-2 \ + byn_ER/UTF-8 \ ++C.UTF-8/UTF-8 \ + ca_AD.UTF-8/UTF-8 \ + ca_AD/ISO-8859-15 \ + ca_ES.UTF-8/UTF-8 \ +diff --git a/localedata/locales/C b/localedata/locales/C +new file mode 100644 +index 0000000000000000..ca801c79cf7e953e +--- /dev/null ++++ b/localedata/locales/C +@@ -0,0 +1,194 @@ ++escape_char / ++comment_char % ++% Locale for C locale in UTF-8 ++ ++LC_IDENTIFICATION ++title "C locale" ++source "" ++address "" ++contact "" ++email "bug-glibc-locales@gnu.org" ++tel "" ++fax "" ++language "" ++territory "" ++revision "2.0" ++date "2020-06-28" ++category "i18n:2012";LC_IDENTIFICATION ++category "i18n:2012";LC_CTYPE ++category "i18n:2012";LC_COLLATE ++category "i18n:2012";LC_TIME ++category "i18n:2012";LC_NUMERIC ++category "i18n:2012";LC_MONETARY ++category "i18n:2012";LC_MESSAGES ++category "i18n:2012";LC_PAPER ++category "i18n:2012";LC_NAME ++category "i18n:2012";LC_ADDRESS ++category "i18n:2012";LC_TELEPHONE ++category "i18n:2012";LC_MEASUREMENT ++END LC_IDENTIFICATION ++ ++LC_CTYPE ++% Include only the i18n character type classes without any of the ++% transliteration that i18n uses by default. ++copy "i18n_ctype" ++ ++% Include the neutral transliterations. The builtin C and ++% POSIX locales have +1600 transliterations that are built into ++% the locales, and these are a superset of those. ++translit_start ++include "translit_neutral";"" ++% We must use '?' for default_missing because the transliteration ++% framework includes it directly into the output and so it must ++% be compatible with ASCII if that is the target character set. ++default_missing ++translit_end ++ ++% Include the transliterations that can convert combined characters. ++% These are generally expected by users. ++translit_start ++include "translit_combining";"" ++translit_end ++ ++END LC_CTYPE ++ ++LC_COLLATE ++% The keyword 'codepoint_collation' in any part of any LC_COLLATE ++% immediately discards all collation information and causes the ++% locale to use strcmp/wcscmp for collation comparison. This is ++% exactly what is needed for C (ASCII) or C.UTF-8. ++codepoint_collation ++END LC_COLLATE ++ ++LC_MONETARY ++ ++% This is the 14652 i18n fdcc-set definition for the LC_MONETARY ++% category (except for the int_curr_symbol and currency_symbol, they are ++% empty in the 14652 i18n fdcc-set definition and also empty in ++% glibc/locale/C-monetary.c.). ++int_curr_symbol "" ++currency_symbol "" ++mon_decimal_point "." ++mon_thousands_sep "" ++mon_grouping -1 ++positive_sign "" ++negative_sign "-" ++int_frac_digits -1 ++frac_digits -1 ++p_cs_precedes -1 ++int_p_sep_by_space -1 ++p_sep_by_space -1 ++n_cs_precedes -1 ++int_n_sep_by_space -1 ++n_sep_by_space -1 ++p_sign_posn -1 ++n_sign_posn -1 ++% ++END LC_MONETARY ++ ++LC_NUMERIC ++% This is the POSIX Locale definition for ++% the LC_NUMERIC category. ++% ++decimal_point "." ++thousands_sep "" ++grouping -1 ++END LC_NUMERIC ++ ++LC_TIME ++% This is the POSIX Locale definition for the LC_TIME category with the ++% exception that time is per ISO 8601 and 24-hour. ++% ++% Abbreviated weekday names (%a) ++abday "Sun";"Mon";"Tue";"Wed";"Thu";"Fri";"Sat" ++ ++% Full weekday names (%A) ++day "Sunday";"Monday";"Tuesday";"Wednesday";"Thursday";/ ++ "Friday";"Saturday" ++ ++% Abbreviated month names (%b) ++abmon "Jan";"Feb";"Mar";"Apr";"May";"Jun";"Jul";"Aug";"Sep";/ ++ "Oct";"Nov";"Dec" ++ ++% Full month names (%B) ++mon "January";"February";"March";"April";"May";"June";"July";/ ++ "August";"September";"October";"November";"December" ++ ++% Week description, consists of three fields: ++% 1. Number of days in a week. ++% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday). ++% 3. The weekday number to be contained in the first week of the year. ++% ++% ISO 8601 conforming applications should use the values 7, 19971201 (a ++% Monday), and 4 (Thursday), respectively. ++week 7;19971201;4 ++first_weekday 1 ++first_workday 2 ++ ++% Appropriate date and time representation (%c) ++d_t_fmt "%a %b %e %H:%M:%S %Y" ++ ++% Appropriate date representation (%x) ++d_fmt "%m/%d/%y" ++ ++% Appropriate time representation (%X) ++t_fmt "%H:%M:%S" ++ ++% Appropriate AM/PM time representation (%r) ++t_fmt_ampm "%I:%M:%S %p" ++ ++% Equivalent of AM/PM (%p) ++am_pm "AM";"PM" ++ ++% Appropriate date representation (date(1)) ++date_fmt "%a %b %e %H:%M:%S %Z %Y" ++END LC_TIME ++ ++LC_MESSAGES ++% This is the POSIX Locale definition for ++% the LC_NUMERIC category. ++% ++yesexpr "^[yY]" ++noexpr "^[nN]" ++yesstr "Yes" ++nostr "No" ++END LC_MESSAGES ++ ++LC_PAPER ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_PAPER category. ++% (A4 paper, this is also used in the built in C/POSIX ++% locale in glibc/locale/C-paper.c) ++height 297 ++width 210 ++END LC_PAPER ++ ++LC_NAME ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_NAME category. ++% (also used in the built in C/POSIX locale in glibc/locale/C-name.c) ++name_fmt "%p%t%g%t%m%t%f" ++END LC_NAME ++ ++LC_ADDRESS ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_ADDRESS category. ++% (also used in the built in C/POSIX locale in glibc/locale/C-address.c) ++postal_fmt "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" ++END LC_ADDRESS ++ ++LC_TELEPHONE ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_TELEPHONE category. ++% "+%c %a %l" ++tel_int_fmt "+%c %a %l" ++% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c) ++END LC_TELEPHONE ++ ++LC_MEASUREMENT ++% This is the ISO/IEC 14652 "i18n" definition for ++% the LC_MEASUREMENT category. ++% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c) ++%metric ++measurement 1 ++END LC_MEASUREMENT +diff --git a/posix/Makefile b/posix/Makefile +index 059efb3cd2706cbe..a5229777eeb0e067 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -190,9 +190,19 @@ $(objpfx)wordexp-tst.out: wordexp-tst.sh $(objpfx)wordexp-test + $(evaluate-test) + endif + +-LOCALES := cs_CZ.UTF-8 da_DK.ISO-8859-1 de_DE.ISO-8859-1 de_DE.UTF-8 \ +- en_US.UTF-8 es_US.ISO-8859-1 es_US.UTF-8 ja_JP.EUC-JP tr_TR.UTF-8 \ +- cs_CZ.ISO-8859-2 ++LOCALES := \ ++ cs_CZ.ISO-8859-2 \ ++ cs_CZ.UTF-8 \ ++ C.UTF-8 \ ++ da_DK.ISO-8859-1 \ ++ de_DE.ISO-8859-1 \ ++ de_DE.UTF-8 \ ++ en_US.UTF-8 \ ++ es_US.ISO-8859-1 \ ++ es_US.UTF-8 \ ++ ja_JP.EUC-JP \ ++ tr_TR.UTF-8 \ ++ # LOCALES + include ../gen-locales.mk + + $(objpfx)bug-regex1.out: $(gen-locales) +diff --git a/posix/bug-regex1.c b/posix/bug-regex1.c +index 38eb543951862492..7e9f4ec430a95631 100644 +--- a/posix/bug-regex1.c ++++ b/posix/bug-regex1.c +@@ -41,6 +41,26 @@ main (void) + puts (" -> OK"); + } + ++ puts ("in C.UTF-8 locale"); ++ setlocale (LC_ALL, "C.UTF-8"); ++ s = re_compile_pattern ("[an\371]*n", 7, ®ex); ++ if (s != NULL) ++ { ++ puts ("re_compile_pattern return non-NULL value"); ++ result = 1; ++ } ++ else ++ { ++ match = re_match (®ex, "an", 2, 0, ®s); ++ if (match != 2) ++ { ++ printf ("re_match returned %d, expected 2\n", match); ++ result = 1; ++ } ++ else ++ puts (" -> OK"); ++ } ++ + puts ("in de_DE.ISO-8859-1 locale"); + setlocale (LC_ALL, "de_DE.ISO-8859-1"); + s = re_compile_pattern ("[an]*n", 7, ®ex); +diff --git a/posix/bug-regex19.c b/posix/bug-regex19.c +index b3fee0a7302c3263..e00ff60a14f994bf 100644 +--- a/posix/bug-regex19.c ++++ b/posix/bug-regex19.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #define BRE RE_SYNTAX_POSIX_BASIC + #define ERE RE_SYNTAX_POSIX_EXTENDED +@@ -407,8 +408,8 @@ do_mb_tests (const struct test_s *test) + return 0; + } + +-int +-main (void) ++static int ++do_test (void) + { + size_t i; + int ret = 0; +@@ -417,20 +418,17 @@ main (void) + + for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) + { +- if (setlocale (LC_ALL, "de_DE.ISO-8859-1") == NULL) +- { +- puts ("setlocale de_DE.ISO-8859-1 failed"); +- ret = 1; +- } ++ xsetlocale (LC_ALL, "de_DE.ISO-8859-1"); + ret |= do_one_test (&tests[i], ""); +- if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) +- { +- puts ("setlocale de_DE.UTF-8 failed"); +- ret = 1; +- } ++ xsetlocale (LC_ALL, "de_DE.UTF-8"); ++ ret |= do_one_test (&tests[i], "UTF-8 "); ++ ret |= do_mb_tests (&tests[i]); ++ xsetlocale (LC_ALL, "C.UTF-8"); + ret |= do_one_test (&tests[i], "UTF-8 "); + ret |= do_mb_tests (&tests[i]); + } + + return ret; + } ++ ++#include +diff --git a/posix/bug-regex4.c b/posix/bug-regex4.c +index 8d5ae11567889301..6475833c525176b2 100644 +--- a/posix/bug-regex4.c ++++ b/posix/bug-regex4.c +@@ -32,8 +32,33 @@ main (void) + + memset (®ex, '\0', sizeof (regex)); + ++ printf ("INFO: Checking C.\n"); + setlocale (LC_ALL, "C"); + ++ s = re_compile_pattern ("ab[cde]", 7, ®ex); ++ if (s != NULL) ++ { ++ puts ("re_compile_pattern returned non-NULL value"); ++ result = 1; ++ } ++ else ++ { ++ match[0] = re_search_2 (®ex, "xyabez", 6, "", 0, 1, 5, NULL, 6); ++ match[1] = re_search_2 (®ex, NULL, 0, "abc", 3, 0, 3, NULL, 3); ++ match[2] = re_search_2 (®ex, "xya", 3, "bd", 2, 2, 3, NULL, 5); ++ if (match[0] != 2 || match[1] != 0 || match[2] != 2) ++ { ++ printf ("re_search_2 returned %d,%d,%d, expected 2,0,2\n", ++ match[0], match[1], match[2]); ++ result = 1; ++ } ++ else ++ puts (" -> OK"); ++ } ++ ++ printf ("INFO: Checking C.UTF-8.\n"); ++ setlocale (LC_ALL, "C.UTF-8"); ++ + s = re_compile_pattern ("ab[cde]", 7, ®ex); + if (s != NULL) + { +diff --git a/posix/bug-regex6.c b/posix/bug-regex6.c +index 2bdf2126a49ee99b..0929b69b83c91e5e 100644 +--- a/posix/bug-regex6.c ++++ b/posix/bug-regex6.c +@@ -30,7 +30,7 @@ main (int argc, char *argv[]) + regex_t re; + regmatch_t mat[10]; + int i, j, ret = 0; +- const char *locales[] = { "C", "de_DE.UTF-8" }; ++ const char *locales[] = { "C", "C.UTF-8", "de_DE.UTF-8" }; + const char *string = "http://www.regex.com/pattern/matching.html#intro"; + regmatch_t expect[10] = { + { 0, 48 }, { 0, 5 }, { 0, 4 }, { 5, 20 }, { 7, 20 }, { 20, 42 }, +diff --git a/posix/transbug.c b/posix/transbug.c +index d0983b4d44d04fd2..b240177cf72326ff 100644 +--- a/posix/transbug.c ++++ b/posix/transbug.c +@@ -116,16 +116,32 @@ do_test (void) + static const char lower[] = "[[:lower:]]+"; + static const char upper[] = "[[:upper:]]+"; + struct re_registers regs[4]; ++ int result = 0; + ++#define CHECK(exp) \ ++ if (exp) { puts (#exp); result = 1; } ++ ++ printf ("INFO: Checking C.\n"); + setlocale (LC_ALL, "C"); + + (void) re_set_syntax (RE_SYNTAX_GNU_AWK); + +- int result; +-#define CHECK(exp) \ +- if (exp) { puts (#exp); result = 1; } ++ result |= run_test (lower, regs); ++ result |= run_test (upper, ®s[2]); ++ if (! result) ++ { ++ CHECK (regs[0].start[0] != regs[2].start[0]); ++ CHECK (regs[0].end[0] != regs[2].end[0]); ++ CHECK (regs[1].start[0] != regs[3].start[0]); ++ CHECK (regs[1].end[0] != regs[3].end[0]); ++ } ++ ++ printf ("INFO: Checking C.UTF-8.\n"); ++ setlocale (LC_ALL, "C.UTF-8"); ++ ++ (void) re_set_syntax (RE_SYNTAX_GNU_AWK); + +- result = run_test (lower, regs); ++ result |= run_test (lower, regs); + result |= run_test (upper, ®s[2]); + if (! result) + { +diff --git a/posix/tst-fnmatch.input b/posix/tst-fnmatch.input +index 67aac5aadafd8aeb..6ff5318032e0afb2 100644 +--- a/posix/tst-fnmatch.input ++++ b/posix/tst-fnmatch.input +@@ -472,6 +472,397 @@ C "\\" "[Z-\\]]" 0 + C "]" "[Z-\\]]" 0 + C "-" "[Z-\\]]" NOMATCH + ++# B.6 004(C) ++C.UTF-8 "!#%+,-./01234567889" "!#%+,-./01234567889" 0 ++C.UTF-8 ":;=@ABCDEFGHIJKLMNO" ":;=@ABCDEFGHIJKLMNO" 0 ++C.UTF-8 "PQRSTUVWXYZ]abcdefg" "PQRSTUVWXYZ]abcdefg" 0 ++C.UTF-8 "hijklmnopqrstuvwxyz" "hijklmnopqrstuvwxyz" 0 ++C.UTF-8 "^_{}~" "^_{}~" 0 ++ ++# B.6 005(C) ++C.UTF-8 "\"$&'()" "\\\"\\$\\&\\'\\(\\)" 0 ++C.UTF-8 "*?[\\`|" "\\*\\?\\[\\\\\\`\\|" 0 ++C.UTF-8 "<>" "\\<\\>" 0 ++ ++# B.6 006(C) ++C.UTF-8 "?*[" "[?*[][?*[][?*[]" 0 ++C.UTF-8 "a/b" "?/b" 0 ++ ++# B.6 007(C) ++C.UTF-8 "a/b" "a?b" 0 ++C.UTF-8 "a/b" "a/?" 0 ++C.UTF-8 "aa/b" "?/b" NOMATCH ++C.UTF-8 "aa/b" "a?b" NOMATCH ++C.UTF-8 "a/bb" "a/?" NOMATCH ++ ++# B.6 009(C) ++C.UTF-8 "abc" "[abc]" NOMATCH ++C.UTF-8 "x" "[abc]" NOMATCH ++C.UTF-8 "a" "[abc]" 0 ++C.UTF-8 "[" "[[abc]" 0 ++C.UTF-8 "a" "[][abc]" 0 ++C.UTF-8 "a]" "[]a]]" 0 ++ ++# B.6 010(C) ++C.UTF-8 "xyz" "[!abc]" NOMATCH ++C.UTF-8 "x" "[!abc]" 0 ++C.UTF-8 "a" "[!abc]" NOMATCH ++ ++# B.6 011(C) ++C.UTF-8 "]" "[][abc]" 0 ++C.UTF-8 "abc]" "[][abc]" NOMATCH ++C.UTF-8 "[]abc" "[][]abc" NOMATCH ++C.UTF-8 "]" "[!]]" NOMATCH ++C.UTF-8 "aa]" "[!]a]" NOMATCH ++C.UTF-8 "]" "[!a]" 0 ++C.UTF-8 "]]" "[!a]]" 0 ++ ++# B.6 012(C) ++C.UTF-8 "a" "[[.a.]]" 0 ++C.UTF-8 "-" "[[.-.]]" 0 ++C.UTF-8 "-" "[[.-.][.].]]" 0 ++C.UTF-8 "-" "[[.].][.-.]]" 0 ++C.UTF-8 "-" "[[.-.][=u=]]" 0 ++C.UTF-8 "-" "[[.-.][:alpha:]]" 0 ++C.UTF-8 "a" "[![.a.]]" NOMATCH ++ ++# B.6 013(C) ++C.UTF-8 "a" "[[.b.]]" NOMATCH ++C.UTF-8 "a" "[[.b.][.c.]]" NOMATCH ++C.UTF-8 "a" "[[.b.][=b=]]" NOMATCH ++ ++ ++# B.6 015(C) ++C.UTF-8 "a" "[[=a=]]" 0 ++C.UTF-8 "b" "[[=a=]b]" 0 ++C.UTF-8 "b" "[[=a=][=b=]]" 0 ++C.UTF-8 "a" "[[=a=][=b=]]" 0 ++C.UTF-8 "a" "[[=a=][.b.]]" 0 ++C.UTF-8 "a" "[[=a=][:digit:]]" 0 ++ ++# B.6 016(C) ++C.UTF-8 "=" "[[=a=]b]" NOMATCH ++C.UTF-8 "]" "[[=a=]b]" NOMATCH ++C.UTF-8 "a" "[[=b=][=c=]]" NOMATCH ++C.UTF-8 "a" "[[=b=][.].]]" NOMATCH ++C.UTF-8 "a" "[[=b=][:digit:]]" NOMATCH ++ ++# B.6 017(C) ++C.UTF-8 "a" "[[:alnum:]]" 0 ++C.UTF-8 "a" "[![:alnum:]]" NOMATCH ++C.UTF-8 "-" "[[:alnum:]]" NOMATCH ++C.UTF-8 "a]a" "[[:alnum:]]a" NOMATCH ++C.UTF-8 "-" "[[:alnum:]-]" 0 ++C.UTF-8 "aa" "[[:alnum:]]a" 0 ++C.UTF-8 "-" "[![:alnum:]]" 0 ++C.UTF-8 "]" "[!][:alnum:]]" NOMATCH ++C.UTF-8 "[" "[![:alnum:][]" NOMATCH ++C.UTF-8 "a" "[[:alnum:]]" 0 ++C.UTF-8 "b" "[[:alnum:]]" 0 ++C.UTF-8 "c" "[[:alnum:]]" 0 ++C.UTF-8 "d" "[[:alnum:]]" 0 ++C.UTF-8 "e" "[[:alnum:]]" 0 ++C.UTF-8 "f" "[[:alnum:]]" 0 ++C.UTF-8 "g" "[[:alnum:]]" 0 ++C.UTF-8 "h" "[[:alnum:]]" 0 ++C.UTF-8 "i" "[[:alnum:]]" 0 ++C.UTF-8 "j" "[[:alnum:]]" 0 ++C.UTF-8 "k" "[[:alnum:]]" 0 ++C.UTF-8 "l" "[[:alnum:]]" 0 ++C.UTF-8 "m" "[[:alnum:]]" 0 ++C.UTF-8 "n" "[[:alnum:]]" 0 ++C.UTF-8 "o" "[[:alnum:]]" 0 ++C.UTF-8 "p" "[[:alnum:]]" 0 ++C.UTF-8 "q" "[[:alnum:]]" 0 ++C.UTF-8 "r" "[[:alnum:]]" 0 ++C.UTF-8 "s" "[[:alnum:]]" 0 ++C.UTF-8 "t" "[[:alnum:]]" 0 ++C.UTF-8 "u" "[[:alnum:]]" 0 ++C.UTF-8 "v" "[[:alnum:]]" 0 ++C.UTF-8 "w" "[[:alnum:]]" 0 ++C.UTF-8 "x" "[[:alnum:]]" 0 ++C.UTF-8 "y" "[[:alnum:]]" 0 ++C.UTF-8 "z" "[[:alnum:]]" 0 ++C.UTF-8 "A" "[[:alnum:]]" 0 ++C.UTF-8 "B" "[[:alnum:]]" 0 ++C.UTF-8 "C" "[[:alnum:]]" 0 ++C.UTF-8 "D" "[[:alnum:]]" 0 ++C.UTF-8 "E" "[[:alnum:]]" 0 ++C.UTF-8 "F" "[[:alnum:]]" 0 ++C.UTF-8 "G" "[[:alnum:]]" 0 ++C.UTF-8 "H" "[[:alnum:]]" 0 ++C.UTF-8 "I" "[[:alnum:]]" 0 ++C.UTF-8 "J" "[[:alnum:]]" 0 ++C.UTF-8 "K" "[[:alnum:]]" 0 ++C.UTF-8 "L" "[[:alnum:]]" 0 ++C.UTF-8 "M" "[[:alnum:]]" 0 ++C.UTF-8 "N" "[[:alnum:]]" 0 ++C.UTF-8 "O" "[[:alnum:]]" 0 ++C.UTF-8 "P" "[[:alnum:]]" 0 ++C.UTF-8 "Q" "[[:alnum:]]" 0 ++C.UTF-8 "R" "[[:alnum:]]" 0 ++C.UTF-8 "S" "[[:alnum:]]" 0 ++C.UTF-8 "T" "[[:alnum:]]" 0 ++C.UTF-8 "U" "[[:alnum:]]" 0 ++C.UTF-8 "V" "[[:alnum:]]" 0 ++C.UTF-8 "W" "[[:alnum:]]" 0 ++C.UTF-8 "X" "[[:alnum:]]" 0 ++C.UTF-8 "Y" "[[:alnum:]]" 0 ++C.UTF-8 "Z" "[[:alnum:]]" 0 ++C.UTF-8 "0" "[[:alnum:]]" 0 ++C.UTF-8 "1" "[[:alnum:]]" 0 ++C.UTF-8 "2" "[[:alnum:]]" 0 ++C.UTF-8 "3" "[[:alnum:]]" 0 ++C.UTF-8 "4" "[[:alnum:]]" 0 ++C.UTF-8 "5" "[[:alnum:]]" 0 ++C.UTF-8 "6" "[[:alnum:]]" 0 ++C.UTF-8 "7" "[[:alnum:]]" 0 ++C.UTF-8 "8" "[[:alnum:]]" 0 ++C.UTF-8 "9" "[[:alnum:]]" 0 ++C.UTF-8 "!" "[[:alnum:]]" NOMATCH ++C.UTF-8 "#" "[[:alnum:]]" NOMATCH ++C.UTF-8 "%" "[[:alnum:]]" NOMATCH ++C.UTF-8 "+" "[[:alnum:]]" NOMATCH ++C.UTF-8 "," "[[:alnum:]]" NOMATCH ++C.UTF-8 "-" "[[:alnum:]]" NOMATCH ++C.UTF-8 "." "[[:alnum:]]" NOMATCH ++C.UTF-8 "/" "[[:alnum:]]" NOMATCH ++C.UTF-8 ":" "[[:alnum:]]" NOMATCH ++C.UTF-8 ";" "[[:alnum:]]" NOMATCH ++C.UTF-8 "=" "[[:alnum:]]" NOMATCH ++C.UTF-8 "@" "[[:alnum:]]" NOMATCH ++C.UTF-8 "[" "[[:alnum:]]" NOMATCH ++C.UTF-8 "\\" "[[:alnum:]]" NOMATCH ++C.UTF-8 "]" "[[:alnum:]]" NOMATCH ++C.UTF-8 "^" "[[:alnum:]]" NOMATCH ++C.UTF-8 "_" "[[:alnum:]]" NOMATCH ++C.UTF-8 "{" "[[:alnum:]]" NOMATCH ++C.UTF-8 "}" "[[:alnum:]]" NOMATCH ++C.UTF-8 "~" "[[:alnum:]]" NOMATCH ++C.UTF-8 "\"" "[[:alnum:]]" NOMATCH ++C.UTF-8 "$" "[[:alnum:]]" NOMATCH ++C.UTF-8 "&" "[[:alnum:]]" NOMATCH ++C.UTF-8 "'" "[[:alnum:]]" NOMATCH ++C.UTF-8 "(" "[[:alnum:]]" NOMATCH ++C.UTF-8 ")" "[[:alnum:]]" NOMATCH ++C.UTF-8 "*" "[[:alnum:]]" NOMATCH ++C.UTF-8 "?" "[[:alnum:]]" NOMATCH ++C.UTF-8 "`" "[[:alnum:]]" NOMATCH ++C.UTF-8 "|" "[[:alnum:]]" NOMATCH ++C.UTF-8 "<" "[[:alnum:]]" NOMATCH ++C.UTF-8 ">" "[[:alnum:]]" NOMATCH ++C.UTF-8 "\t" "[[:cntrl:]]" 0 ++C.UTF-8 "t" "[[:cntrl:]]" NOMATCH ++C.UTF-8 "t" "[[:lower:]]" 0 ++C.UTF-8 "\t" "[[:lower:]]" NOMATCH ++C.UTF-8 "T" "[[:lower:]]" NOMATCH ++C.UTF-8 "\t" "[[:space:]]" 0 ++C.UTF-8 "t" "[[:space:]]" NOMATCH ++C.UTF-8 "t" "[[:alpha:]]" 0 ++C.UTF-8 "\t" "[[:alpha:]]" NOMATCH ++C.UTF-8 "0" "[[:digit:]]" 0 ++C.UTF-8 "\t" "[[:digit:]]" NOMATCH ++C.UTF-8 "t" "[[:digit:]]" NOMATCH ++C.UTF-8 "\t" "[[:print:]]" NOMATCH ++C.UTF-8 "t" "[[:print:]]" 0 ++C.UTF-8 "T" "[[:upper:]]" 0 ++C.UTF-8 "\t" "[[:upper:]]" NOMATCH ++C.UTF-8 "t" "[[:upper:]]" NOMATCH ++C.UTF-8 "\t" "[[:blank:]]" 0 ++C.UTF-8 "t" "[[:blank:]]" NOMATCH ++C.UTF-8 "\t" "[[:graph:]]" NOMATCH ++C.UTF-8 "t" "[[:graph:]]" 0 ++C.UTF-8 "." "[[:punct:]]" 0 ++C.UTF-8 "t" "[[:punct:]]" NOMATCH ++C.UTF-8 "\t" "[[:punct:]]" NOMATCH ++C.UTF-8 "0" "[[:xdigit:]]" 0 ++C.UTF-8 "\t" "[[:xdigit:]]" NOMATCH ++C.UTF-8 "a" "[[:xdigit:]]" 0 ++C.UTF-8 "A" "[[:xdigit:]]" 0 ++C.UTF-8 "t" "[[:xdigit:]]" NOMATCH ++C.UTF-8 "a" "[[alpha]]" NOMATCH ++C.UTF-8 "a" "[[alpha:]]" NOMATCH ++C.UTF-8 "a]" "[[alpha]]" 0 ++C.UTF-8 "a]" "[[alpha:]]" 0 ++C.UTF-8 "a" "[[:alpha:][.b.]]" 0 ++C.UTF-8 "a" "[[:alpha:][=b=]]" 0 ++C.UTF-8 "a" "[[:alpha:][:digit:]]" 0 ++C.UTF-8 "a" "[[:digit:][:alpha:]]" 0 ++ ++# B.6 018(C) ++C.UTF-8 "a" "[a-c]" 0 ++C.UTF-8 "b" "[a-c]" 0 ++C.UTF-8 "c" "[a-c]" 0 ++C.UTF-8 "a" "[b-c]" NOMATCH ++C.UTF-8 "d" "[b-c]" NOMATCH ++C.UTF-8 "B" "[a-c]" NOMATCH ++C.UTF-8 "b" "[A-C]" NOMATCH ++C.UTF-8 "" "[a-c]" NOMATCH ++C.UTF-8 "as" "[a-ca-z]" NOMATCH ++C.UTF-8 "a" "[[.a.]-c]" 0 ++C.UTF-8 "a" "[a-[.c.]]" 0 ++C.UTF-8 "a" "[[.a.]-[.c.]]" 0 ++C.UTF-8 "b" "[[.a.]-c]" 0 ++C.UTF-8 "b" "[a-[.c.]]" 0 ++C.UTF-8 "b" "[[.a.]-[.c.]]" 0 ++C.UTF-8 "c" "[[.a.]-c]" 0 ++C.UTF-8 "c" "[a-[.c.]]" 0 ++C.UTF-8 "c" "[[.a.]-[.c.]]" 0 ++C.UTF-8 "d" "[[.a.]-c]" NOMATCH ++C.UTF-8 "d" "[a-[.c.]]" NOMATCH ++C.UTF-8 "d" "[[.a.]-[.c.]]" NOMATCH ++ ++# B.6 019(C) ++C.UTF-8 "a" "[c-a]" NOMATCH ++C.UTF-8 "a" "[[.c.]-a]" NOMATCH ++C.UTF-8 "a" "[c-[.a.]]" NOMATCH ++C.UTF-8 "a" "[[.c.]-[.a.]]" NOMATCH ++C.UTF-8 "c" "[c-a]" NOMATCH ++C.UTF-8 "c" "[[.c.]-a]" NOMATCH ++C.UTF-8 "c" "[c-[.a.]]" NOMATCH ++C.UTF-8 "c" "[[.c.]-[.a.]]" NOMATCH ++ ++# B.6 020(C) ++C.UTF-8 "a" "[a-c0-9]" 0 ++C.UTF-8 "d" "[a-c0-9]" NOMATCH ++C.UTF-8 "B" "[a-c0-9]" NOMATCH ++ ++# B.6 021(C) ++C.UTF-8 "-" "[-a]" 0 ++C.UTF-8 "a" "[-b]" NOMATCH ++C.UTF-8 "-" "[!-a]" NOMATCH ++C.UTF-8 "a" "[!-b]" 0 ++C.UTF-8 "-" "[a-c-0-9]" 0 ++C.UTF-8 "b" "[a-c-0-9]" 0 ++C.UTF-8 "a:" "a[0-9-a]" NOMATCH ++C.UTF-8 "a:" "a[09-a]" 0 ++ ++# B.6 024(C) ++C.UTF-8 "" "*" 0 ++C.UTF-8 "asd/sdf" "*" 0 ++ ++# B.6 025(C) ++C.UTF-8 "as" "[a-c][a-z]" 0 ++C.UTF-8 "as" "??" 0 ++ ++# B.6 026(C) ++C.UTF-8 "asd/sdf" "as*df" 0 ++C.UTF-8 "asd/sdf" "as*" 0 ++C.UTF-8 "asd/sdf" "*df" 0 ++C.UTF-8 "asd/sdf" "as*dg" NOMATCH ++C.UTF-8 "asdf" "as*df" 0 ++C.UTF-8 "asdf" "as*df?" NOMATCH ++C.UTF-8 "asdf" "as*??" 0 ++C.UTF-8 "asdf" "a*???" 0 ++C.UTF-8 "asdf" "*????" 0 ++C.UTF-8 "asdf" "????*" 0 ++C.UTF-8 "asdf" "??*?" 0 ++ ++# B.6 027(C) ++C.UTF-8 "/" "/" 0 ++C.UTF-8 "/" "/*" 0 ++C.UTF-8 "/" "*/" 0 ++C.UTF-8 "/" "/?" NOMATCH ++C.UTF-8 "/" "?/" NOMATCH ++C.UTF-8 "/" "?" 0 ++C.UTF-8 "." "?" 0 ++C.UTF-8 "/." "??" 0 ++C.UTF-8 "/" "[!a-c]" 0 ++C.UTF-8 "." "[!a-c]" 0 ++ ++# B.6 029(C) ++C.UTF-8 "/" "/" 0 PATHNAME ++C.UTF-8 "//" "//" 0 PATHNAME ++C.UTF-8 "/.a" "/*" 0 PATHNAME ++C.UTF-8 "/.a" "/?a" 0 PATHNAME ++C.UTF-8 "/.a" "/[!a-z]a" 0 PATHNAME ++C.UTF-8 "/.a/.b" "/*/?b" 0 PATHNAME ++ ++# B.6 030(C) ++C.UTF-8 "/" "?" NOMATCH PATHNAME ++C.UTF-8 "/" "*" NOMATCH PATHNAME ++C.UTF-8 "a/b" "a?b" NOMATCH PATHNAME ++C.UTF-8 "/.a/.b" "/*b" NOMATCH PATHNAME ++ ++# B.6 031(C) ++C.UTF-8 "/$" "\\/\\$" 0 ++C.UTF-8 "/[" "\\/\\[" 0 ++C.UTF-8 "/[" "\\/[" 0 ++C.UTF-8 "/[]" "\\/\\[]" 0 ++ ++# B.6 032(C) ++C.UTF-8 "/$" "\\/\\$" NOMATCH NOESCAPE ++C.UTF-8 "/\\$" "\\/\\$" NOMATCH NOESCAPE ++C.UTF-8 "\\/\\$" "\\/\\$" 0 NOESCAPE ++ ++# B.6 033(C) ++C.UTF-8 ".asd" ".*" 0 PERIOD ++C.UTF-8 "/.asd" "*" 0 PERIOD ++C.UTF-8 "/as/.df" "*/?*f" 0 PERIOD ++C.UTF-8 "..asd" ".[!a-z]*" 0 PERIOD ++ ++# B.6 034(C) ++C.UTF-8 ".asd" "*" NOMATCH PERIOD ++C.UTF-8 ".asd" "?asd" NOMATCH PERIOD ++C.UTF-8 ".asd" "[!a-z]*" NOMATCH PERIOD ++ ++# B.6 035(C) ++C.UTF-8 "/." "/." 0 PATHNAME|PERIOD ++C.UTF-8 "/.a./.b." "/.*/.*" 0 PATHNAME|PERIOD ++C.UTF-8 "/.a./.b." "/.??/.??" 0 PATHNAME|PERIOD ++ ++# B.6 036(C) ++C.UTF-8 "/." "*" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/." "/*" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/." "/?" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/." "/[!a-z]" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/a./.b." "/*/*" NOMATCH PATHNAME|PERIOD ++C.UTF-8 "/a./.b." "/??/???" NOMATCH PATHNAME|PERIOD ++ ++# Some home-grown tests. ++C.UTF-8 "foobar" "foo*[abc]z" NOMATCH ++C.UTF-8 "foobaz" "foo*[abc][xyz]" 0 ++C.UTF-8 "foobaz" "foo?*[abc][xyz]" 0 ++C.UTF-8 "foobaz" "foo?*[abc][x/yz]" 0 ++C.UTF-8 "foobaz" "foo?*[abc]/[xyz]" NOMATCH PATHNAME ++C.UTF-8 "a" "a/" NOMATCH PATHNAME ++C.UTF-8 "a/" "a" NOMATCH PATHNAME ++C.UTF-8 "//a" "/a" NOMATCH PATHNAME ++C.UTF-8 "/a" "//a" NOMATCH PATHNAME ++C.UTF-8 "az" "[a-]z" 0 ++C.UTF-8 "bz" "[ab-]z" 0 ++C.UTF-8 "cz" "[ab-]z" NOMATCH ++C.UTF-8 "-z" "[ab-]z" 0 ++C.UTF-8 "az" "[-a]z" 0 ++C.UTF-8 "bz" "[-ab]z" 0 ++C.UTF-8 "cz" "[-ab]z" NOMATCH ++C.UTF-8 "-z" "[-ab]z" 0 ++C.UTF-8 "\\" "[\\\\-a]" 0 ++C.UTF-8 "_" "[\\\\-a]" 0 ++C.UTF-8 "a" "[\\\\-a]" 0 ++C.UTF-8 "-" "[\\\\-a]" NOMATCH ++C.UTF-8 "\\" "[\\]-a]" NOMATCH ++C.UTF-8 "_" "[\\]-a]" 0 ++C.UTF-8 "a" "[\\]-a]" 0 ++C.UTF-8 "]" "[\\]-a]" 0 ++C.UTF-8 "-" "[\\]-a]" NOMATCH ++C.UTF-8 "\\" "[!\\\\-a]" NOMATCH ++C.UTF-8 "_" "[!\\\\-a]" NOMATCH ++C.UTF-8 "a" "[!\\\\-a]" NOMATCH ++C.UTF-8 "-" "[!\\\\-a]" 0 ++C.UTF-8 "!" "[\\!-]" 0 ++C.UTF-8 "-" "[\\!-]" 0 ++C.UTF-8 "\\" "[\\!-]" NOMATCH ++C.UTF-8 "Z" "[Z-\\\\]" 0 ++C.UTF-8 "[" "[Z-\\\\]" 0 ++C.UTF-8 "\\" "[Z-\\\\]" 0 ++C.UTF-8 "-" "[Z-\\\\]" NOMATCH ++C.UTF-8 "Z" "[Z-\\]]" 0 ++C.UTF-8 "[" "[Z-\\]]" 0 ++C.UTF-8 "\\" "[Z-\\]]" 0 ++C.UTF-8 "]" "[Z-\\]]" 0 ++C.UTF-8 "-" "[Z-\\]]" NOMATCH ++ + # Following are tests outside the scope of IEEE 2003.2 since they are using + # locales other than the C locale. The main focus of the tests is on the + # handling of ranges and the recognition of character (vs bytes). +@@ -677,7 +1068,6 @@ C "x/y" "*" 0 PATHNAME|LEADING_DIR + C "x/y/z" "*" 0 PATHNAME|LEADING_DIR + C "x" "*x" 0 PATHNAME|LEADING_DIR + +-en_US.UTF-8 "\366.csv" "*.csv" 0 + C "x/y" "*x" 0 PATHNAME|LEADING_DIR + C "x/y/z" "*x" 0 PATHNAME|LEADING_DIR + C "x" "x*" 0 PATHNAME|LEADING_DIR +@@ -693,6 +1083,33 @@ C "x" "x?y" NOMATCH PATHNAME|LEADING_DIR + C "x/y" "x?y" NOMATCH PATHNAME|LEADING_DIR + C "x/y/z" "x?y" NOMATCH PATHNAME|LEADING_DIR + ++# Duplicate the "Test of GNU extensions." tests but for C.UTF-8. ++C.UTF-8 "x" "x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "*x" 0 PATHNAME|LEADING_DIR ++ ++C.UTF-8 "x/y" "*x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "*x" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "x*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x*" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "a" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "a" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "a" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x" "x/y" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x/y" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x/y" 0 PATHNAME|LEADING_DIR ++C.UTF-8 "x" "x?y" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y" "x?y" NOMATCH PATHNAME|LEADING_DIR ++C.UTF-8 "x/y/z" "x?y" NOMATCH PATHNAME|LEADING_DIR ++ ++# Bug 14185 ++en_US.UTF-8 "\366.csv" "*.csv" 0 ++ + # ksh style matching. + C "abcd" "?@(a|b)*@(c)d" 0 EXTMATCH + C "/dev/udp/129.22.8.102/45" "/dev/@(tcp|udp)/*/*" 0 PATHNAME|EXTMATCH +@@ -822,3 +1239,133 @@ C "" "" 0 + C "" "" 0 EXTMATCH + C "" "*([abc])" 0 EXTMATCH + C "" "?([abc])" 0 EXTMATCH ++ ++# Duplicate the "ksh style matching." for C.UTF-8. ++C.UTF-8 "abcd" "?@(a|b)*@(c)d" 0 EXTMATCH ++C.UTF-8 "/dev/udp/129.22.8.102/45" "/dev/@(tcp|udp)/*/*" 0 PATHNAME|EXTMATCH ++C.UTF-8 "12" "[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "12abc" "[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "1" "[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "07" "+([0-7])" 0 EXTMATCH ++C.UTF-8 "0377" "+([0-7])" 0 EXTMATCH ++C.UTF-8 "09" "+([0-7])" NOMATCH EXTMATCH ++C.UTF-8 "paragraph" "para@(chute|graph)" 0 EXTMATCH ++C.UTF-8 "paramour" "para@(chute|graph)" NOMATCH EXTMATCH ++C.UTF-8 "para991" "para?([345]|99)1" 0 EXTMATCH ++C.UTF-8 "para381" "para?([345]|99)1" NOMATCH EXTMATCH ++C.UTF-8 "paragraph" "para*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "para" "para*([0-9])" 0 EXTMATCH ++C.UTF-8 "para13829383746592" "para*([0-9])" 0 EXTMATCH ++C.UTF-8 "paragraph" "para+([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "para" "para+([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "para987346523" "para+([0-9])" 0 EXTMATCH ++C.UTF-8 "paragraph" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "para.38" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "para.graph" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "para39" "para!(*.[0-9])" 0 EXTMATCH ++C.UTF-8 "" "*(0|1|3|5|7|9)" 0 EXTMATCH ++C.UTF-8 "137577991" "*(0|1|3|5|7|9)" 0 EXTMATCH ++C.UTF-8 "2468" "*(0|1|3|5|7|9)" NOMATCH EXTMATCH ++C.UTF-8 "1358" "*(0|1|3|5|7|9)" NOMATCH EXTMATCH ++C.UTF-8 "file.c" "*.c?(c)" 0 EXTMATCH ++C.UTF-8 "file.C" "*.c?(c)" NOMATCH EXTMATCH ++C.UTF-8 "file.cc" "*.c?(c)" 0 EXTMATCH ++C.UTF-8 "file.ccc" "*.c?(c)" NOMATCH EXTMATCH ++C.UTF-8 "parse.y" "!(*.c|*.h|Makefile.in|config*|README)" 0 EXTMATCH ++C.UTF-8 "shell.c" "!(*.c|*.h|Makefile.in|config*|README)" NOMATCH EXTMATCH ++C.UTF-8 "Makefile" "!(*.c|*.h|Makefile.in|config*|README)" 0 EXTMATCH ++C.UTF-8 "VMS.FILE;1" "*\;[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "VMS.FILE;0" "*\;[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "VMS.FILE;" "*\;[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "VMS.FILE;139" "*\;[1-9]*([0-9])" 0 EXTMATCH ++C.UTF-8 "VMS.FILE;1N" "*\;[1-9]*([0-9])" NOMATCH EXTMATCH ++C.UTF-8 "abcfefg" "ab**(e|f)" 0 EXTMATCH ++C.UTF-8 "abcfefg" "ab**(e|f)g" 0 EXTMATCH ++C.UTF-8 "ab" "ab*+(e|f)" NOMATCH EXTMATCH ++C.UTF-8 "abef" "ab***ef" 0 EXTMATCH ++C.UTF-8 "abef" "ab**" 0 EXTMATCH ++C.UTF-8 "fofo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "ffo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "foooofo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "foooofof" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "fooofoofofooo" "*(f*(o))" 0 EXTMATCH ++C.UTF-8 "foooofof" "*(f+(o))" NOMATCH EXTMATCH ++C.UTF-8 "xfoooofof" "*(f*(o))" NOMATCH EXTMATCH ++C.UTF-8 "foooofofx" "*(f*(o))" NOMATCH EXTMATCH ++C.UTF-8 "ofxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofooofoofofooo" "*(f*(o))" NOMATCH EXTMATCH ++C.UTF-8 "foooxfooxfoxfooox" "*(f*(o)x)" 0 EXTMATCH ++C.UTF-8 "foooxfooxofoxfooox" "*(f*(o)x)" NOMATCH EXTMATCH ++C.UTF-8 "foooxfooxfxfooox" "*(f*(o)x)" 0 EXTMATCH ++C.UTF-8 "ofxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxoo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxofo" "*(*(of*(o)x)o)" NOMATCH EXTMATCH ++C.UTF-8 "ofoooxoofxoofoooxoofxooofxofxo" "*(*(of*(o)x)o)" 0 EXTMATCH ++C.UTF-8 "aac" "*(@(a))a@(c)" 0 EXTMATCH ++C.UTF-8 "ac" "*(@(a))a@(c)" 0 EXTMATCH ++C.UTF-8 "c" "*(@(a))a@(c)" NOMATCH EXTMATCH ++C.UTF-8 "aaac" "*(@(a))a@(c)" 0 EXTMATCH ++C.UTF-8 "baaac" "*(@(a))a@(c)" NOMATCH EXTMATCH ++C.UTF-8 "abcd" "?@(a|b)*@(c)d" 0 EXTMATCH ++C.UTF-8 "abcd" "@(ab|a*@(b))*(c)d" 0 EXTMATCH ++C.UTF-8 "acd" "@(ab|a*(b))*(c)d" 0 EXTMATCH ++C.UTF-8 "abbcd" "@(ab|a*(b))*(c)d" 0 EXTMATCH ++C.UTF-8 "effgz" "@(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "efgz" "@(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "egz" "@(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "egzefffgzbcdij" "*(b+(c)d|e*(f)g?|?(h)i@(j|k))" 0 EXTMATCH ++C.UTF-8 "egz" "@(b+(c)d|e+(f)g?|?(h)i@(j|k))" NOMATCH EXTMATCH ++C.UTF-8 "ofoofo" "*(of+(o))" 0 EXTMATCH ++C.UTF-8 "oxfoxoxfox" "*(oxf+(ox))" 0 EXTMATCH ++C.UTF-8 "oxfoxfox" "*(oxf+(ox))" NOMATCH EXTMATCH ++C.UTF-8 "ofoofo" "*(of+(o)|f)" 0 EXTMATCH ++C.UTF-8 "foofoofo" "@(foo|f|fo)*(f|of+(o))" 0 EXTMATCH ++C.UTF-8 "oofooofo" "*(of|oof+(o))" 0 EXTMATCH ++C.UTF-8 "fffooofoooooffoofffooofff" "*(*(f)*(o))" 0 EXTMATCH ++C.UTF-8 "fofoofoofofoo" "*(fo|foo)" 0 EXTMATCH ++C.UTF-8 "foo" "!(x)" 0 EXTMATCH ++C.UTF-8 "foo" "!(x)*" 0 EXTMATCH ++C.UTF-8 "foo" "!(foo)" NOMATCH EXTMATCH ++C.UTF-8 "foo" "!(foo)*" 0 EXTMATCH ++C.UTF-8 "foobar" "!(foo)" 0 EXTMATCH ++C.UTF-8 "foobar" "!(foo)*" 0 EXTMATCH ++C.UTF-8 "moo.cow" "!(*.*).!(*.*)" 0 EXTMATCH ++C.UTF-8 "mad.moo.cow" "!(*.*).!(*.*)" NOMATCH EXTMATCH ++C.UTF-8 "mucca.pazza" "mu!(*(c))?.pa!(*(z))?" NOMATCH EXTMATCH ++C.UTF-8 "fff" "!(f)" 0 EXTMATCH ++C.UTF-8 "fff" "*(!(f))" 0 EXTMATCH ++C.UTF-8 "fff" "+(!(f))" 0 EXTMATCH ++C.UTF-8 "ooo" "!(f)" 0 EXTMATCH ++C.UTF-8 "ooo" "*(!(f))" 0 EXTMATCH ++C.UTF-8 "ooo" "+(!(f))" 0 EXTMATCH ++C.UTF-8 "foo" "!(f)" 0 EXTMATCH ++C.UTF-8 "foo" "*(!(f))" 0 EXTMATCH ++C.UTF-8 "foo" "+(!(f))" 0 EXTMATCH ++C.UTF-8 "f" "!(f)" NOMATCH EXTMATCH ++C.UTF-8 "f" "*(!(f))" NOMATCH EXTMATCH ++C.UTF-8 "f" "+(!(f))" NOMATCH EXTMATCH ++C.UTF-8 "foot" "@(!(z*)|*x)" 0 EXTMATCH ++C.UTF-8 "zoot" "@(!(z*)|*x)" NOMATCH EXTMATCH ++C.UTF-8 "foox" "@(!(z*)|*x)" 0 EXTMATCH ++C.UTF-8 "zoox" "@(!(z*)|*x)" 0 EXTMATCH ++C.UTF-8 "foo" "*(!(foo))" 0 EXTMATCH ++C.UTF-8 "foob" "!(foo)b*" NOMATCH EXTMATCH ++C.UTF-8 "foobb" "!(foo)b*" 0 EXTMATCH ++C.UTF-8 "[" "*([a[])" 0 EXTMATCH ++C.UTF-8 "]" "*([]a[])" 0 EXTMATCH ++C.UTF-8 "a" "*([]a[])" 0 EXTMATCH ++C.UTF-8 "b" "*([!]a[])" 0 EXTMATCH ++C.UTF-8 "[" "*([!]a[]|[[])" 0 EXTMATCH ++C.UTF-8 "]" "*([!]a[]|[]])" 0 EXTMATCH ++C.UTF-8 "[" "!([!]a[])" 0 EXTMATCH ++C.UTF-8 "]" "!([!]a[])" 0 EXTMATCH ++C.UTF-8 ")" "*([)])" 0 EXTMATCH ++C.UTF-8 "*" "*([*(])" 0 EXTMATCH ++C.UTF-8 "abcd" "*!(|a)cd" 0 EXTMATCH ++C.UTF-8 "ab/.a" "+([abc])/*" NOMATCH EXTMATCH|PATHNAME|PERIOD ++C.UTF-8 "" "" 0 ++C.UTF-8 "" "" 0 EXTMATCH ++C.UTF-8 "" "*([abc])" 0 EXTMATCH ++C.UTF-8 "" "?([abc])" 0 EXTMATCH +diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c +index 84195fcd2ec153b8..da3f97799e37c607 100644 +--- a/posix/tst-regcomp-truncated.c ++++ b/posix/tst-regcomp-truncated.c +@@ -37,6 +37,7 @@ + static const char locales[][17] = + { + "C", ++ "C.UTF-8", + "en_US.UTF-8", + "de_DE.ISO-8859-1", + }; +diff --git a/posix/tst-regex.c b/posix/tst-regex.c +index e7c2b05e8666a16e..531128de2a9176fa 100644 +--- a/posix/tst-regex.c ++++ b/posix/tst-regex.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + + #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 +@@ -58,7 +59,7 @@ do_test (void) + const char *file; + int fd; + struct stat st; +- int result; ++ int result = 0; + char *inmem; + char *outmem; + size_t inlen; +@@ -123,7 +124,7 @@ do_test (void) + + /* Run the actual tests. All tests are run in a single-byte and a + multi-byte locale. */ +- result = test_expr ("[äáàâéèêíìîñöóòôüúùû]", 4, 4); ++ result |= test_expr ("[äáàâéèêíìîñöóòôüúùû]", 4, 4); + result |= test_expr ("G.ran", 2, 3); + result |= test_expr ("G.\\{1\\}ran", 2, 3); + result |= test_expr ("G.*ran", 3, 44); +@@ -143,19 +144,33 @@ do_test (void) + static int + test_expr (const char *expr, int expected, int expectedicase) + { +- int result; ++ int result = 0; + char *inmem; + char *outmem; + size_t inlen; + size_t outlen; + char *uexpr; + +- /* First test: search with an UTF-8 locale. */ +- if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) +- error (EXIT_FAILURE, 0, "cannot set locale de_DE.UTF-8"); ++ /* First test: search with basic C.UTF-8 locale. */ ++ printf ("INFO: Testing C.UTF-8.\n"); ++ xsetlocale (LC_ALL, "C.UTF-8"); + + printf ("\nTest \"%s\" with multi-byte locale\n", expr); +- result = run_test (expr, mem, memlen, 0, expected); ++ result |= run_test (expr, mem, memlen, 0, expected); ++ printf ("\nTest \"%s\" with multi-byte locale, case insensitive\n", expr); ++ result |= run_test (expr, mem, memlen, 1, expectedicase); ++ printf ("\nTest \"%s\" backwards with multi-byte locale\n", expr); ++ result |= run_test_backwards (expr, mem, memlen, 0, expected); ++ printf ("\nTest \"%s\" backwards with multi-byte locale, case insensitive\n", ++ expr); ++ result |= run_test_backwards (expr, mem, memlen, 1, expectedicase); ++ ++ /* Second test: search with an UTF-8 locale. */ ++ printf ("INFO: Testing de_DE.UTF-8.\n"); ++ xsetlocale (LC_ALL, "de_DE.UTF-8"); ++ ++ printf ("\nTest \"%s\" with multi-byte locale\n", expr); ++ result |= run_test (expr, mem, memlen, 0, expected); + printf ("\nTest \"%s\" with multi-byte locale, case insensitive\n", expr); + result |= run_test (expr, mem, memlen, 1, expectedicase); + printf ("\nTest \"%s\" backwards with multi-byte locale\n", expr); +@@ -165,8 +180,8 @@ test_expr (const char *expr, int expected, int expectedicase) + result |= run_test_backwards (expr, mem, memlen, 1, expectedicase); + + /* Second test: search with an ISO-8859-1 locale. */ +- if (setlocale (LC_ALL, "de_DE.ISO-8859-1") == NULL) +- error (EXIT_FAILURE, 0, "cannot set locale de_DE.ISO-8859-1"); ++ printf ("INFO: Testing de_DE.ISO-8859-1.\n"); ++ xsetlocale (LC_ALL, "de_DE.ISO-8859-1"); + + inmem = (char *) expr; + inlen = strlen (expr); diff --git a/glibc-c-utf8-locale.patch b/glibc-c-utf8-locale.patch deleted file mode 100644 index a4cf357..0000000 --- a/glibc-c-utf8-locale.patch +++ /dev/null @@ -1,286 +0,0 @@ -Short description: Add C.UTF-8 support. -Author(s): Fedora glibc team -Origin: PATCH -Upstream status: not-submitted - -This patch needs to upstream as part of Carlos O'Donell -'s work on enabling upstream C.UTF-8 support. This -work is currently blocked on cleaning up the test results to prove that -full code-point sorting is working as intended. - -Note that this patch does not provide full code-point sorting as -expected. - -This patch needs to upstream as soon as possible since it would be nice -to have this in F29 and fixed. - -From 2eda7b462b415105f5a05c1323372d4e39d46439 Mon Sep 17 00:00:00 2001 -From: Mike FABIAN -Date: Mon, 10 Aug 2015 15:58:12 +0200 -Subject: [PATCH] Add a C.UTF-8 locale - ---- - localedata/SUPPORTED | 1 + - localedata/locales/C | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 239 insertions(+) - create mode 100644 localedata/locales/C - -diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED -index 8ca023e..2a78391 100644 ---- a/localedata/SUPPORTED -+++ b/localedata/SUPPORTED -@@ -1,6 +1,7 @@ - # This file names the currently supported and somewhat tested locales. - # If you have any additions please file a glibc bug report. - SUPPORTED-LOCALES=\ -+C.UTF-8/UTF-8 \ - aa_DJ.UTF-8/UTF-8 \ - aa_DJ/ISO-8859-1 \ - aa_ER/UTF-8 \ -diff --git a/localedata/locales/C b/localedata/locales/C -new file mode 100644 -index 0000000..fdf460e ---- /dev/null -+++ b/localedata/locales/C -@@ -0,0 +1,238 @@ -+escape_char / -+comment_char % -+% Locale for C locale in UTF-8 -+ -+LC_IDENTIFICATION -+title "C locale" -+source "" -+address "" -+contact "" -+email "mfabian@redhat.com" -+tel "" -+fax "" -+language "C" -+territory "" -+revision "1.0" -+date "2015-08-10" -+% -+category "i18n:2012";LC_IDENTIFICATION -+category "i18n:2012";LC_CTYPE -+category "i18n:2012";LC_COLLATE -+category "i18n:2012";LC_TIME -+category "i18n:2012";LC_NUMERIC -+category "i18n:2012";LC_MONETARY -+category "i18n:2012";LC_MESSAGES -+category "i18n:2012";LC_PAPER -+category "i18n:2012";LC_NAME -+category "i18n:2012";LC_ADDRESS -+category "i18n:2012";LC_TELEPHONE -+category "i18n:2012";LC_MEASUREMENT -+END LC_IDENTIFICATION -+ -+LC_CTYPE -+copy "i18n" -+ -+translit_start -+include "translit_combining";"" -+translit_end -+ -+END LC_CTYPE -+ -+LC_COLLATE -+order_start forward -+ -+.. -+ -+ -+.. -+ -+ -+.. -+ -+ -+.. -+ -+ -+.. -+ -+ -+.. -+ -+UNDEFINED -+order_end -+END LC_COLLATE -+ -+LC_MONETARY -+% This is the 14652 i18n fdcc-set definition for -+% the LC_MONETARY category -+% (except for the int_curr_symbol and currency_symbol, they are empty in -+% the 14652 i18n fdcc-set definition and also empty in -+% glibc/locale/C-monetary.c. But localedef complains in that case). -+% -+% Using "USD" for int_curr_symbol. But maybe "XXX" would be better? -+% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217) -+int_curr_symbol "" -+% Using "$" for currency_symbol. But maybe would be better? -+% U+00A4 is the "generic currency symbol" -+% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29) -+currency_symbol "" -+mon_decimal_point "" -+mon_thousands_sep "" -+mon_grouping -1 -+positive_sign "" -+negative_sign "" -+int_frac_digits -1 -+frac_digits -1 -+p_cs_precedes -1 -+int_p_sep_by_space -1 -+p_sep_by_space -1 -+n_cs_precedes -1 -+int_n_sep_by_space -1 -+n_sep_by_space -1 -+p_sign_posn -1 -+n_sign_posn -1 -+% -+END LC_MONETARY -+ -+LC_NUMERIC -+% This is the POSIX Locale definition for -+% the LC_NUMERIC category. -+% -+decimal_point "" -+thousands_sep "" -+grouping -1 -+END LC_NUMERIC -+ -+LC_TIME -+% This is the POSIX Locale definition for -+% the LC_TIME category. -+% -+% Abbreviated weekday names (%a) -+abday "";"";/ -+ "";"";/ -+ "";"";/ -+ "" -+ -+% Full weekday names (%A) -+day "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "" -+ -+% Abbreviated month names (%b) -+abmon "";"";/ -+ "";"";/ -+ "";"";/ -+ "";"";/ -+ "";"";/ -+ "";"" -+ -+% Full month names (%B) -+mon "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "";/ -+ "" -+ -+% Week description, consists of three fields: -+% 1. Number of days in a week. -+% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday). -+% 3. The weekday number to be contained in the first week of the year. -+% -+% ISO 8601 conforming applications should use the values 7, 19971201 (a -+% Monday), and 4 (Thursday), respectively. -+week 7;19971201;4 -+first_weekday 1 -+first_workday 1 -+ -+% Appropriate date and time representation (%c) -+% "%a %b %e %H:%M:%S %Y" -+d_t_fmt "" -+ -+% Appropriate date representation (%x) -+% "%m/%d/%y" -+d_fmt "" -+ -+% Appropriate time representation (%X) -+% "%H:%M:%S" -+t_fmt "" -+ -+% Appropriate AM/PM time representation (%r) -+% "%I:%M:%S %p" -+t_fmt_ampm "" -+ -+% Equivalent of AM/PM (%p) "AM"/"PM" -+% -+am_pm "";"" -+ -+% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y" -+date_fmt "" -+END LC_TIME -+ -+LC_MESSAGES -+% This is the POSIX Locale definition for -+% the LC_NUMERIC category. -+% -+yesexpr "" -+noexpr "" -+yesstr "" -+nostr "" -+END LC_MESSAGES -+ -+LC_PAPER -+% This is the ISO/IEC 14652 "i18n" definition for -+% the LC_PAPER category. -+% (A4 paper, this is also used in the built in C/POSIX -+% locale in glibc/locale/C-paper.c) -+height 297 -+width 210 -+END LC_PAPER -+ -+LC_NAME -+% This is the ISO/IEC 14652 "i18n" definition for -+% the LC_NAME category. -+% "%p%t%g%t%m%t%f" -+% (also used in the built in C/POSIX locale in glibc/locale/C-name.c) -+name_fmt "/ -+" -+END LC_NAME -+ -+LC_ADDRESS -+% This is the ISO/IEC 14652 "i18n" definition for -+% the LC_ADDRESS category. -+% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" -+% (also used in the built in C/POSIX locale in glibc/locale/C-address.c) -+postal_fmt "/ -+/ -+/ -+/ -+" -+END LC_ADDRESS -+ -+LC_TELEPHONE -+% This is the ISO/IEC 14652 "i18n" definition for -+% the LC_TELEPHONE category. -+% "+%c %a %l" -+tel_int_fmt "/ -+" -+% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c) -+END LC_TELEPHONE -+ -+LC_MEASUREMENT -+% This is the ISO/IEC 14652 "i18n" definition for -+% the LC_MEASUREMENT category. -+% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c) -+%metric -+measurement 1 -+END LC_MEASUREMENT -+ --- -2.4.3 - diff --git a/glibc-rh1992702-1.patch b/glibc-rh1992702-1.patch new file mode 100644 index 0000000..528156a --- /dev/null +++ b/glibc-rh1992702-1.patch @@ -0,0 +1,102 @@ +Patch proposed for upstream inclusion: + + + +Author: Adhemerval Zanella +Date: Tue Sep 7 09:22:57 2021 -0300 + + misc: Add __get_nprocs_sched + + This is an internal function meant to return the number of avaliable + processor where the process can scheduled, different than the + __get_nprocs which returns a the system available online CPU. + + The Linux implementation currently only calls __get_nprocs(), which + in tuns calls sched_getaffinity. + Reviewed-by: Florian Weimer + +diff --git a/include/sys/sysinfo.h b/include/sys/sysinfo.h +index 7388356a19269335..c490561581733038 100644 +--- a/include/sys/sysinfo.h ++++ b/include/sys/sysinfo.h +@@ -9,10 +9,15 @@ + extern int __get_nprocs_conf (void); + libc_hidden_proto (__get_nprocs_conf) + +-/* Return number of available processors. */ ++/* Return number of available processors (not all of them will be ++ available to the caller process). */ + extern int __get_nprocs (void); + libc_hidden_proto (__get_nprocs) + ++/* Return the number of available processors which the process can ++ be scheduled. */ ++extern int __get_nprocs_sched (void) attribute_hidden; ++ + /* Return number of physical pages of memory in the system. */ + extern long int __get_phys_pages (void); + libc_hidden_proto (__get_phys_pages) +diff --git a/malloc/arena.c b/malloc/arena.c +index 4c398753aeadbb9d..78ef4cf18c780dfc 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -878,7 +878,7 @@ arena_get2 (size_t size, mstate avoid_arena) + narenas_limit = mp_.arena_max; + else if (narenas > mp_.arena_test) + { +- int n = __get_nprocs (); ++ int n = __get_nprocs_sched (); + + if (n >= 1) + narenas_limit = NARENAS_FROM_NCORES (n); +diff --git a/misc/getsysstats.c b/misc/getsysstats.c +index 2986d62247cf98ca..5cbba0f9bd93bd78 100644 +--- a/misc/getsysstats.c ++++ b/misc/getsysstats.c +@@ -44,6 +44,12 @@ weak_alias (__get_nprocs, get_nprocs) + link_warning (get_nprocs, "warning: get_nprocs will always return 1") + + ++int ++__get_nprocs_sched (void) ++{ ++ return 1; ++} ++ + long int + __get_phys_pages (void) + { +diff --git a/sysdeps/mach/getsysstats.c b/sysdeps/mach/getsysstats.c +index 1267f39da26aee38..cc8023f979bf6f74 100644 +--- a/sysdeps/mach/getsysstats.c ++++ b/sysdeps/mach/getsysstats.c +@@ -62,6 +62,12 @@ __get_nprocs (void) + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) + ++int ++__get_nprocs_sched (void) ++{ ++ return __get_nprocs (); ++} ++ + /* Return the number of physical pages on the system. */ + long int + __get_phys_pages (void) +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 8a5d342f0c8bbeae..e9c0dc4d83d4fb2a 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -87,6 +87,12 @@ __get_nprocs (void) + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) + ++int ++__get_nprocs_sched (void) ++{ ++ return __get_nprocs (); ++} ++ + + /* On some architectures it is possible to distinguish between configured + and active cpus. */ diff --git a/glibc-rh1992702-2.patch b/glibc-rh1992702-2.patch new file mode 100644 index 0000000..40fe556 --- /dev/null +++ b/glibc-rh1992702-2.patch @@ -0,0 +1,208 @@ +Patch proposed for upstream inclusion: + + + +Author: Adhemerval Zanella +Date: Tue Sep 7 09:22:58 2021 -0300 + + linux: Simplify get_nprocs + + This patch simplifies the memory allocation code and uses the sched + routines instead of reimplement it. This still uses a stack + allocation buffer, so it can be used on malloc initialization code. + + Linux currently supports at maximum of 4096 cpus for most architectures: + + $ find -iname Kconfig | xargs git grep -A10 -w NR_CPUS | grep -w range + arch/alpha/Kconfig- range 2 32 + arch/arc/Kconfig- range 2 4096 + arch/arm/Kconfig- range 2 16 if DEBUG_KMAP_LOCAL + arch/arm/Kconfig- range 2 32 if !DEBUG_KMAP_LOCAL + arch/arm64/Kconfig- range 2 4096 + arch/csky/Kconfig- range 2 32 + arch/hexagon/Kconfig- range 2 6 if SMP + arch/ia64/Kconfig- range 2 4096 + arch/mips/Kconfig- range 2 256 + arch/openrisc/Kconfig- range 2 32 + arch/parisc/Kconfig- range 2 32 + arch/riscv/Kconfig- range 2 32 + arch/s390/Kconfig- range 2 512 + arch/sh/Kconfig- range 2 32 + arch/sparc/Kconfig- range 2 32 if SPARC32 + arch/sparc/Kconfig- range 2 4096 if SPARC64 + arch/um/Kconfig- range 1 1 + arch/x86/Kconfig-# [NR_CPUS_RANGE_BEGIN ... NR_CPUS_RANGE_END] range. + arch/x86/Kconfig- range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END + arch/xtensa/Kconfig- range 2 32 + + With x86 supporting 8192: + + arch/x86/Kconfig + 976 config NR_CPUS_RANGE_END + 977 int + 978 depends on X86_64 + 979 default 8192 if SMP && CPUMASK_OFFSTACK + 980 default 512 if SMP && !CPUMASK_OFFSTACK + 981 default 1 if !SMP + + So using a maximum of 32k cpu should cover all cases (and I would + expect once we start to have many more CPUs that Linux would provide + a more straightforward way to query for such information). + + A test is added to check if sched_getaffinity can successfully return + with large buffers. + + Checked on x86_64-linux-gnu and i686-linux-gnu. + Reviewed-by: Florian Weimer + +diff --git a/posix/Makefile b/posix/Makefile +index a5229777eeb0e067..61fcdf015b4ec83b 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -107,7 +107,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ + tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ + tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ + bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ +- tst-wordexp-nocmd tst-execveat tst-spawn5 ++ tst-wordexp-nocmd tst-execveat tst-spawn5 \ ++ tst-sched_getaffinity + + # Test for the glob symbol version that was replaced in glibc 2.27. + ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) +diff --git a/posix/tst-sched_getaffinity.c b/posix/tst-sched_getaffinity.c +new file mode 100644 +index 0000000000000000..6d1fdcb05ff4d16c +--- /dev/null ++++ b/posix/tst-sched_getaffinity.c +@@ -0,0 +1,47 @@ ++/* Tests for sched_getaffinity with large buffers. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ /* The values are larger than the default cpu_set_t. */ ++ const int bufsize[] = { 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1<<16, 1<<17 }; ++ int cpucount[array_length(bufsize)]; ++ ++ for (int i = 0; i < array_length (bufsize); i++) ++ { ++ cpu_set_t *cpuset = CPU_ALLOC (bufsize[i]); ++ TEST_VERIFY (cpuset != NULL); ++ size_t size = CPU_ALLOC_SIZE (bufsize[i]); ++ TEST_COMPARE (sched_getaffinity (0, size, cpuset), 0); ++ cpucount[i] = CPU_COUNT_S (size, cpuset); ++ CPU_FREE (cpuset); ++ } ++ ++ for (int i = 0; i < array_length (cpucount) - 1; i++) ++ for (int j = 1; j < array_length (cpucount); j++) ++ TEST_COMPARE (cpucount[i], cpucount[j]); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index e9c0dc4d83d4fb2a..1e3d88676df37f81 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -28,61 +28,29 @@ + #include + #include + +-/* Compute the population count of the entire array. */ +-static int +-__get_nprocs_count (const unsigned long int *array, size_t length) +-{ +- int count = 0; +- for (size_t i = 0; i < length; ++i) +- if (__builtin_add_overflow (count, __builtin_popcountl (array[i]), +- &count)) +- return INT_MAX; +- return count; +-} +- +-/* __get_nprocs with a large buffer. */ +-static int +-__get_nprocs_large (void) +-{ +- /* This code cannot use scratch_buffer because it is used during +- malloc initialization. */ +- size_t pagesize = GLRO (dl_pagesize); +- unsigned long int *page = __mmap (0, pagesize, PROT_READ | PROT_WRITE, +- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +- if (page == MAP_FAILED) +- return 2; +- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, pagesize, page); +- int count; +- if (r > 0) +- count = __get_nprocs_count (page, pagesize / sizeof (unsigned long int)); +- else if (r == -EINVAL) +- /* One page is still not enough to store the bits. A more-or-less +- arbitrary value. This assumes t hat such large systems never +- happen in practice. */ +- count = GLRO (dl_pagesize) * CHAR_BIT; +- else +- count = 2; +- __munmap (page, GLRO (dl_pagesize)); +- return count; +-} +- + int + __get_nprocs (void) + { +- /* Fast path for most systems. The kernel expects a buffer size +- that is a multiple of 8. */ +- unsigned long int small_buffer[1024 / CHAR_BIT / sizeof (unsigned long int)]; +- int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, +- sizeof (small_buffer), small_buffer); ++ enum ++ { ++ max_num_cpus = 32768, ++ cpu_bits_size = CPU_ALLOC_SIZE (32768) ++ }; ++ ++ /* This cannot use malloc because it is used on malloc initialization. */ ++ __cpu_mask cpu_bits[cpu_bits_size / sizeof (__cpu_mask)]; ++ int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size, ++ cpu_bits); + if (r > 0) +- return __get_nprocs_count (small_buffer, r / sizeof (unsigned long int)); ++ return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits); + else if (r == -EINVAL) +- /* The kernel requests a larger buffer to store the data. */ +- return __get_nprocs_large (); +- else +- /* Some other error. 2 is conservative (not a uniprocessor +- system, so atomics are needed). */ +- return 2; ++ /* The input buffer is still not enough to store the number of cpus. This ++ is an arbitrary values assuming such systems should be rare and there ++ is no offline cpus. */ ++ return max_num_cpus; ++ /* Some other error. 2 is conservative (not a uniprocessor system, so ++ atomics are needed). */ ++ return 2; + } + libc_hidden_def (__get_nprocs) + weak_alias (__get_nprocs, get_nprocs) diff --git a/glibc-rh1992702-3.patch b/glibc-rh1992702-3.patch new file mode 100644 index 0000000..e944874 --- /dev/null +++ b/glibc-rh1992702-3.patch @@ -0,0 +1,202 @@ +Patch proposed for upstream inclusion: + + + +Author: Adhemerval Zanella +Date: Tue Sep 7 09:22:59 2021 -0300 + + linux: Revert the use of sched_getaffinity on get_nproc (BZ #28310) + + The use of sched_getaffinity on get_nproc and + sysconf (_SC_NPROCESSORS_ONLN) done in 903bc7dcc2acafc40 (BZ #27645) + breaks the top command in common hypervisor configurations and also + other monitoring tools. + + The main issue using sched_getaffinity changed the symbols semantic + from system-wide scope of online CPUs to per-process one (which can + be changed with kernel cpusets or book parameters in VM). + + This patch reverts mostly of the 903bc7dcc2acafc40, with the + exceptions: + + * No more cached values and atomic updates, since they are inherent + racy. + + * No /proc/cpuinfo fallback, since /proc/stat is already used and + it would require to revert more arch-specific code. + + * The alloca is replace with a static buffer of 1024 bytes. + + So the implementation first consult the sysfs, and fallbacks to procfs. + + Checked on x86_64-linux-gnu. + Reviewed-by: Florian Weimer + +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 1e3d88676df37f81..15ad91cf2f5905ac 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -17,6 +17,8 @@ + . */ + + #include ++#include ++#include + #include + #include + #include +@@ -29,7 +31,7 @@ + #include + + int +-__get_nprocs (void) ++__get_nprocs_sched (void) + { + enum + { +@@ -52,14 +54,141 @@ __get_nprocs (void) + atomics are needed). */ + return 2; + } +-libc_hidden_def (__get_nprocs) +-weak_alias (__get_nprocs, get_nprocs) ++ ++static char * ++next_line (int fd, char *const buffer, char **cp, char **re, ++ char *const buffer_end) ++{ ++ char *res = *cp; ++ char *nl = memchr (*cp, '\n', *re - *cp); ++ if (nl == NULL) ++ { ++ if (*cp != buffer) ++ { ++ if (*re == buffer_end) ++ { ++ memmove (buffer, *cp, *re - *cp); ++ *re = buffer + (*re - *cp); ++ *cp = buffer; ++ ++ ssize_t n = __read_nocancel (fd, *re, buffer_end - *re); ++ if (n < 0) ++ return NULL; ++ ++ *re += n; ++ ++ nl = memchr (*cp, '\n', *re - *cp); ++ while (nl == NULL && *re == buffer_end) ++ { ++ /* Truncate too long lines. */ ++ *re = buffer + 3 * (buffer_end - buffer) / 4; ++ n = __read_nocancel (fd, *re, buffer_end - *re); ++ if (n < 0) ++ return NULL; ++ ++ nl = memchr (*re, '\n', n); ++ **re = '\n'; ++ *re += n; ++ } ++ } ++ else ++ nl = memchr (*cp, '\n', *re - *cp); ++ ++ res = *cp; ++ } ++ ++ if (nl == NULL) ++ nl = *re - 1; ++ } ++ ++ *cp = nl + 1; ++ assert (*cp <= *re); ++ ++ return res == *re ? NULL : res; ++} ++ + + int +-__get_nprocs_sched (void) ++__get_nprocs (void) + { +- return __get_nprocs (); ++ enum { buffer_size = 1024 }; ++ char buffer[buffer_size]; ++ char *buffer_end = buffer + buffer_size; ++ char *cp = buffer_end; ++ char *re = buffer_end; ++ ++ const int flags = O_RDONLY | O_CLOEXEC; ++ /* This file contains comma-separated ranges. */ ++ int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags); ++ char *l; ++ int result = 0; ++ if (fd != -1) ++ { ++ l = next_line (fd, buffer, &cp, &re, buffer_end); ++ if (l != NULL) ++ do ++ { ++ char *endp; ++ unsigned long int n = strtoul (l, &endp, 10); ++ if (l == endp) ++ { ++ result = 0; ++ break; ++ } ++ ++ unsigned long int m = n; ++ if (*endp == '-') ++ { ++ l = endp + 1; ++ m = strtoul (l, &endp, 10); ++ if (l == endp) ++ { ++ result = 0; ++ break; ++ } ++ } ++ ++ result += m - n + 1; ++ ++ l = endp; ++ if (l < re && *l == ',') ++ ++l; ++ } ++ while (l < re && *l != '\n'); ++ ++ __close_nocancel_nostatus (fd); ++ ++ if (result > 0) ++ return result; ++ } ++ ++ cp = buffer_end; ++ re = buffer_end; ++ ++ /* Default to an SMP system in case we cannot obtain an accurate ++ number. */ ++ result = 2; ++ ++ fd = __open_nocancel ("/proc/stat", flags); ++ if (fd != -1) ++ { ++ result = 0; ++ ++ while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL) ++ /* The current format of /proc/stat has all the cpu* entries ++ at the front. We assume here that stays this way. */ ++ if (strncmp (l, "cpu", 3) != 0) ++ break; ++ else if (isdigit (l[3])) ++ ++result; ++ ++ __close_nocancel_nostatus (fd); ++ } ++ ++ return result; + } ++libc_hidden_def (__get_nprocs) ++weak_alias (__get_nprocs, get_nprocs) + + + /* On some architectures it is possible to distinguish between configured diff --git a/glibc-upstream-2.34-1.patch b/glibc-upstream-2.34-1.patch new file mode 100644 index 0000000..c161318 --- /dev/null +++ b/glibc-upstream-2.34-1.patch @@ -0,0 +1,26 @@ +commit 0b03996304f86d6dba8f0d4b7048b9bb7186f17d +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:10 2021 +0530 + + ldconfig: avoid leak on empty paths in config file + + Reviewed-by: Arjun Shankar + (cherry picked from commit b0234d79e7d82475d1666f25326ec045c045b3ed) + +diff --git a/elf/ldconfig.c b/elf/ldconfig.c +index 1037e8d0cf8d28b6..b8893637f8aaea8d 100644 +--- a/elf/ldconfig.c ++++ b/elf/ldconfig.c +@@ -503,7 +503,11 @@ add_dir_1 (const char *line, const char *from_file, int from_line) + entry->path[--i] = '\0'; + + if (i == 0) +- return; ++ { ++ free (entry->path); ++ free (entry); ++ return; ++ } + + char *path = entry->path; + if (opt_chroot != NULL) diff --git a/glibc-upstream-2.34-10.patch b/glibc-upstream-2.34-10.patch new file mode 100644 index 0000000..023ea30 --- /dev/null +++ b/glibc-upstream-2.34-10.patch @@ -0,0 +1,34 @@ +commit f2413f2710d5d5cc884b413b83fcf8198e3717fa +Author: H.J. Lu +Date: Sat Aug 28 06:10:38 2021 -0700 + + x86-64: Use testl to check __x86_string_control + + Use testl, instead of andl, to check __x86_string_control to avoid + updating __x86_string_control. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 3c8b9879cab6d41787bc5b14c1748f62fd6d0e5f) + +diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +index 9f02624375c07b26..abde8438d41f2320 100644 +--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ++++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S +@@ -325,7 +325,7 @@ L(movsb): + /* Avoid slow backward REP MOVSB. */ + jb L(more_8x_vec_backward) + # if AVOID_SHORT_DISTANCE_REP_MOVSB +- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) ++ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) + jz 3f + movq %rdi, %rcx + subq %rsi, %rcx +@@ -333,7 +333,7 @@ L(movsb): + # endif + 1: + # if AVOID_SHORT_DISTANCE_REP_MOVSB +- andl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) ++ testl $X86_STRING_CONTROL_AVOID_SHORT_DISTANCE_REP_MOVSB, __x86_string_control(%rip) + jz 3f + movq %rsi, %rcx + subq %rdi, %rcx diff --git a/glibc-upstream-2.34-11.patch b/glibc-upstream-2.34-11.patch new file mode 100644 index 0000000..47849fb --- /dev/null +++ b/glibc-upstream-2.34-11.patch @@ -0,0 +1,62 @@ +commit 52d0119743180164d1664b6773ac5d873f224608 +Author: Jiaxun Yang +Date: Tue Sep 7 13:31:42 2021 +0800 + + MIPS: Setup errno for {f,l,}xstat + + {f,l,}xstat stub for MIPS is using INTERNAL_SYSCALL + to do xstat syscall for glibc ver, However it leaves + errno untouched and thus giving bad errno output. + + Setup errno properly when syscall returns non-zero. + + Signed-off-by: Jiaxun Yang + Reviewed-by: Adhemerval Zanella + + (cherry picked from commit 66016ec8aeefd40e016d7040d966484c764b0e9c) + +diff --git a/sysdeps/unix/sysv/linux/mips/fxstat.c b/sysdeps/unix/sysv/linux/mips/fxstat.c +index 11511d30b38708ce..4a6016ff123e8dd9 100644 +--- a/sysdeps/unix/sysv/linux/mips/fxstat.c ++++ b/sysdeps/unix/sysv/linux/mips/fxstat.c +@@ -35,7 +35,9 @@ __fxstat (int vers, int fd, struct stat *buf) + { + struct kernel_stat kbuf; + int r = INTERNAL_SYSCALL_CALL (fstat, fd, &kbuf); +- return r ?: __xstat_conv (vers, &kbuf, buf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); + } + } + } +diff --git a/sysdeps/unix/sysv/linux/mips/lxstat.c b/sysdeps/unix/sysv/linux/mips/lxstat.c +index 871fb6c6c5886665..54f990a250677091 100644 +--- a/sysdeps/unix/sysv/linux/mips/lxstat.c ++++ b/sysdeps/unix/sysv/linux/mips/lxstat.c +@@ -35,7 +35,9 @@ __lxstat (int vers, const char *name, struct stat *buf) + { + struct kernel_stat kbuf; + int r = INTERNAL_SYSCALL_CALL (lstat, name, &kbuf); +- return r ?: __xstat_conv (vers, &kbuf, buf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); + } + } + } +diff --git a/sysdeps/unix/sysv/linux/mips/xstat.c b/sysdeps/unix/sysv/linux/mips/xstat.c +index 9d810b6f653b964b..86f4dc31a82ff1bb 100644 +--- a/sysdeps/unix/sysv/linux/mips/xstat.c ++++ b/sysdeps/unix/sysv/linux/mips/xstat.c +@@ -35,7 +35,9 @@ __xstat (int vers, const char *name, struct stat *buf) + { + struct kernel_stat kbuf; + int r = INTERNAL_SYSCALL_CALL (stat, name, &kbuf); +- return r ?: __xstat_conv (vers, &kbuf, buf); ++ if (r == 0) ++ return __xstat_conv (vers, &kbuf, buf); ++ return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r); + } + } + } diff --git a/glibc-upstream-2.34-12.patch b/glibc-upstream-2.34-12.patch new file mode 100644 index 0000000..ef0ec20 --- /dev/null +++ b/glibc-upstream-2.34-12.patch @@ -0,0 +1,117 @@ +commit addc9d62d61eea790a35328cbfce53333a07bd3e +Author: Florian Weimer +Date: Mon Aug 30 13:43:56 2021 +0200 + + support: Add support_wait_for_thread_exit + + (cherry picked from commit 032d74eaf6179100048a5bf0ce942e97dc8b9a60) + +diff --git a/support/Makefile b/support/Makefile +index a462781718426d35..ef2b1a980a407f8f 100644 +--- a/support/Makefile ++++ b/support/Makefile +@@ -82,9 +82,10 @@ libsupport-routines = \ + support_test_compare_blob \ + support_test_compare_failure \ + support_test_compare_string \ +- support_write_file_string \ + support_test_main \ + support_test_verify_impl \ ++ support_wait_for_thread_exit \ ++ support_write_file_string \ + temp_file \ + timespec \ + timespec-time64 \ +diff --git a/support/support.h b/support/support.h +index 834dba909770a992..a5978b939af2fb41 100644 +--- a/support/support.h ++++ b/support/support.h +@@ -174,6 +174,10 @@ timer_t support_create_timer (uint64_t sec, long int nsec, bool repeat, + /* Disable the timer TIMER. */ + void support_delete_timer (timer_t timer); + ++/* Wait until all threads except the current thread have exited (as ++ far as the kernel is concerned). */ ++void support_wait_for_thread_exit (void); ++ + struct support_stack + { + void *stack; +diff --git a/support/support_wait_for_thread_exit.c b/support/support_wait_for_thread_exit.c +new file mode 100644 +index 0000000000000000..658a81381006ea62 +--- /dev/null ++++ b/support/support_wait_for_thread_exit.c +@@ -0,0 +1,72 @@ ++/* Wait until all threads except the current thread has exited. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++support_wait_for_thread_exit (void) ++{ ++#ifdef __linux__ ++ DIR *proc_self_task = opendir ("/proc/self/task"); ++ TEST_VERIFY_EXIT (proc_self_task != NULL); ++ ++ while (true) ++ { ++ errno = 0; ++ struct dirent *e = readdir (proc_self_task); ++ if (e == NULL && errno != 0) ++ FAIL_EXIT1 ("readdir: %m"); ++ if (e == NULL) ++ { ++ /* Only the main thread remains. Testing may continue. */ ++ closedir (proc_self_task); ++ return; ++ } ++ ++ if (strcmp (e->d_name, ".") == 0 || strcmp (e->d_name, "..") == 0) ++ continue; ++ ++ int task_tid = atoi (e->d_name); ++ if (task_tid <= 0) ++ FAIL_EXIT1 ("Invalid /proc/self/task entry: %s", e->d_name); ++ ++ if (task_tid == gettid ()) ++ /* The current thread. Keep scanning for other ++ threads. */ ++ continue; ++ ++ /* task_tid does not refer to this thread here, i.e., there is ++ another running thread. */ ++ ++ /* Small timeout to give the thread a chance to exit. */ ++ usleep (50 * 1000); ++ ++ /* Start scanning the directory from the start. */ ++ rewinddir (proc_self_task); ++ } ++#else ++ /* Use a large timeout because we cannot verify that the thread has ++ exited. */ ++ usleep (5 * 1000 * 1000); ++#endif ++} diff --git a/glibc-upstream-2.34-13.patch b/glibc-upstream-2.34-13.patch new file mode 100644 index 0000000..8f0acc6 --- /dev/null +++ b/glibc-upstream-2.34-13.patch @@ -0,0 +1,279 @@ +commit 3abf3bd4edc86fb28c099cc85203cb46a811e0b8 +Author: Florian Weimer +Date: Mon Sep 13 11:06:08 2021 +0200 + + nptl: pthread_kill, pthread_cancel should not fail after exit (bug 19193) + + This closes one remaining race condition related to bug 12889: if + the thread already exited on the kernel side, returning ESRCH + is not correct because that error is reserved for the thread IDs + (pthread_t values) whose lifetime has ended. In case of a + kernel-side exit and a valid thread ID, no signal needs to be sent + and cancellation does not have an effect, so just return 0. + + sysdeps/pthread/tst-kill4.c triggers undefined behavior and is + removed with this commit. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 8af8456004edbab71f8903a60a3cae442cf6fe69) + +diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c +index cc25ff21f364e8a4..9bac6e3b76a20312 100644 +--- a/nptl/pthread_cancel.c ++++ b/nptl/pthread_cancel.c +@@ -62,10 +62,11 @@ __pthread_cancel (pthread_t th) + { + volatile struct pthread *pd = (volatile struct pthread *) th; + +- /* Make sure the descriptor is valid. */ +- if (INVALID_TD_P (pd)) +- /* Not a valid thread handle. */ +- return ESRCH; ++ if (pd->tid == 0) ++ /* The thread has already exited on the kernel side. Its outcome ++ (regular exit, other cancelation) has already been ++ determined. */ ++ return 0; + + static int init_sigcancel = 0; + if (atomic_load_relaxed (&init_sigcancel) == 0) +diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c +index f79a2b26fc7f72e5..5d4c86f9205a6fb5 100644 +--- a/nptl/pthread_kill.c ++++ b/nptl/pthread_kill.c +@@ -46,7 +46,12 @@ __pthread_kill_internal (pthread_t threadid, int signo) + ? INTERNAL_SYSCALL_ERRNO (val) : 0); + } + else +- val = ESRCH; ++ /* The kernel reports that the thread has exited. POSIX specifies ++ the ESRCH error only for the case when the lifetime of a thread ++ ID has ended, but calling pthread_kill on such a thread ID is ++ undefined in glibc. Therefore, do not treat kernel thread exit ++ as an error. */ ++ val = 0; + + return val; + } +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index 42f9fc507263657d..dedfa0d290da4949 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -89,7 +89,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-join8 tst-join9 tst-join10 tst-join11 tst-join12 tst-join13 \ + tst-join14 tst-join15 \ + tst-key1 tst-key2 tst-key3 tst-key4 \ +- tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \ ++ tst-kill1 tst-kill2 tst-kill3 tst-kill5 tst-kill6 \ + tst-locale1 tst-locale2 \ + tst-memstream \ + tst-mutex-errorcheck tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 \ +@@ -118,6 +118,9 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-unload \ + tst-unwind-thread \ + tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ ++ tst-pthread_cancel-exited \ ++ tst-pthread_kill-exited \ ++ # tests + + tests-time64 := \ + tst-abstime-time64 \ +diff --git a/sysdeps/pthread/tst-kill4.c b/sysdeps/pthread/tst-kill4.c +deleted file mode 100644 +index 9563939792b96ebd..0000000000000000 +--- a/sysdeps/pthread/tst-kill4.c ++++ /dev/null +@@ -1,90 +0,0 @@ +-/* Copyright (C) 2003-2021 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +- +-static void * +-tf (void *a) +-{ +- return NULL; +-} +- +- +-int +-do_test (void) +-{ +- pthread_attr_t at; +- if (pthread_attr_init (&at) != 0) +- { +- puts ("attr_create failed"); +- exit (1); +- } +- +- /* Limit thread stack size, because if it is too large, pthread_join +- will free it immediately rather than put it into stack cache. */ +- if (pthread_attr_setstacksize (&at, 2 * 1024 * 1024) != 0) +- { +- puts ("setstacksize failed"); +- exit (1); +- } +- +- pthread_t th; +- if (pthread_create (&th, &at, tf, NULL) != 0) +- { +- puts ("create failed"); +- exit (1); +- } +- +- pthread_attr_destroy (&at); +- +- if (pthread_join (th, NULL) != 0) +- { +- puts ("join failed"); +- exit (1); +- } +- +- /* The following only works because we assume here something about +- the implementation. Namely, that the memory allocated for the +- thread descriptor is not going away, that the TID field is +- cleared and therefore the signal is sent to process 0, and that +- we can savely assume there is no other process with this ID at +- that time. */ +- int e = pthread_kill (th, 0); +- if (e == 0) +- { +- puts ("pthread_kill succeeded"); +- exit (1); +- } +- if (e != ESRCH) +- { +- puts ("pthread_kill didn't return ESRCH"); +- exit (1); +- } +- +- return 0; +-} +- +- +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" +diff --git a/sysdeps/pthread/tst-pthread_cancel-exited.c b/sysdeps/pthread/tst-pthread_cancel-exited.c +new file mode 100644 +index 0000000000000000..811c9bee07ab2638 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_cancel-exited.c +@@ -0,0 +1,45 @@ ++/* Test that pthread_kill succeeds for an exited thread. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that pthread_kill returns 0 (and not ESRCH) for ++ a thread that has exited on the kernel side. */ ++ ++#include ++#include ++#include ++ ++static void * ++noop_thread (void *closure) ++{ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thr = xpthread_create (NULL, noop_thread, NULL); ++ ++ support_wait_for_thread_exit (); ++ ++ xpthread_cancel (thr); ++ xpthread_join (thr); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c +new file mode 100644 +index 0000000000000000..7575fb6d58cae99c +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_kill-exited.c +@@ -0,0 +1,46 @@ ++/* Test that pthread_kill succeeds for an exited thread. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that pthread_kill returns 0 (and not ESRCH) for ++ a thread that has exited on the kernel side. */ ++ ++#include ++#include ++#include ++#include ++ ++static void * ++noop_thread (void *closure) ++{ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thr = xpthread_create (NULL, noop_thread, NULL); ++ ++ support_wait_for_thread_exit (); ++ ++ xpthread_kill (thr, SIGUSR1); ++ xpthread_join (thr); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.34-14.patch b/glibc-upstream-2.34-14.patch new file mode 100644 index 0000000..9d9c1c5 --- /dev/null +++ b/glibc-upstream-2.34-14.patch @@ -0,0 +1,411 @@ +commit a8ac8c4725ddb1119764126a8674a04c9dd5aea8 +Author: Florian Weimer +Date: Mon Sep 13 11:06:08 2021 +0200 + + nptl: Fix race between pthread_kill and thread exit (bug 12889) + + A new thread exit lock and flag are introduced. They are used to + detect that the thread is about to exit or has exited in + __pthread_kill_internal, and the signal is not sent in this case. + + The test sysdeps/pthread/tst-pthread_cancel-select-loop.c is derived + from a downstream test originally written by Marek Polacek. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 526c3cf11ee9367344b6b15d669e4c3cb461a2be) + +diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c +index cfe37a3443b69454..50065bc9bd8a28e5 100644 +--- a/nptl/allocatestack.c ++++ b/nptl/allocatestack.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + /* Default alignment of stack. */ + #ifndef STACK_ALIGN +@@ -127,6 +128,8 @@ get_cached_stack (size_t *sizep, void **memp) + /* No pending event. */ + result->nextevent = NULL; + ++ result->exiting = false; ++ __libc_lock_init (result->exit_lock); + result->tls_state = (struct tls_internal_t) { 0 }; + + /* Clear the DTV. */ +diff --git a/nptl/descr.h b/nptl/descr.h +index c85778d44941a42f..4de84138fb960fa4 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -396,6 +396,12 @@ struct pthread + PTHREAD_CANCEL_ASYNCHRONOUS). */ + unsigned char canceltype; + ++ /* Used in __pthread_kill_internal to detected a thread that has ++ exited or is about to exit. exit_lock must only be acquired ++ after blocking signals. */ ++ bool exiting; ++ int exit_lock; /* A low-level lock (for use with __libc_lock_init etc). */ ++ + /* Used on strsignal. */ + struct tls_internal_t tls_state; + +diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c +index d8ec299cb1661e82..33b426fc682300dc 100644 +--- a/nptl/pthread_create.c ++++ b/nptl/pthread_create.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + +@@ -485,6 +486,19 @@ start_thread (void *arg) + /* This was the last thread. */ + exit (0); + ++ /* This prevents sending a signal from this thread to itself during ++ its final stages. This must come after the exit call above ++ because atexit handlers must not run with signals blocked. */ ++ __libc_signal_block_all (NULL); ++ ++ /* Tell __pthread_kill_internal that this thread is about to exit. ++ If there is a __pthread_kill_internal in progress, this delays ++ the thread exit until the signal has been queued by the kernel ++ (so that the TID used to send it remains valid). */ ++ __libc_lock_lock (pd->exit_lock); ++ pd->exiting = true; ++ __libc_lock_unlock (pd->exit_lock); ++ + #ifndef __ASSUME_SET_ROBUST_LIST + /* If this thread has any robust mutexes locked, handle them now. */ + # if __PTHREAD_MUTEX_HAVE_PREV +diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c +index 5d4c86f9205a6fb5..fb7862eff787a94f 100644 +--- a/nptl/pthread_kill.c ++++ b/nptl/pthread_kill.c +@@ -16,6 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + #include + #include +@@ -23,37 +24,51 @@ + int + __pthread_kill_internal (pthread_t threadid, int signo) + { +- pid_t tid; + struct pthread *pd = (struct pthread *) threadid; +- + if (pd == THREAD_SELF) +- /* It is a special case to handle raise() implementation after a vfork +- call (which does not update the PD tid field). */ +- tid = INLINE_SYSCALL_CALL (gettid); +- else +- /* Force load of pd->tid into local variable or register. Otherwise +- if a thread exits between ESRCH test and tgkill, we might return +- EINVAL, because pd->tid would be cleared by the kernel. */ +- tid = atomic_forced_read (pd->tid); +- +- int val; +- if (__glibc_likely (tid > 0)) + { +- pid_t pid = __getpid (); +- +- val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); +- val = (INTERNAL_SYSCALL_ERROR_P (val) +- ? INTERNAL_SYSCALL_ERRNO (val) : 0); ++ /* Use the actual TID from the kernel, so that it refers to the ++ current thread even if called after vfork. There is no ++ signal blocking in this case, so that the signal is delivered ++ immediately, before __pthread_kill_internal returns: a signal ++ sent to the thread itself needs to be delivered ++ synchronously. (It is unclear if Linux guarantees the ++ delivery of all pending signals after unblocking in the code ++ below. POSIX only guarantees delivery of a single signal, ++ which may not be the right one.) */ ++ pid_t tid = INTERNAL_SYSCALL_CALL (gettid); ++ int ret = INTERNAL_SYSCALL_CALL (kill, tid, signo); ++ return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; + } ++ ++ /* Block all signals, as required by pd->exit_lock. */ ++ sigset_t old_mask; ++ __libc_signal_block_all (&old_mask); ++ __libc_lock_lock (pd->exit_lock); ++ ++ int ret; ++ if (pd->exiting) ++ /* The thread is about to exit (or has exited). Sending the ++ signal is either not observable (the target thread has already ++ blocked signals at this point), or it will fail, or it might be ++ delivered to a new, unrelated thread that has reused the TID. ++ So do not actually send the signal. Do not report an error ++ because the threadid argument is still valid (the thread ID ++ lifetime has not ended), and ESRCH (for example) would be ++ misleading. */ ++ ret = 0; + else +- /* The kernel reports that the thread has exited. POSIX specifies +- the ESRCH error only for the case when the lifetime of a thread +- ID has ended, but calling pthread_kill on such a thread ID is +- undefined in glibc. Therefore, do not treat kernel thread exit +- as an error. */ +- val = 0; ++ { ++ /* Using tgkill is a safety measure. pd->exit_lock ensures that ++ the target thread cannot exit. */ ++ ret = INTERNAL_SYSCALL_CALL (tgkill, __getpid (), pd->tid, signo); ++ ret = INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; ++ } ++ ++ __libc_lock_unlock (pd->exit_lock); ++ __libc_signal_restore_set (&old_mask); + +- return val; ++ return ret; + } + + int +diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile +index dedfa0d290da4949..48dba717a1cdc20a 100644 +--- a/sysdeps/pthread/Makefile ++++ b/sysdeps/pthread/Makefile +@@ -119,7 +119,9 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ + tst-unwind-thread \ + tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ + tst-pthread_cancel-exited \ ++ tst-pthread_cancel-select-loop \ + tst-pthread_kill-exited \ ++ tst-pthread_kill-exiting \ + # tests + + tests-time64 := \ +diff --git a/sysdeps/pthread/tst-pthread_cancel-select-loop.c b/sysdeps/pthread/tst-pthread_cancel-select-loop.c +new file mode 100644 +index 0000000000000000..a62087589cee24b5 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_cancel-select-loop.c +@@ -0,0 +1,87 @@ ++/* Test that pthread_cancel succeeds during thread exit. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test tries to trigger an internal race condition in ++ pthread_cancel, where the cancellation signal is sent after the ++ thread has begun the cancellation process. This can result in a ++ spurious ESRCH error. For the original bug 12889, the window is ++ quite small, so the bug was not reproduced in every run. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Set to true by timeout_thread_function when the test should ++ terminate. */ ++static bool timeout; ++ ++static void * ++timeout_thread_function (void *unused) ++{ ++ usleep (5 * 1000 * 1000); ++ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED); ++ return NULL; ++} ++ ++/* Used for blocking the select function below. */ ++static int pipe_fds[2]; ++ ++static void * ++canceled_thread_function (void *unused) ++{ ++ while (true) ++ { ++ fd_set rfs; ++ fd_set wfs; ++ fd_set efs; ++ FD_ZERO (&rfs); ++ FD_ZERO (&wfs); ++ FD_ZERO (&efs); ++ FD_SET (pipe_fds[0], &rfs); ++ ++ /* If the cancellation request is recognized early, the thread ++ begins exiting while the cancellation signal arrives. */ ++ select (FD_SETSIZE, &rfs, &wfs, &efs, NULL); ++ } ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xpipe (pipe_fds); ++ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL); ++ ++ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED)) ++ { ++ pthread_t thr = xpthread_create (NULL, canceled_thread_function, NULL); ++ xpthread_cancel (thr); ++ TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED); ++ } ++ ++ xpthread_join (thr_timeout); ++ xclose (pipe_fds[0]); ++ xclose (pipe_fds[1]); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/pthread/tst-pthread_kill-exiting.c b/sysdeps/pthread/tst-pthread_kill-exiting.c +new file mode 100644 +index 0000000000000000..f803e94f1195f204 +--- /dev/null ++++ b/sysdeps/pthread/tst-pthread_kill-exiting.c +@@ -0,0 +1,123 @@ ++/* Test that pthread_kill succeeds during thread exit. ++ Copyright (C) 2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that pthread_kill for a thread that is exiting ++ succeeds (with or without actually delivering the signal). */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Set to true by timeout_thread_function when the test should ++ terminate. */ ++static bool timeout; ++ ++static void * ++timeout_thread_function (void *unused) ++{ ++ usleep (1000 * 1000); ++ __atomic_store_n (&timeout, true, __ATOMIC_RELAXED); ++ return NULL; ++} ++ ++/* Used to synchronize the sending threads with the target thread and ++ main thread. */ ++static pthread_barrier_t barrier_1; ++static pthread_barrier_t barrier_2; ++ ++/* The target thread to which signals are to be sent. */ ++static pthread_t target_thread; ++ ++/* Set by the main thread to true after timeout has been set to ++ true. */ ++static bool exiting; ++ ++static void * ++sender_thread_function (void *unused) ++{ ++ while (true) ++ { ++ /* Wait until target_thread has been initialized. The target ++ thread and main thread participate in this barrier. */ ++ xpthread_barrier_wait (&barrier_1); ++ ++ if (exiting) ++ break; ++ ++ xpthread_kill (target_thread, SIGUSR1); ++ ++ /* Communicate that the signal has been sent. The main thread ++ participates in this barrier. */ ++ xpthread_barrier_wait (&barrier_2); ++ } ++ return NULL; ++} ++ ++static void * ++target_thread_function (void *unused) ++{ ++ target_thread = pthread_self (); ++ xpthread_barrier_wait (&barrier_1); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ xsignal (SIGUSR1, SIG_IGN); ++ ++ pthread_t thr_timeout = xpthread_create (NULL, timeout_thread_function, NULL); ++ ++ pthread_t threads[4]; ++ xpthread_barrier_init (&barrier_1, NULL, array_length (threads) + 2); ++ xpthread_barrier_init (&barrier_2, NULL, array_length (threads) + 1); ++ ++ for (int i = 0; i < array_length (threads); ++i) ++ threads[i] = xpthread_create (NULL, sender_thread_function, NULL); ++ ++ while (!__atomic_load_n (&timeout, __ATOMIC_RELAXED)) ++ { ++ xpthread_create (NULL, target_thread_function, NULL); ++ ++ /* Wait for the target thread to be set up and signal sending to ++ start. */ ++ xpthread_barrier_wait (&barrier_1); ++ ++ /* Wait for signal sending to complete. */ ++ xpthread_barrier_wait (&barrier_2); ++ ++ xpthread_join (target_thread); ++ } ++ ++ exiting = true; ++ ++ /* Signal the sending threads to exit. */ ++ xpthread_create (NULL, target_thread_function, NULL); ++ xpthread_barrier_wait (&barrier_1); ++ ++ for (int i = 0; i < array_length (threads); ++i) ++ xpthread_join (threads[i]); ++ xpthread_join (thr_timeout); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.34-15.patch b/glibc-upstream-2.34-15.patch new file mode 100644 index 0000000..a2275fb --- /dev/null +++ b/glibc-upstream-2.34-15.patch @@ -0,0 +1,117 @@ +commit 3fc51f35b4f32e1bb99d85c1578e930e725ff929 +Author: Siddhesh Poyarekar +Date: Mon Sep 13 20:48:35 2021 +0530 + + iconvconfig: Fix behaviour with --prefix [BZ #28199] + + The consolidation of configuration parsing broke behaviour with + --prefix, where the prefix bled into the modules cache. Accept a + prefix which, when non-NULL, is prepended to the path when looking for + configuration files but only the original directory is added to the + modules cache. + + This has no effect on the codegen of gconv_conf since it passes NULL. + + Reported-by: Patrick McCarty + Reported-by: Michael Hudson-Doyle + Reviewed-by: Andreas Schwab + (cherry picked from commit 43cea6d5652b6b9e61ac6ecc69419c909b504f47) + +diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c +index 62bee28769deb979..cc391d8f936687f3 100644 +--- a/iconv/gconv_conf.c ++++ b/iconv/gconv_conf.c +@@ -478,7 +478,7 @@ __gconv_read_conf (void) + __gconv_get_path (); + + for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt) +- gconv_parseconfdir (__gconv_path_elem[cnt].name, ++ gconv_parseconfdir (NULL, __gconv_path_elem[cnt].name, + __gconv_path_elem[cnt].len); + #endif + +diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h +index 2f062689ecc72749..a586268abc103abd 100644 +--- a/iconv/gconv_parseconfdir.h ++++ b/iconv/gconv_parseconfdir.h +@@ -39,7 +39,6 @@ + /* Name of the file containing the module information in the directories + along the path. */ + static const char gconv_conf_filename[] = "gconv-modules"; +-static const char gconv_conf_dirname[] = "gconv-modules.d"; + + static void add_alias (char *); + static void add_module (char *, const char *, size_t, int); +@@ -110,19 +109,28 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len) + return true; + } + ++/* Prefix DIR (with length DIR_LEN) with PREFIX if the latter is non-NULL and ++ parse configuration in it. */ ++ + static __always_inline bool +-gconv_parseconfdir (const char *dir, size_t dir_len) ++gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len) + { +- /* No slash needs to be inserted between dir and gconv_conf_filename; +- dir already ends in a slash. */ +- char *buf = malloc (dir_len + sizeof (gconv_conf_dirname)); ++ /* No slash needs to be inserted between dir and gconv_conf_filename; dir ++ already ends in a slash. The additional 2 is to accommodate the ".d" ++ when looking for configuration files in gconv-modules.d. */ ++ size_t buflen = dir_len + sizeof (gconv_conf_filename) + 2; ++ char *buf = malloc (buflen + (prefix != NULL ? strlen (prefix) : 0)); ++ char *cp = buf; + bool found = false; + + if (buf == NULL) + return false; + +- char *cp = mempcpy (mempcpy (buf, dir, dir_len), gconv_conf_filename, +- sizeof (gconv_conf_filename)); ++ if (prefix != NULL) ++ cp = stpcpy (cp, prefix); ++ ++ cp = mempcpy (mempcpy (cp, dir, dir_len), gconv_conf_filename, ++ sizeof (gconv_conf_filename)); + + /* Read the gconv-modules configuration file first. */ + found = read_conf_file (buf, dir, dir_len); +diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c +index 783b2bbdbb684ac6..273a71f67315f670 100644 +--- a/iconv/iconvconfig.c ++++ b/iconv/iconvconfig.c +@@ -653,13 +653,21 @@ add_module (char *rp, const char *directory, + static int + handle_dir (const char *dir) + { ++ char *newp = NULL; + size_t dirlen = strlen (dir); + bool found = false; + +- char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "", +- dir, dir[dirlen - 1] != '/' ? "/" : ""); ++ /* End directory path with a '/' if it doesn't already. */ ++ if (dir[dirlen - 1] != '/') ++ { ++ newp = xmalloc (dirlen + 2); ++ memcpy (newp, dir, dirlen); ++ newp[dirlen++] = '/'; ++ newp[dirlen] = '\0'; ++ dir = newp; ++ } + +- found = gconv_parseconfdir (fulldir, strlen (fulldir)); ++ found = gconv_parseconfdir (dir[0] == '/' ? prefix : NULL, dir, dirlen); + + if (!found) + { +@@ -671,7 +679,7 @@ handle_dir (const char *dir) + "configuration files with names ending in .conf."); + } + +- free (fulldir); ++ free (newp); + + return found ? 0 : 1; + } diff --git a/glibc-upstream-2.34-16.patch b/glibc-upstream-2.34-16.patch new file mode 100644 index 0000000..3d8a568 --- /dev/null +++ b/glibc-upstream-2.34-16.patch @@ -0,0 +1,31 @@ +commit ae925404a10bf0ea63d6e8d41e3821f68b4d776c +Author: Aurelien Jarno +Date: Fri Sep 3 00:28:14 2021 +0200 + + Fix failing nss/tst-nss-files-hosts-long with local resolver + + When a local resolver like unbound is listening on the IPv4 loopback + address 127.0.0.1, the nss/tst-nss-files-hosts-long test fails. This is + due to: + - the default resolver in the absence of resolv.conf being 127.0.0.1 + - the default DNS NSS database configuration in the absence of + nsswitch.conf being 'hosts: dns [!UNAVAIL=return] file' + + This causes the requests for 'test4' and 'test6' to first be sent to the + local resolver, which responds with NXDOMAIN in the likely case those + records do no exist. In turn that causes the access to /etc/hosts to be + skipped, which is the purpose of that test. + + Fix that by providing a simple nsswitch.conf file forcing access to + /etc/hosts for that test. I have tested that the only changed result in + the testsuite is that test. + + (cherry picked from commit 2738480a4b0866723fb8c633f36bdd34a8767581) + +diff --git a/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf +new file mode 100644 +index 0000000000000000..5b0c6a419937a013 +--- /dev/null ++++ b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf +@@ -0,0 +1 @@ ++hosts: files diff --git a/glibc-upstream-2.34-17.patch b/glibc-upstream-2.34-17.patch new file mode 100644 index 0000000..ca37faa --- /dev/null +++ b/glibc-upstream-2.34-17.patch @@ -0,0 +1,26 @@ +commit 007d699d0e0d0957eead78ad252ad592656284de +Author: Joseph Myers +Date: Tue Sep 7 13:08:38 2021 +0000 + + Use Linux 5.14 in build-many-glibcs.py + + This patch makes build-many-glibcs.py use Linux 5.14. + + Tested with build-many-glibcs.py (host-libraries, compilers and glibcs + builds). + + (cherry picked from commit 4e04a47208e1712fcf202a6d9831f0900d575225) + +diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py +index 5a77af90a6b49909..86537fa8005cfd3d 100755 +--- a/scripts/build-many-glibcs.py ++++ b/scripts/build-many-glibcs.py +@@ -782,7 +782,7 @@ class Context(object): + 'gcc': 'vcs-11', + 'glibc': 'vcs-mainline', + 'gmp': '6.2.1', +- 'linux': '5.13', ++ 'linux': '5.14', + 'mpc': '1.2.1', + 'mpfr': '4.1.0', + 'mig': 'vcs-mainline', diff --git a/glibc-upstream-2.34-18.patch b/glibc-upstream-2.34-18.patch new file mode 100644 index 0000000..017225a --- /dev/null +++ b/glibc-upstream-2.34-18.patch @@ -0,0 +1,377 @@ +commit 005bafcf5b8a85d4c82831401f052747e160a7e8 +Author: Joseph Myers +Date: Wed Sep 8 12:42:06 2021 +0000 + + Update syscall lists for Linux 5.14 + + Linux 5.14 has two new syscalls, memfd_secret (on some architectures + only) and quotactl_fd. Update syscall-names.list and regenerate the + arch-syscall.h headers with build-many-glibcs.py update-syscalls. + + Tested with build-many-glibcs.py. + + (cherry picked from commit 89dc0372a9055e7ef86fe19be6201fa0b16b2f0e) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +index e9eb707d0ac022ed..bedab1abbac7f6c1 100644 +--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h +@@ -126,6 +126,7 @@ + #define __NR_mbind 235 + #define __NR_membarrier 283 + #define __NR_memfd_create 279 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 238 + #define __NR_mincore 232 + #define __NR_mkdirat 34 +@@ -187,6 +188,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +index bd6b7d4003a252be..91354ed9e29b8d15 100644 +--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h +@@ -337,6 +337,7 @@ + #define __NR_pwritev2 521 + #define __NR_query_module 347 + #define __NR_quotactl 148 ++#define __NR_quotactl_fd 553 + #define __NR_read 3 + #define __NR_readahead 379 + #define __NR_readlink 58 +diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +index 10650549c1dcd100..ff5c7eb36db89494 100644 +--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h +@@ -190,6 +190,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +index 85c9b236ce7862b6..5772333ceef6ce59 100644 +--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h +@@ -244,6 +244,7 @@ + #define __NR_pwritev 362 + #define __NR_pwritev2 393 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readlink 85 +diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +index 24b0d1f94e5f99da..4af6d6202f6df7ae 100644 +--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h +@@ -199,6 +199,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +index feb70abc3e1eb486..b07fc8549de34157 100644 +--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h +@@ -231,6 +231,7 @@ + #define __NR_pwritev 316 + #define __NR_pwritev2 348 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 207 + #define __NR_readlink 85 +diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +index 3b1894a79b6fcfaf..6e4264698b5ce480 100644 +--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h +@@ -183,6 +183,7 @@ + #define __NR_mbind 274 + #define __NR_membarrier 375 + #define __NR_memfd_create 356 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 294 + #define __NR_mincore 218 + #define __NR_mkdir 39 +@@ -266,6 +267,7 @@ + #define __NR_pwritev2 379 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +index fb388a5fa4e9b28e..1ca706d7216a3902 100644 +--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h +@@ -218,6 +218,7 @@ + #define __NR_pwritev 1320 + #define __NR_pwritev2 1349 + #define __NR_quotactl 1137 ++#define __NR_quotactl_fd 1467 + #define __NR_read 1026 + #define __NR_readahead 1216 + #define __NR_readlink 1092 +diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +index 7bc8c4af92cf2bd3..2f10f71f90d225ff 100644 +--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h +@@ -254,6 +254,7 @@ + #define __NR_pwritev2 378 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 240 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +index cf560d3af47f19c5..0607a4dfa6adaa23 100644 +--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h +@@ -266,6 +266,7 @@ + #define __NR_pwritev2 394 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +index f346460f4880f10e..0055eec0b169ba96 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h +@@ -251,6 +251,7 @@ + #define __NR_pwritev2 4362 + #define __NR_query_module 4187 + #define __NR_quotactl 4131 ++#define __NR_quotactl_fd 4443 + #define __NR_read 4003 + #define __NR_readahead 4223 + #define __NR_readdir 4089 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +index 38ed84997a2fa3d1..8e8e9f91ccfebfab 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h +@@ -232,6 +232,7 @@ + #define __NR_pwritev2 6326 + #define __NR_query_module 6171 + #define __NR_quotactl 6172 ++#define __NR_quotactl_fd 6443 + #define __NR_read 6000 + #define __NR_readahead 6179 + #define __NR_readlink 6087 +diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +index e6a10c842178168c..ebd1545f806564bb 100644 +--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h +@@ -219,6 +219,7 @@ + #define __NR_pwritev2 5322 + #define __NR_query_module 5171 + #define __NR_quotactl 5172 ++#define __NR_quotactl_fd 5443 + #define __NR_read 5000 + #define __NR_readahead 5179 + #define __NR_readlink 5087 +diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +index 5314890289a1723f..2b530b1f88e4c52a 100644 +--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h +@@ -198,6 +198,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +index b5b075853297cf2e..a32984a9c17315ee 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h +@@ -260,6 +260,7 @@ + #define __NR_pwritev2 381 + #define __NR_query_module 166 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 191 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +index c77435ca61aba109..b01e464fb906d632 100644 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h +@@ -243,6 +243,7 @@ + #define __NR_pwritev2 381 + #define __NR_query_module 166 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 191 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index 70854bb9e360b40a..24d0a2c455caa630 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +@@ -179,6 +179,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +index 83b9f31abaee9d52..e526c89ae7b285cc 100644 +--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h +@@ -187,6 +187,7 @@ + #define __NR_pwritev 70 + #define __NR_pwritev2 287 + #define __NR_quotactl 60 ++#define __NR_quotactl_fd 443 + #define __NR_read 63 + #define __NR_readahead 213 + #define __NR_readlinkat 78 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +index b224c4aad4c9b1b1..d4c7b101b64c010f 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h +@@ -251,6 +251,7 @@ + #define __NR_pwritev2 377 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 222 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +index 59864af125b437e4..bd8c78d7059a0f31 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h +@@ -221,6 +221,7 @@ + #define __NR_pwritev2 377 + #define __NR_query_module 167 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 222 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +index 23612c9092b9c2ee..3b6ac3d084d74638 100644 +--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h +@@ -246,6 +246,7 @@ + #define __NR_pwritev 334 + #define __NR_pwritev2 382 + #define __NR_quotactl 131 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 225 + #define __NR_readdir 89 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +index 380cddb2d8f9f443..35221a707e4d4a7c 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h +@@ -252,6 +252,7 @@ + #define __NR_pwritev2 359 + #define __NR_query_module 184 + #define __NR_quotactl 165 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 205 + #define __NR_readdir 204 +diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +index 2175eeb6edcf7c34..5ba2b2050924df1c 100644 +--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h +@@ -231,6 +231,7 @@ + #define __NR_pwritev2 359 + #define __NR_query_module 184 + #define __NR_quotactl 165 ++#define __NR_quotactl_fd 443 + #define __NR_read 3 + #define __NR_readahead 205 + #define __NR_readdir 204 +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +index 89c5895b9b6845ff..fd98893b0e44a606 100644 +--- a/sysdeps/unix/sysv/linux/syscall-names.list ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -21,8 +21,8 @@ + # This file can list all potential system calls. The names are only + # used if the installed kernel headers also provide them. + +-# The list of system calls is current as of Linux 5.13. +-kernel 5.13 ++# The list of system calls is current as of Linux 5.14. ++kernel 5.14 + + FAST_atomic_update + FAST_cmpxchg +@@ -247,6 +247,7 @@ madvise + mbind + membarrier + memfd_create ++memfd_secret + memory_ordering + migrate_pages + mincore +@@ -452,6 +453,7 @@ pwritev + pwritev2 + query_module + quotactl ++quotactl_fd + read + readahead + readdir +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +index 8e028eb62be2041d..26d6ac68a651ec98 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h +@@ -154,6 +154,7 @@ + #define __NR_mbind 237 + #define __NR_membarrier 324 + #define __NR_memfd_create 319 ++#define __NR_memfd_secret 447 + #define __NR_migrate_pages 256 + #define __NR_mincore 27 + #define __NR_mkdir 83 +@@ -224,6 +225,7 @@ + #define __NR_pwritev2 328 + #define __NR_query_module 178 + #define __NR_quotactl 179 ++#define __NR_quotactl_fd 443 + #define __NR_read 0 + #define __NR_readahead 187 + #define __NR_readlink 89 +diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +index 004feb53f1f38ced..36847783f6b91d5e 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h ++++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h +@@ -148,6 +148,7 @@ + #define __NR_mbind 1073742061 + #define __NR_membarrier 1073742148 + #define __NR_memfd_create 1073742143 ++#define __NR_memfd_secret 1073742271 + #define __NR_migrate_pages 1073742080 + #define __NR_mincore 1073741851 + #define __NR_mkdir 1073741907 +@@ -216,6 +217,7 @@ + #define __NR_pwritev 1073742359 + #define __NR_pwritev2 1073742371 + #define __NR_quotactl 1073742003 ++#define __NR_quotactl_fd 1073742267 + #define __NR_read 1073741824 + #define __NR_readahead 1073742011 + #define __NR_readlink 1073741913 diff --git a/glibc-upstream-2.34-19.patch b/glibc-upstream-2.34-19.patch new file mode 100644 index 0000000..b0f0b9a --- /dev/null +++ b/glibc-upstream-2.34-19.patch @@ -0,0 +1,27 @@ +commit 114581bf53864aaee562ee237461fc394bc61963 +Author: Joseph Myers +Date: Tue Sep 14 13:51:58 2021 +0000 + + Update kernel version to 5.14 in tst-mman-consts.py + + This patch updates the kernel version in the test tst-mman-consts.py + to 5.14. (There are no new MAP_* constants covered by this test in + 5.14 that need any other header changes.) + + Tested with build-many-glibcs.py. + + (cherry picked from commit 4b39e3498324d1aea802fea8d4b8764f5ddb4fd1) + +diff --git a/sysdeps/unix/sysv/linux/tst-mman-consts.py b/sysdeps/unix/sysv/linux/tst-mman-consts.py +index ee5b13ee1232fdf5..810433c238f31c25 100644 +--- a/sysdeps/unix/sysv/linux/tst-mman-consts.py ++++ b/sysdeps/unix/sysv/linux/tst-mman-consts.py +@@ -33,7 +33,7 @@ def main(): + help='C compiler (including options) to use') + args = parser.parse_args() + linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) +- linux_version_glibc = (5, 13) ++ linux_version_glibc = (5, 14) + sys.exit(glibcextract.compare_macro_consts( + '#define _GNU_SOURCE 1\n' + '#include \n', diff --git a/glibc-upstream-2.34-2.patch b/glibc-upstream-2.34-2.patch new file mode 100644 index 0000000..fbddab3 --- /dev/null +++ b/glibc-upstream-2.34-2.patch @@ -0,0 +1,33 @@ +commit 3a48da47a91ccc6f5de260574809e7a44551b876 +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:20 2021 +0530 + + gconv_parseconfdir: Fix memory leak + + The allocated `conf` would leak if we have to skip over the file due + to the underlying filesystem not supporting dt_type. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 5f9b78fe35d08739b6da1e5b356786d41116c108) + +diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h +index a4153e54c6d43797..2f062689ecc72749 100644 +--- a/iconv/gconv_parseconfdir.h ++++ b/iconv/gconv_parseconfdir.h +@@ -153,12 +153,11 @@ gconv_parseconfdir (const char *dir, size_t dir_len) + struct stat64 st; + if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0) + continue; +- if (ent->d_type == DT_UNKNOWN +- && (lstat64 (conf, &st) == -1 +- || !S_ISREG (st.st_mode))) +- continue; + +- found |= read_conf_file (conf, dir, dir_len); ++ if (ent->d_type != DT_UNKNOWN ++ || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode))) ++ found |= read_conf_file (conf, dir, dir_len); ++ + free (conf); + } + } diff --git a/glibc-upstream-2.34-20.patch b/glibc-upstream-2.34-20.patch new file mode 100644 index 0000000..f4b1aed --- /dev/null +++ b/glibc-upstream-2.34-20.patch @@ -0,0 +1,29 @@ +commit 4ed990e5b97a61f29f929bdeb36c5b2abb547a64 +Author: Joseph Myers +Date: Tue Sep 14 14:19:24 2021 +0000 + + Add MADV_POPULATE_READ and MADV_POPULATE_WRITE from Linux 5.14 to bits/mman-linux.h + + Linux 5.14 adds constants MADV_POPULATE_READ and MADV_POPULATE_WRITE + (with the same values on all architectures). Add these to glibc's + bits/mman-linux.h. + + Tested for x86_64. + + (cherry picked from commit 3561106278cddd2f007bd27fd4c3e90caaf14b43) + +diff --git a/sysdeps/unix/sysv/linux/bits/mman-linux.h b/sysdeps/unix/sysv/linux/bits/mman-linux.h +index 3b1ae418e073c122..31451c28d93f9f72 100644 +--- a/sysdeps/unix/sysv/linux/bits/mman-linux.h ++++ b/sysdeps/unix/sysv/linux/bits/mman-linux.h +@@ -89,6 +89,10 @@ + # define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK. */ + # define MADV_COLD 20 /* Deactivate these pages. */ + # define MADV_PAGEOUT 21 /* Reclaim these pages. */ ++# define MADV_POPULATE_READ 22 /* Populate (prefault) page tables ++ readable. */ ++# define MADV_POPULATE_WRITE 23 /* Populate (prefault) page tables ++ writable. */ + # define MADV_HWPOISON 100 /* Poison a page for testing. */ + #endif + diff --git a/glibc-upstream-2.34-3.patch b/glibc-upstream-2.34-3.patch new file mode 100644 index 0000000..136cbf2 --- /dev/null +++ b/glibc-upstream-2.34-3.patch @@ -0,0 +1,32 @@ +commit a5bd2e10e0c25b80286dc36068e22a4cb4893af0 +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:11:03 2021 +0530 + + gaiconf_init: Avoid double-free in label and precedence lists + + labellist and precedencelist could get freed a second time if there + are allocation failures, so set them to NULL to avoid a double-free. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 77a34079d8f3d63b61543bf3af93043f8674e4c4) + +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 838a68f0229b5aa8..43dfc6739e350a58 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -2008,6 +2008,7 @@ gaiconf_init (void) + l = l->next; + } + free_prefixlist (labellist); ++ labellist = NULL; + + /* Sort the entries so that the most specific ones are at + the beginning. */ +@@ -2046,6 +2047,7 @@ gaiconf_init (void) + l = l->next; + } + free_prefixlist (precedencelist); ++ precedencelist = NULL; + + /* Sort the entries so that the most specific ones are at + the beginning. */ diff --git a/glibc-upstream-2.34-4.patch b/glibc-upstream-2.34-4.patch new file mode 100644 index 0000000..12ce5e6 --- /dev/null +++ b/glibc-upstream-2.34-4.patch @@ -0,0 +1,24 @@ +commit 7ff4da3dc26de351a5abe7c2905038cbe55c8041 +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:53 2021 +0530 + + copy_and_spawn_sgid: Avoid double calls to close() + + If close() on infd and outfd succeeded, reset the fd numbers so that + we don't attempt to close them again. + + Reviewed-by: Arjun Shankar + (cherry picked from commit 45caed9d67a00af917d8b5b88d4b5eb1225b7aef) + +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +index 27bfd19c9374a183..0bacf6dbc23b0732 100644 +--- a/support/support_capture_subprocess.c ++++ b/support/support_capture_subprocess.c +@@ -170,6 +170,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid) + support_subprogram because we only want the program exit status, not the + contents. */ + ret = 0; ++ infd = outfd = -1; + + char * const args[] = {execname, child_id, NULL}; + diff --git a/glibc-upstream-2.34-5.patch b/glibc-upstream-2.34-5.patch new file mode 100644 index 0000000..fe8b853 --- /dev/null +++ b/glibc-upstream-2.34-5.patch @@ -0,0 +1,22 @@ +commit 9995d0588f4f9adc68419224d2b3698e2ca4f77e +Author: Siddhesh Poyarekar +Date: Tue Aug 3 21:10:29 2021 +0530 + + iconv_charmap: Close output file when done + + Reviewed-by: Arjun Shankar + (cherry picked from commit 1e0e6d656db9dfa12ef7eb67976385d3deb0d4ff) + +diff --git a/iconv/iconv_charmap.c b/iconv/iconv_charmap.c +index e2d53fee3cbfbb7a..a8b6b56124909f6c 100644 +--- a/iconv/iconv_charmap.c ++++ b/iconv/iconv_charmap.c +@@ -234,6 +234,8 @@ charmap_conversion (const char *from_code, struct charmap_t *from_charmap, + while (++remaining < argc); + + /* All done. */ ++ if (output != stdout) ++ fclose (output); + free_table (cvtbl); + return status; + } diff --git a/glibc-upstream-2.34-6.patch b/glibc-upstream-2.34-6.patch new file mode 100644 index 0000000..5e6a43d --- /dev/null +++ b/glibc-upstream-2.34-6.patch @@ -0,0 +1,65 @@ +commit 31902ae639d6a50e768a85f1cd2a17e56b8463c2 +Author: Florian Weimer +Date: Fri Aug 6 09:51:38 2021 +0200 + + Linux: Fix fcntl, ioctl, prctl redirects for _TIME_BITS=64 (bug 28182) + + __REDIRECT and __THROW are not compatible with C++ due to the ordering of the + __asm__ alias and the throw specifier. __REDIRECT_NTH has to be used + instead. + + Fixes commit 8a40aff86ba5f64a3a84883e539cb67b ("io: Add time64 alias + for fcntl"), commit 82c395d91ea4f69120d453aeec398e30 ("misc: Add + time64 alias for ioctl"), commit b39ffab860cd743a82c91946619f1b8158 + ("Linux: Add time64 alias for prctl"). + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c87fcacc50505d550f1bb038382bcc7ea73a5926) + +diff --git a/io/fcntl.h b/io/fcntl.h +index 8917a73b420b503d..1c96f98f4d75ce65 100644 +--- a/io/fcntl.h ++++ b/io/fcntl.h +@@ -187,10 +187,10 @@ extern int fcntl64 (int __fd, int __cmd, ...); + # endif + #else /* __USE_TIME_BITS64 */ + # ifdef __REDIRECT +-extern int __REDIRECT (fcntl, (int __fd, int __request, ...), +- __fcntl_time64) __THROW; +-extern int __REDIRECT (fcntl64, (int __fd, int __request, ...), +- __fcntl_time64) __THROW; ++extern int __REDIRECT_NTH (fcntl, (int __fd, int __request, ...), ++ __fcntl_time64); ++extern int __REDIRECT_NTH (fcntl64, (int __fd, int __request, ...), ++ __fcntl_time64); + # else + extern int __fcntl_time64 (int __fd, int __request, ...) __THROW; + # define fcntl64 __fcntl_time64 +diff --git a/misc/sys/ioctl.h b/misc/sys/ioctl.h +index 6884d9925f06125f..9945c1e9181eb313 100644 +--- a/misc/sys/ioctl.h ++++ b/misc/sys/ioctl.h +@@ -42,8 +42,8 @@ __BEGIN_DECLS + extern int ioctl (int __fd, unsigned long int __request, ...) __THROW; + #else + # ifdef __REDIRECT +-extern int __REDIRECT (ioctl, (int __fd, unsigned long int __request, ...), +- __ioctl_time64) __THROW; ++extern int __REDIRECT_NTH (ioctl, (int __fd, unsigned long int __request, ...), ++ __ioctl_time64); + # else + extern int __ioctl_time64 (int __fd, unsigned long int __request, ...) __THROW; + # define ioctl __ioctl_time64 +diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h +index db88938b3a542b0b..f0e0d2f27f9b9ee9 100644 +--- a/sysdeps/unix/sysv/linux/sys/prctl.h ++++ b/sysdeps/unix/sysv/linux/sys/prctl.h +@@ -42,7 +42,7 @@ __BEGIN_DECLS + extern int prctl (int __option, ...) __THROW; + #else + # ifdef __REDIRECT +-extern int __REDIRECT (prctl, (int __option, ...), __prctl_time64) __THROW; ++extern int __REDIRECT_NTH (prctl, (int __option, ...), __prctl_time64); + # else + extern int __prctl_time64 (int __option,d ...) __THROW; + # define ioctl __prctl_time64 diff --git a/glibc-upstream-2.34-7.patch b/glibc-upstream-2.34-7.patch new file mode 100644 index 0000000..c49b837 --- /dev/null +++ b/glibc-upstream-2.34-7.patch @@ -0,0 +1,35 @@ +commit 79474303223c5665bec75ffbdb2a86ee04a2514b +Author: Nikita Popov +Date: Mon Aug 9 20:17:34 2021 +0530 + + librt: fix NULL pointer dereference (bug 28213) + + Helper thread frees copied attribute on NOTIFY_REMOVED message + received from the OS kernel. Unfortunately, it fails to check whether + copied attribute actually exists (data.attr != NULL). This worked + earlier because free() checks passed pointer before actually + attempting to release corresponding memory. But + __pthread_attr_destroy assumes pointer is not NULL. + + So passing NULL pointer to __pthread_attr_destroy will result in + segmentation fault. This scenario is possible if + notification->sigev_notify_attributes == NULL (which means default + thread attributes should be used). + + Signed-off-by: Nikita Popov + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit b805aebd42364fe696e417808a700fdb9800c9e8) + +diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c +index 9799dcdaa479a1d5..eccae2e4c6cdfefa 100644 +--- a/sysdeps/unix/sysv/linux/mq_notify.c ++++ b/sysdeps/unix/sysv/linux/mq_notify.c +@@ -131,7 +131,7 @@ helper_thread (void *arg) + to wait until it is done with it. */ + (void) __pthread_barrier_wait (¬ify_barrier); + } +- else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) ++ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL) + { + /* The only state we keep is the copy of the thread attributes. */ + __pthread_attr_destroy (data.attr); diff --git a/glibc-upstream-2.34-8.patch b/glibc-upstream-2.34-8.patch new file mode 100644 index 0000000..b08f0ce --- /dev/null +++ b/glibc-upstream-2.34-8.patch @@ -0,0 +1,140 @@ +commit 7c987a5ccb31df80456d53a094e47f81310f549b +Author: Nikita Popov +Date: Thu Aug 12 16:09:50 2021 +0530 + + librt: add test (bug 28213) + + This test implements following logic: + 1) Create POSIX message queue. + Register a notification with mq_notify (using NULL attributes). + Then immediately unregister the notification with mq_notify. + Helper thread in a vulnerable version of glibc + should cause NULL pointer dereference after these steps. + 2) Once again, register the same notification. + Try to send a dummy message. + Test is considered successfulif the dummy message + is successfully received by the callback function. + + Signed-off-by: Nikita Popov + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 4cc79c217744743077bf7a0ec5e0a4318f1e6641) + +diff --git a/rt/Makefile b/rt/Makefile +index 113cea03a5b75613..910e7759956d7ae9 100644 +--- a/rt/Makefile ++++ b/rt/Makefile +@@ -74,6 +74,7 @@ tests := tst-shm tst-timer tst-timer2 \ + tst-aio7 tst-aio8 tst-aio9 tst-aio10 \ + tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ + tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \ ++ tst-bz28213 \ + tst-timer3 tst-timer4 tst-timer5 \ + tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \ + tst-shm-cancel \ +diff --git a/rt/tst-bz28213.c b/rt/tst-bz28213.c +new file mode 100644 +index 0000000000000000..0c096b5a0ad4170a +--- /dev/null ++++ b/rt/tst-bz28213.c +@@ -0,0 +1,101 @@ ++/* Bug 28213: test for NULL pointer dereference in mq_notify. ++ Copyright (C) The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static mqd_t m = -1; ++static const char msg[] = "hello"; ++ ++static void ++check_bz28213_cb (union sigval sv) ++{ ++ char buf[sizeof (msg)]; ++ ++ (void) sv; ++ ++ TEST_VERIFY_EXIT ((size_t) mq_receive (m, buf, sizeof (buf), NULL) ++ == sizeof (buf)); ++ TEST_VERIFY_EXIT (memcmp (buf, msg, sizeof (buf)) == 0); ++ ++ exit (0); ++} ++ ++static void ++check_bz28213 (void) ++{ ++ struct sigevent sev; ++ ++ memset (&sev, '\0', sizeof (sev)); ++ sev.sigev_notify = SIGEV_THREAD; ++ sev.sigev_notify_function = check_bz28213_cb; ++ ++ /* Step 1: Register & unregister notifier. ++ Helper thread should receive NOTIFY_REMOVED notification. ++ In a vulnerable version of glibc, NULL pointer dereference follows. */ ++ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); ++ TEST_VERIFY_EXIT (mq_notify (m, NULL) == 0); ++ ++ /* Step 2: Once again, register notification. ++ Try to send one message. ++ Test is considered successful, if the callback does exit (0). */ ++ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); ++ TEST_VERIFY_EXIT (mq_send (m, msg, sizeof (msg), 1) == 0); ++ ++ /* Wait... */ ++ pause (); ++} ++ ++static int ++do_test (void) ++{ ++ static const char m_name[] = "/bz28213_queue"; ++ struct mq_attr m_attr; ++ ++ memset (&m_attr, '\0', sizeof (m_attr)); ++ m_attr.mq_maxmsg = 1; ++ m_attr.mq_msgsize = sizeof (msg); ++ ++ m = mq_open (m_name, ++ O_RDWR | O_CREAT | O_EXCL, ++ 0600, ++ &m_attr); ++ ++ if (m < 0) ++ { ++ if (errno == ENOSYS) ++ FAIL_UNSUPPORTED ("POSIX message queues are not implemented\n"); ++ FAIL_EXIT1 ("Failed to create POSIX message queue: %m\n"); ++ } ++ ++ TEST_VERIFY_EXIT (mq_unlink (m_name) == 0); ++ ++ check_bz28213 (); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.34-9.patch b/glibc-upstream-2.34-9.patch new file mode 100644 index 0000000..b22636d --- /dev/null +++ b/glibc-upstream-2.34-9.patch @@ -0,0 +1,24 @@ +commit 9acab0bba6a5a57323b1f94bf95b21618a9e5aa4 +Author: Arjun Shankar +Date: Fri Aug 20 16:24:05 2021 +0200 + + elf: Fix missing colon in LD_SHOW_AUXV output [BZ #28253] + + This commit adds a missing colon in the AT_MINSIGSTKSZ entry in + the _dl_show_auxv function. + + (cherry picked from commit 82fbcd7118d760492e2ecc9fa291e358b9ba0361) + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index d47bef1340ce6f35..2c684c2db2a1f59b 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -317,7 +317,7 @@ _dl_show_auxv (void) + [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex }, + [AT_RANDOM - 2] = { "RANDOM: 0x", hex }, + [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex }, +- [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ ", dec }, ++ [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec }, + [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec }, + [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex }, + [AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec }, diff --git a/glibc.spec b/glibc.spec index 2f31c43..b3f203c 100644 --- a/glibc.spec +++ b/glibc.spec @@ -151,7 +151,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 2%{?dist} +Release: 5%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -225,11 +225,35 @@ Patch13: glibc-fedora-localedata-rh61908.patch Patch15: glibc-rh1070416.patch Patch16: glibc-nscd-sysconfig.patch Patch17: glibc-cs-path.patch -Patch18: glibc-c-utf8-locale.patch +Patch18: glibc-c-utf8-locale-1.patch +Patch19: glibc-c-utf8-locale-2.patch Patch23: glibc-python3.patch Patch29: glibc-fedora-nsswitch.patch Patch30: glibc-deprecated-selinux-makedb.patch Patch31: glibc-deprecated-selinux-nscd.patch +Patch32: glibc-upstream-2.34-1.patch +Patch33: glibc-upstream-2.34-2.patch +Patch34: glibc-upstream-2.34-3.patch +Patch35: glibc-upstream-2.34-4.patch +Patch36: glibc-upstream-2.34-5.patch +Patch37: glibc-upstream-2.34-6.patch +Patch38: glibc-upstream-2.34-7.patch +Patch39: glibc-upstream-2.34-8.patch +Patch40: glibc-upstream-2.34-9.patch +Patch41: glibc-upstream-2.34-10.patch +Patch42: glibc-upstream-2.34-11.patch +Patch43: glibc-upstream-2.34-12.patch +Patch44: glibc-upstream-2.34-13.patch +Patch45: glibc-upstream-2.34-14.patch +Patch46: glibc-upstream-2.34-15.patch +Patch47: glibc-upstream-2.34-16.patch +Patch48: glibc-upstream-2.34-17.patch +Patch49: glibc-upstream-2.34-18.patch +Patch50: glibc-upstream-2.34-19.patch +Patch51: glibc-upstream-2.34-20.patch +Patch52: glibc-rh1992702-1.patch +Patch53: glibc-rh1992702-2.patch +Patch54: glibc-rh1992702-3.patch ############################################################################## # Continued list of core "glibc" package information: @@ -342,6 +366,7 @@ BuildRequires: perl-interpreter # Filter out all GLIBC_PRIVATE symbols since they are internal to # the package and should not be examined by any other tool. %global __filter_GLIBC_PRIVATE 1 +%global __provides_exclude ^libc_malloc_debug\\.so.*$ # For language packs we have glibc require a virtual dependency # "glibc-langpack" wich gives us at least one installed langpack. @@ -1483,6 +1508,9 @@ mkdir -p %{glibc_sysroot}%{_libdir} mv -f %{glibc_sysroot}/%{_lib}/lib{pcprofile,memusage}.so \ %{glibc_sysroot}%{_libdir} +# Disallow linking against libc_malloc_debug. +rm %{glibc_sysroot}%{_libdir}/libc_malloc_debug.so + # Strip all of the installed object files. strip -g %{glibc_sysroot}%{_libdir}/*.o @@ -2257,9 +2285,41 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog -* Mon Aug 09 2021 Mohan Boddu - 2.34-2 -- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags - Related: rhbz#1991688 +* Wed Sep 15 2021 Florian Weimer - 2.34-5 +- Use system CPU count for sysconf(_SC_NPROCESSORS_*) (#1992702) + +* Wed Sep 15 2021 Florian Weimer - 2.34-4 +- Sync with upstream branch release/2.34/master, + commit 4ed990e5b97a61f29f929bdeb36c5b2abb547a64: +- Add MADV_POPULATE_READ and MADV_POPULATE_WRITE from Linux 5.14 to + bits/mman-linux.h +- Update kernel version to 5.14 in tst-mman-consts.py +- Update syscall lists for Linux 5.14 +- Use Linux 5.14 in build-many-glibcs.py +- Fix failing nss/tst-nss-files-hosts-long with local resolver +- iconvconfig: Fix behaviour with --prefix [BZ #28199] +- nptl: Fix race between pthread_kill and thread exit (swbz#12889, #1994068) +- nptl: pthread_kill, pthread_cancel should not fail after exit + (swbz#19193, #1994068) +- support: Add support_wait_for_thread_exit +- MIPS: Setup errno for {f,l,}xstat +- x86-64: Use testl to check __x86_string_control +- elf: Fix missing colon in LD_SHOW_AUXV output (swbz#28253, #1995648) +- librt: add test (swbz#28213, #1994264) +- CVE-2021-38604: fix NULL pointer dereference in mq_notify + (swbz#28213, #1994264) +- Linux: Fix fcntl, ioctl, prctl redirects for _TIME_BITS=64 (bug 28182) +- iconv_charmap: Close output file when done +- copy_and_spawn_sgid: Avoid double calls to close() +- gaiconf_init: Avoid double-free in label and precedence lists +- gconv_parseconfdir: Fix memory leak +- ldconfig: avoid leak on empty paths in config file + +* Wed Sep 15 2021 Florian Weimer - 2.34-3 +- Switch to upstream version of C.UTF-8 (#1997589) + +* Wed Aug 25 2021 Siddhesh Poyarekar - 2.34-2 +- Disable dependencies and linking for libc_malloc_debug.so (#1985048). * Mon Aug 2 2021 Florian Weimer - 2.34-1 - Switch to glibc 2.34 release tarball: