Compare commits
107 Commits
Author | SHA1 | Date |
---|---|---|
|
61f15e90bc | |
|
6129ad64d4 | |
|
1fa217076e | |
|
5846004b81 | |
|
7e6e06c36d | |
|
72195d4485 | |
|
77335ae30e | |
|
76ac51ab78 | |
|
293db26d85 | |
|
525a40ce11 | |
|
1ff5b17afe | |
|
a4d24cbe45 | |
|
b3c6eb0e4c | |
|
6144405435 | |
|
c96359dd1c | |
|
8797f87802 | |
|
5f0fe918a5 | |
|
c098079671 | |
|
4a003b4922 | |
|
ca11f82b69 | |
|
b21f47f287 | |
|
d53844dd72 | |
|
134a36d7f8 | |
|
a464847a25 | |
|
9c5a4265d8 | |
|
bd8d2430b4 | |
|
819bb4065c | |
|
3aed6a961c | |
|
34927af202 | |
|
fcb4083893 | |
|
50bcae98df | |
|
74725dd94e | |
|
9701fdade7 | |
|
6666c40188 | |
|
4124e42f39 | |
|
d9394d9d7e | |
|
47192f413e | |
|
448365c7f7 | |
|
a54853472d | |
|
dcaaa78467 | |
|
7b77f1b10f | |
|
b797613532 | |
|
e4dacdad3d | |
|
539fe8abbd | |
|
7b2061df55 | |
|
bfa3999fdd | |
|
82a97343d6 | |
|
a84cd6b530 | |
|
fdf2115d36 | |
|
4d79a1a6dd | |
|
70ec0cd8b9 | |
|
97506ad65a | |
|
5b4007bb56 | |
|
9f81c9aa6e | |
|
2300402532 | |
|
8a209c638d | |
|
047399b0d0 | |
|
1c5b89063f | |
|
b82e3b3f85 | |
|
8e6306e004 | |
|
5fff012634 | |
|
123aebc7d4 | |
|
109c797f85 | |
|
0ba614c06d | |
|
de5b416635 | |
|
b4e36d719d | |
|
e7b9f886b0 | |
|
5d5d75dce2 | |
|
88850a88bb | |
|
657df54449 | |
|
1ebcbd5e46 | |
|
70a46f30e1 | |
|
7c5e863b5b | |
|
133c946b2f | |
|
ec674e19b8 | |
|
4265b0b8f6 | |
|
062fb704db | |
|
1aba59b258 | |
|
650d554f72 | |
|
60935671c3 | |
|
7a4d7ca184 | |
|
1d88b65b1d | |
|
b8873c0d8b | |
|
afea822158 | |
|
173c24248d | |
|
5ce3b68016 | |
|
fdcac6f8f4 | |
|
2f22666a8b | |
|
16caa0b760 | |
|
81ee17d92e | |
|
36c64b8ffa | |
|
5ca0400677 | |
|
4232176d25 | |
|
c42d98baca | |
|
383945e966 | |
|
a5ad6ecfc9 | |
|
6287bab02b | |
|
8e5fc280df | |
|
3b14ffff2a | |
|
447d75c71c | |
|
a63c0b6456 | |
|
c63972c3a9 | |
|
9588eec39f | |
|
723de53164 | |
|
fde5e92317 | |
|
02e1d4ee3e | |
|
60efd153e5 |
|
@ -1,862 +0,0 @@
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <assert.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "../locale/hashval.h"
|
|
||||||
#define __LC_LAST 13
|
|
||||||
#include "../locale/locarchive.h"
|
|
||||||
#include "../crypt/md5.h"
|
|
||||||
|
|
||||||
const char *alias_file = DATADIR "/locale/locale.alias";
|
|
||||||
const char *locar_file = PREFIX "/lib/locale/locale-archive";
|
|
||||||
const char *tmpl_file = PREFIX "/lib/locale/locale-archive.tmpl";
|
|
||||||
const char *loc_path = PREFIX "/lib/locale/";
|
|
||||||
/* Flags set by `--verbose` option. */
|
|
||||||
int be_quiet = 1;
|
|
||||||
int verbose = 0;
|
|
||||||
int max_locarchive_open_retry = 10;
|
|
||||||
const char *output_prefix;
|
|
||||||
|
|
||||||
/* Endianness should have been taken care of by localedef. We don't need to do
|
|
||||||
additional swapping. We need this variable exported however, since
|
|
||||||
locarchive.c uses it to determine if it needs to swap endianness of a value
|
|
||||||
before writing to or reading from the archive. */
|
|
||||||
bool swap_endianness_p = false;
|
|
||||||
|
|
||||||
static const char *locnames[] =
|
|
||||||
{
|
|
||||||
#define DEFINE_CATEGORY(category, category_name, items, a) \
|
|
||||||
[category] = category_name,
|
|
||||||
#include "../locale/categories.def"
|
|
||||||
#undef DEFINE_CATEGORY
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
is_prime (unsigned long candidate)
|
|
||||||
{
|
|
||||||
/* No even number and none less than 10 will be passed here. */
|
|
||||||
unsigned long int divn = 3;
|
|
||||||
unsigned long int sq = divn * divn;
|
|
||||||
|
|
||||||
while (sq < candidate && candidate % divn != 0)
|
|
||||||
{
|
|
||||||
++divn;
|
|
||||||
sq += 4 * divn;
|
|
||||||
++divn;
|
|
||||||
}
|
|
||||||
|
|
||||||
return candidate % divn != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
next_prime (unsigned long seed)
|
|
||||||
{
|
|
||||||
/* Make it definitely odd. */
|
|
||||||
seed |= 1;
|
|
||||||
|
|
||||||
while (!is_prime (seed))
|
|
||||||
seed += 2;
|
|
||||||
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
error (int status, int errnum, const char *message, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start (args, message);
|
|
||||||
fflush (stdout);
|
|
||||||
fprintf (stderr, "%s: ", program_invocation_name);
|
|
||||||
vfprintf (stderr, message, args);
|
|
||||||
va_end (args);
|
|
||||||
if (errnum)
|
|
||||||
fprintf (stderr, ": %s", strerror (errnum));
|
|
||||||
putc ('\n', stderr);
|
|
||||||
fflush (stderr);
|
|
||||||
if (status)
|
|
||||||
exit (errnum == EROFS ? 0 : status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
xmalloc (size_t size)
|
|
||||||
{
|
|
||||||
void *p = malloc (size);
|
|
||||||
if (p == NULL)
|
|
||||||
error (EXIT_FAILURE, errno, "could not allocate %zd bytes of memory", size);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
open_tmpl_archive (struct locarhandle *ah)
|
|
||||||
{
|
|
||||||
struct stat64 st;
|
|
||||||
int fd;
|
|
||||||
struct locarhead head;
|
|
||||||
const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname;
|
|
||||||
|
|
||||||
/* Open the archive. We must have exclusive write access. */
|
|
||||||
fd = open64 (archivefname, O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
error (EXIT_FAILURE, errno, "cannot open locale archive template file \"%s\"",
|
|
||||||
archivefname);
|
|
||||||
|
|
||||||
if (fstat64 (fd, &st) < 0)
|
|
||||||
error (EXIT_FAILURE, errno, "cannot stat locale archive template file \"%s\"",
|
|
||||||
archivefname);
|
|
||||||
|
|
||||||
/* Read the header. */
|
|
||||||
if (TEMP_FAILURE_RETRY (read (fd, &head, sizeof (head))) != sizeof (head))
|
|
||||||
error (EXIT_FAILURE, errno, "cannot read archive header");
|
|
||||||
|
|
||||||
ah->fd = fd;
|
|
||||||
ah->mmaped = (head.sumhash_offset
|
|
||||||
+ head.sumhash_size * sizeof (struct sumhashent));
|
|
||||||
if (ah->mmaped > (unsigned long) st.st_size)
|
|
||||||
error (EXIT_FAILURE, 0, "locale archive template file truncated");
|
|
||||||
ah->mmaped = st.st_size;
|
|
||||||
ah->reserved = st.st_size;
|
|
||||||
|
|
||||||
/* Now we know how large the administrative information part is.
|
|
||||||
Map all of it. */
|
|
||||||
ah->addr = mmap64 (NULL, ah->mmaped, PROT_READ, MAP_SHARED, fd, 0);
|
|
||||||
if (ah->addr == MAP_FAILED)
|
|
||||||
error (EXIT_FAILURE, errno, "cannot map archive header");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the locale archive. */
|
|
||||||
extern void open_archive (struct locarhandle *ah, bool readonly);
|
|
||||||
|
|
||||||
/* Close the locale archive. */
|
|
||||||
extern void close_archive (struct locarhandle *ah);
|
|
||||||
|
|
||||||
/* Add given locale data to the archive. */
|
|
||||||
extern int add_locale_to_archive (struct locarhandle *ah, const char *name,
|
|
||||||
locale_data_t data, bool replace);
|
|
||||||
|
|
||||||
extern void add_alias (struct locarhandle *ah, const char *alias,
|
|
||||||
bool replace, const char *oldname,
|
|
||||||
uint32_t *locrec_offset_p);
|
|
||||||
|
|
||||||
extern struct namehashent *
|
|
||||||
insert_name (struct locarhandle *ah,
|
|
||||||
const char *name, size_t name_len, bool replace);
|
|
||||||
|
|
||||||
struct nameent
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
struct locrecent *locrec;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dataent
|
|
||||||
{
|
|
||||||
const unsigned char *sum;
|
|
||||||
uint32_t file_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
nameentcmp (const void *a, const void *b)
|
|
||||||
{
|
|
||||||
struct locrecent *la = ((const struct nameent *) a)->locrec;
|
|
||||||
struct locrecent *lb = ((const struct nameent *) b)->locrec;
|
|
||||||
uint32_t start_a = -1, end_a = 0;
|
|
||||||
uint32_t start_b = -1, end_b = 0;
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
{
|
|
||||||
if (la->record[cnt].offset < start_a)
|
|
||||||
start_a = la->record[cnt].offset;
|
|
||||||
if (la->record[cnt].offset + la->record[cnt].len > end_a)
|
|
||||||
end_a = la->record[cnt].offset + la->record[cnt].len;
|
|
||||||
}
|
|
||||||
assert (start_a != (uint32_t)-1);
|
|
||||||
assert (end_a != 0);
|
|
||||||
|
|
||||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
{
|
|
||||||
if (lb->record[cnt].offset < start_b)
|
|
||||||
start_b = lb->record[cnt].offset;
|
|
||||||
if (lb->record[cnt].offset + lb->record[cnt].len > end_b)
|
|
||||||
end_b = lb->record[cnt].offset + lb->record[cnt].len;
|
|
||||||
}
|
|
||||||
assert (start_b != (uint32_t)-1);
|
|
||||||
assert (end_b != 0);
|
|
||||||
|
|
||||||
if (start_a != start_b)
|
|
||||||
return (int)start_a - (int)start_b;
|
|
||||||
return (int)end_a - (int)end_b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
dataentcmp (const void *a, const void *b)
|
|
||||||
{
|
|
||||||
if (((const struct dataent *) a)->file_offset
|
|
||||||
< ((const struct dataent *) b)->file_offset)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (((const struct dataent *) a)->file_offset
|
|
||||||
> ((const struct dataent *) b)->file_offset)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sumsearchfn (const void *key, const void *ent)
|
|
||||||
{
|
|
||||||
uint32_t keyn = *(uint32_t *)key;
|
|
||||||
uint32_t entn = ((struct dataent *)ent)->file_offset;
|
|
||||||
|
|
||||||
if (keyn < entn)
|
|
||||||
return -1;
|
|
||||||
if (keyn > entn)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
compute_data (struct locarhandle *ah, struct nameent *name, size_t sumused,
|
|
||||||
struct dataent *files, locale_data_t data)
|
|
||||||
{
|
|
||||||
int cnt;
|
|
||||||
struct locrecent *locrec = name->locrec;
|
|
||||||
struct dataent *file;
|
|
||||||
data[LC_ALL].addr = ((char *) ah->addr) + locrec->record[LC_ALL].offset;
|
|
||||||
data[LC_ALL].size = locrec->record[LC_ALL].len;
|
|
||||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
{
|
|
||||||
data[cnt].addr = ((char *) ah->addr) + locrec->record[cnt].offset;
|
|
||||||
data[cnt].size = locrec->record[cnt].len;
|
|
||||||
if (data[cnt].addr >= data[LC_ALL].addr
|
|
||||||
&& data[cnt].addr + data[cnt].size
|
|
||||||
<= data[LC_ALL].addr + data[LC_ALL].size)
|
|
||||||
__md5_buffer (data[cnt].addr, data[cnt].size, data[cnt].sum);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file = bsearch (&locrec->record[cnt].offset, files, sumused,
|
|
||||||
sizeof (*files), sumsearchfn);
|
|
||||||
if (file == NULL)
|
|
||||||
error (EXIT_FAILURE, 0, "inconsistent template file");
|
|
||||||
memcpy (data[cnt].sum, file->sum, sizeof (data[cnt].sum));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
fill_archive (struct locarhandle *tmpl_ah,
|
|
||||||
const char *fname,
|
|
||||||
size_t install_langs_count, char *install_langs_list[],
|
|
||||||
size_t nlist, char *list[],
|
|
||||||
const char *primary)
|
|
||||||
{
|
|
||||||
struct locarhandle ah;
|
|
||||||
struct locarhead *head;
|
|
||||||
int result = 0;
|
|
||||||
struct nameent *names;
|
|
||||||
struct namehashent *namehashtab;
|
|
||||||
size_t cnt, used;
|
|
||||||
struct dataent *files;
|
|
||||||
struct sumhashent *sumhashtab;
|
|
||||||
size_t sumused;
|
|
||||||
struct locrecent *primary_locrec = NULL;
|
|
||||||
struct nameent *primary_nameent = NULL;
|
|
||||||
|
|
||||||
head = tmpl_ah->addr;
|
|
||||||
names = (struct nameent *) malloc (head->namehash_used
|
|
||||||
* sizeof (struct nameent));
|
|
||||||
files = (struct dataent *) malloc (head->sumhash_used
|
|
||||||
* sizeof (struct dataent));
|
|
||||||
if (names == NULL || files == NULL)
|
|
||||||
error (EXIT_FAILURE, errno, "could not allocate tables");
|
|
||||||
|
|
||||||
namehashtab = (struct namehashent *) ((char *) tmpl_ah->addr
|
|
||||||
+ head->namehash_offset);
|
|
||||||
sumhashtab = (struct sumhashent *) ((char *) tmpl_ah->addr
|
|
||||||
+ head->sumhash_offset);
|
|
||||||
|
|
||||||
for (cnt = used = 0; cnt < head->namehash_size; ++cnt)
|
|
||||||
if (namehashtab[cnt].locrec_offset != 0)
|
|
||||||
{
|
|
||||||
char * name;
|
|
||||||
int i;
|
|
||||||
assert (used < head->namehash_used);
|
|
||||||
name = tmpl_ah->addr + namehashtab[cnt].name_offset;
|
|
||||||
if (install_langs_count == 0)
|
|
||||||
{
|
|
||||||
/* Always intstall the entry. */
|
|
||||||
names[used].name = name;
|
|
||||||
names[used++].locrec
|
|
||||||
= (struct locrecent *) ((char *) tmpl_ah->addr +
|
|
||||||
namehashtab[cnt].locrec_offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Only install the entry if the user asked for it via
|
|
||||||
--install-langs. */
|
|
||||||
for (i = 0; i < install_langs_count; i++)
|
|
||||||
{
|
|
||||||
/* Add one for "_" and one for the null terminator. */
|
|
||||||
size_t len = strlen (install_langs_list[i]) + 2;
|
|
||||||
char *install_lang = (char *)xmalloc (len);
|
|
||||||
strcpy (install_lang, install_langs_list[i]);
|
|
||||||
if (strchr (install_lang, '_') == NULL)
|
|
||||||
strcat (install_lang, "_");
|
|
||||||
if (strncmp (name, install_lang, strlen (install_lang)) == 0)
|
|
||||||
{
|
|
||||||
names[used].name = name;
|
|
||||||
names[used++].locrec
|
|
||||||
= (struct locrecent *) ((char *)tmpl_ah->addr
|
|
||||||
+ namehashtab[cnt].locrec_offset);
|
|
||||||
}
|
|
||||||
free (install_lang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the names. */
|
|
||||||
qsort (names, used, sizeof (struct nameent), nameentcmp);
|
|
||||||
|
|
||||||
for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt)
|
|
||||||
if (sumhashtab[cnt].file_offset != 0)
|
|
||||||
{
|
|
||||||
assert (sumused < head->sumhash_used);
|
|
||||||
files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum;
|
|
||||||
files[sumused++].file_offset = sumhashtab[cnt].file_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort by file locations. */
|
|
||||||
qsort (files, sumused, sizeof (struct dataent), dataentcmp);
|
|
||||||
|
|
||||||
/* Open the archive. This call never returns if we cannot
|
|
||||||
successfully open the archive. */
|
|
||||||
ah.fname = NULL;
|
|
||||||
if (fname != NULL)
|
|
||||||
ah.fname = fname;
|
|
||||||
open_archive (&ah, false);
|
|
||||||
|
|
||||||
if (primary != NULL)
|
|
||||||
{
|
|
||||||
for (cnt = 0; cnt < used; ++cnt)
|
|
||||||
if (strcmp (names[cnt].name, primary) == 0)
|
|
||||||
break;
|
|
||||||
if (cnt < used)
|
|
||||||
{
|
|
||||||
locale_data_t data;
|
|
||||||
|
|
||||||
compute_data (tmpl_ah, &names[cnt], sumused, files, data);
|
|
||||||
result |= add_locale_to_archive (&ah, primary, data, 0);
|
|
||||||
primary_locrec = names[cnt].locrec;
|
|
||||||
primary_nameent = &names[cnt];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cnt = 0; cnt < used; ++cnt)
|
|
||||||
if (&names[cnt] == primary_nameent)
|
|
||||||
continue;
|
|
||||||
else if ((cnt > 0 && names[cnt - 1].locrec == names[cnt].locrec)
|
|
||||||
|| names[cnt].locrec == primary_locrec)
|
|
||||||
{
|
|
||||||
const char *oldname;
|
|
||||||
struct namehashent *namehashent;
|
|
||||||
uint32_t locrec_offset;
|
|
||||||
|
|
||||||
if (names[cnt].locrec == primary_locrec)
|
|
||||||
oldname = primary;
|
|
||||||
else
|
|
||||||
oldname = names[cnt - 1].name;
|
|
||||||
namehashent = insert_name (&ah, oldname, strlen (oldname), true);
|
|
||||||
assert (namehashent->name_offset != 0);
|
|
||||||
assert (namehashent->locrec_offset != 0);
|
|
||||||
locrec_offset = namehashent->locrec_offset;
|
|
||||||
add_alias (&ah, names[cnt].name, 0, oldname, &locrec_offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
locale_data_t data;
|
|
||||||
|
|
||||||
compute_data (tmpl_ah, &names[cnt], sumused, files, data);
|
|
||||||
result |= add_locale_to_archive (&ah, names[cnt].name, data, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (nlist-- > 0)
|
|
||||||
{
|
|
||||||
const char *fname = *list++;
|
|
||||||
size_t fnamelen = strlen (fname);
|
|
||||||
struct stat64 st;
|
|
||||||
DIR *dirp;
|
|
||||||
struct dirent64 *d;
|
|
||||||
int seen;
|
|
||||||
locale_data_t data;
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
/* First see whether this really is a directory and whether it
|
|
||||||
contains all the require locale category files. */
|
|
||||||
if (stat64 (fname, &st) < 0)
|
|
||||||
{
|
|
||||||
error (0, 0, "stat of \"%s\" failed: %s: ignored", fname,
|
|
||||||
strerror (errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!S_ISDIR (st.st_mode))
|
|
||||||
{
|
|
||||||
error (0, 0, "\"%s\" is no directory; ignored", fname);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirp = opendir (fname);
|
|
||||||
if (dirp == NULL)
|
|
||||||
{
|
|
||||||
error (0, 0, "cannot open directory \"%s\": %s: ignored",
|
|
||||||
fname, strerror (errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
seen = 0;
|
|
||||||
while ((d = readdir64 (dirp)) != NULL)
|
|
||||||
{
|
|
||||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
if (strcmp (d->d_name, locnames[cnt]) == 0)
|
|
||||||
{
|
|
||||||
unsigned char d_type;
|
|
||||||
|
|
||||||
/* We have an object of the required name. If it's
|
|
||||||
a directory we have to look at a file with the
|
|
||||||
prefix "SYS_". Otherwise we have found what we
|
|
||||||
are looking for. */
|
|
||||||
#ifdef _DIRENT_HAVE_D_TYPE
|
|
||||||
d_type = d->d_type;
|
|
||||||
|
|
||||||
if (d_type != DT_REG)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
|
||||||
|
|
||||||
#ifdef _DIRENT_HAVE_D_TYPE
|
|
||||||
if (d_type == DT_UNKNOWN)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
|
||||||
d->d_name);
|
|
||||||
|
|
||||||
if (stat64 (fullname, &st) == -1)
|
|
||||||
/* We cannot stat the file, ignore it. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
d_type = IFTODT (st.st_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d_type == DT_DIR)
|
|
||||||
{
|
|
||||||
/* We have to do more tests. The file is a
|
|
||||||
directory and it therefore must contain a
|
|
||||||
regular file with the same name except a
|
|
||||||
"SYS_" prefix. */
|
|
||||||
char *t = stpcpy (stpcpy (fullname, fname), "/");
|
|
||||||
strcpy (stpcpy (stpcpy (t, d->d_name), "/SYS_"),
|
|
||||||
d->d_name);
|
|
||||||
|
|
||||||
if (stat64 (fullname, &st) == -1)
|
|
||||||
/* There is no SYS_* file or we cannot
|
|
||||||
access it. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
d_type = IFTODT (st.st_mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we found a regular file (eventually after
|
|
||||||
following a symlink) we are successful. */
|
|
||||||
if (d_type == DT_REG)
|
|
||||||
++seen;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir (dirp);
|
|
||||||
|
|
||||||
if (seen != __LC_LAST - 1)
|
|
||||||
{
|
|
||||||
/* We don't have all locale category files. Ignore the name. */
|
|
||||||
error (0, 0, "incomplete set of locale files in \"%s\"",
|
|
||||||
fname);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the files to the archive. To do this we first compute
|
|
||||||
sizes and the MD5 sums of all the files. */
|
|
||||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
{
|
|
||||||
char fullname[fnamelen + 2 * strlen (locnames[cnt]) + 7];
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"), locnames[cnt]);
|
|
||||||
fd = open64 (fullname, O_RDONLY);
|
|
||||||
if (fd == -1 || fstat64 (fd, &st) == -1)
|
|
||||||
{
|
|
||||||
/* Cannot read the file. */
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISDIR (st.st_mode))
|
|
||||||
{
|
|
||||||
char *t;
|
|
||||||
close (fd);
|
|
||||||
t = stpcpy (stpcpy (fullname, fname), "/");
|
|
||||||
strcpy (stpcpy (stpcpy (t, locnames[cnt]), "/SYS_"),
|
|
||||||
locnames[cnt]);
|
|
||||||
|
|
||||||
fd = open64 (fullname, O_RDONLY);
|
|
||||||
if (fd == -1 || fstat64 (fd, &st) == -1
|
|
||||||
|| !S_ISREG (st.st_mode))
|
|
||||||
{
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map the file. */
|
|
||||||
data[cnt].addr = mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
|
|
||||||
fd, 0);
|
|
||||||
if (data[cnt].addr == MAP_FAILED)
|
|
||||||
{
|
|
||||||
/* Cannot map it. */
|
|
||||||
close (fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
data[cnt].size = st.st_size;
|
|
||||||
__md5_buffer (data[cnt].addr, st.st_size, data[cnt].sum);
|
|
||||||
|
|
||||||
/* We don't need the file descriptor anymore. */
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cnt != __LC_LAST)
|
|
||||||
{
|
|
||||||
while (cnt-- > 0)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
munmap (data[cnt].addr, data[cnt].size);
|
|
||||||
|
|
||||||
error (0, 0, "cannot read all files in \"%s\": ignored", fname);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result |= add_locale_to_archive (&ah, basename (fname), data, 0);
|
|
||||||
|
|
||||||
for (cnt = 0; cnt < __LC_LAST; ++cnt)
|
|
||||||
if (cnt != LC_ALL)
|
|
||||||
munmap (data[cnt].addr, data[cnt].size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We are done. */
|
|
||||||
close_archive (&ah);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage()
|
|
||||||
{
|
|
||||||
printf ("\
|
|
||||||
Usage: build-locale-archive [OPTION]... [TEMPLATE-FILE] [ARCHIVE-FILE]\n\
|
|
||||||
Builds a locale archive from a template file.\n\
|
|
||||||
Options:\n\
|
|
||||||
-h, --help Print this usage message.\n\
|
|
||||||
-v, --verbose Verbose execution.\n\
|
|
||||||
-l, --install-langs=LIST Only include locales given in LIST into the \n\
|
|
||||||
locale archive. LIST is a colon separated list\n\
|
|
||||||
of locale prefixes, for example \"de:en:ja\".\n\
|
|
||||||
The special argument \"all\" means to install\n\
|
|
||||||
all languages and it must be present by itself.\n\
|
|
||||||
If \"all\" is present with any other language it\n\
|
|
||||||
will be treated as the name of a locale.\n\
|
|
||||||
If the --install-langs option is missing, all\n\
|
|
||||||
locales are installed. The colon separated list\n\
|
|
||||||
can contain any strings matching the beginning of\n\
|
|
||||||
locale names.\n\
|
|
||||||
If a string does not contain a \"_\", it is added.\n\
|
|
||||||
Examples:\n\
|
|
||||||
--install-langs=\"en\"\n\
|
|
||||||
installs en_US, en_US.iso88591,\n\
|
|
||||||
en_US.iso885915, en_US.utf8,\n\
|
|
||||||
en_GB ...\n\
|
|
||||||
--install-langs=\"en_US.utf8\"\n\
|
|
||||||
installs only en_US.utf8.\n\
|
|
||||||
--install-langs=\"ko\"\n\
|
|
||||||
installs ko_KR, ko_KR.euckr,\n\
|
|
||||||
ko_KR.utf8 but *not* kok_IN\n\
|
|
||||||
because \"ko\" does not contain\n\
|
|
||||||
\"_\" and it is silently added\n\
|
|
||||||
--install-langs\"ko:kok\"\n\
|
|
||||||
installs ko_KR, ko_KR.euckr,\n\
|
|
||||||
ko_KR.utf8, kok_IN, and\n\
|
|
||||||
kok_IN.utf8.\n\
|
|
||||||
--install-langs=\"POSIX\" will\n\
|
|
||||||
installs *no* locales at all\n\
|
|
||||||
because POSIX matches none of\n\
|
|
||||||
the locales. Actually, any string\n\
|
|
||||||
matching nothing will do that.\n\
|
|
||||||
POSIX and C will always be\n\
|
|
||||||
available because they are\n\
|
|
||||||
builtin.\n\
|
|
||||||
Aliases are installed as well,\n\
|
|
||||||
i.e. --install-langs=\"de\"\n\
|
|
||||||
will install not only every locale starting with\n\
|
|
||||||
\"de\" but also the aliases \"deutsch\"\n\
|
|
||||||
and and \"german\" although the latter does not\n\
|
|
||||||
start with \"de\".\n\
|
|
||||||
\n\
|
|
||||||
If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\
|
|
||||||
where the glibc used expects these files are used by default.\n\
|
|
||||||
");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char path[4096];
|
|
||||||
DIR *dirp;
|
|
||||||
struct dirent64 *d;
|
|
||||||
struct stat64 st;
|
|
||||||
char *list[16384], *primary;
|
|
||||||
char *lang;
|
|
||||||
int install_langs_count = 0;
|
|
||||||
int i;
|
|
||||||
char *install_langs_arg, *ila_start;
|
|
||||||
char **install_langs_list = NULL;
|
|
||||||
unsigned int cnt = 0;
|
|
||||||
struct locarhandle tmpl_ah;
|
|
||||||
char *new_locar_fname = NULL;
|
|
||||||
size_t loc_path_len = strlen (loc_path);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
static struct option long_options[] =
|
|
||||||
{
|
|
||||||
{"help", no_argument, 0, 'h'},
|
|
||||||
{"verbose", no_argument, 0, 'v'},
|
|
||||||
{"install-langs", required_argument, 0, 'l'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
/* getopt_long stores the option index here. */
|
|
||||||
int option_index = 0;
|
|
||||||
|
|
||||||
c = getopt_long (argc, argv, "vhl:",
|
|
||||||
long_options, &option_index);
|
|
||||||
|
|
||||||
/* Detect the end of the options. */
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
printf ("unknown option %s", long_options[option_index].name);
|
|
||||||
if (optarg)
|
|
||||||
printf (" with arg %s", optarg);
|
|
||||||
printf ("\n");
|
|
||||||
usage ();
|
|
||||||
exit (1);
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
verbose = 1;
|
|
||||||
be_quiet = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
usage ();
|
|
||||||
exit (0);
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
install_langs_arg = ila_start = strdup (optarg);
|
|
||||||
/* If the argument to --install-lang is "all", do
|
|
||||||
not limit the list of languages to install and install
|
|
||||||
them all. We do not support installing a single locale
|
|
||||||
called "all". */
|
|
||||||
#define MAGIC_INSTALL_ALL "all"
|
|
||||||
if (install_langs_arg != NULL
|
|
||||||
&& install_langs_arg[0] != '\0'
|
|
||||||
&& !(strncmp(install_langs_arg, MAGIC_INSTALL_ALL,
|
|
||||||
strlen(MAGIC_INSTALL_ALL)) == 0
|
|
||||||
&& strlen (install_langs_arg) == 3))
|
|
||||||
{
|
|
||||||
/* Count the number of languages we will install. */
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lang = strtok(install_langs_arg, ":;,");
|
|
||||||
if (lang == NULL)
|
|
||||||
break;
|
|
||||||
install_langs_count++;
|
|
||||||
install_langs_arg = NULL;
|
|
||||||
}
|
|
||||||
free (ila_start);
|
|
||||||
|
|
||||||
/* Reject an entire string made up of delimiters. */
|
|
||||||
if (install_langs_count == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Copy the list. */
|
|
||||||
install_langs_list = (char **)xmalloc (sizeof(char *) * install_langs_count);
|
|
||||||
install_langs_arg = ila_start = strdup (optarg);
|
|
||||||
install_langs_count = 0;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lang = strtok(install_langs_arg, ":;,");
|
|
||||||
if (lang == NULL)
|
|
||||||
break;
|
|
||||||
install_langs_list[install_langs_count] = lang;
|
|
||||||
install_langs_count++;
|
|
||||||
install_langs_arg = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
/* getopt_long already printed an error message. */
|
|
||||||
usage ();
|
|
||||||
exit (0);
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmpl_ah.fname = NULL;
|
|
||||||
if (optind < argc)
|
|
||||||
tmpl_ah.fname = argv[optind];
|
|
||||||
if (optind + 1 < argc)
|
|
||||||
new_locar_fname = argv[optind + 1];
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
if (tmpl_ah.fname)
|
|
||||||
printf("input archive file specified on command line: %s\n",
|
|
||||||
tmpl_ah.fname);
|
|
||||||
else
|
|
||||||
printf("using default input archive file.\n");
|
|
||||||
if (new_locar_fname)
|
|
||||||
printf("output archive file specified on command line: %s\n",
|
|
||||||
new_locar_fname);
|
|
||||||
else
|
|
||||||
printf("using default output archive file.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
dirp = opendir (loc_path);
|
|
||||||
if (dirp == NULL)
|
|
||||||
error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
|
|
||||||
|
|
||||||
open_tmpl_archive (&tmpl_ah);
|
|
||||||
|
|
||||||
if (new_locar_fname)
|
|
||||||
unlink (new_locar_fname);
|
|
||||||
else
|
|
||||||
unlink (locar_file);
|
|
||||||
primary = getenv ("LC_ALL");
|
|
||||||
if (primary == NULL)
|
|
||||||
primary = getenv ("LANG");
|
|
||||||
if (primary != NULL)
|
|
||||||
{
|
|
||||||
if (strncmp (primary, "ja", 2) != 0
|
|
||||||
&& strncmp (primary, "ko", 2) != 0
|
|
||||||
&& strncmp (primary, "zh", 2) != 0)
|
|
||||||
{
|
|
||||||
char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q;
|
|
||||||
/* This leads to invalid locales sometimes:
|
|
||||||
de_DE.iso885915@euro -> de_DE.utf8@euro */
|
|
||||||
if (ptr != NULL)
|
|
||||||
{
|
|
||||||
p = ptr;
|
|
||||||
q = primary;
|
|
||||||
while (*q && *q != '.' && *q != '@')
|
|
||||||
*p++ = *q++;
|
|
||||||
if (*q == '.')
|
|
||||||
while (*q && *q != '@')
|
|
||||||
q++;
|
|
||||||
p = stpcpy (p, ".utf8");
|
|
||||||
strcpy (p, q);
|
|
||||||
primary = ptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
primary = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (path, loc_path, loc_path_len);
|
|
||||||
|
|
||||||
while ((d = readdir64 (dirp)) != NULL)
|
|
||||||
{
|
|
||||||
if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0)
|
|
||||||
continue;
|
|
||||||
if (strchr (d->d_name, '_') == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
size_t d_name_len = strlen (d->d_name);
|
|
||||||
if (loc_path_len + d_name_len + 1 > sizeof (path))
|
|
||||||
{
|
|
||||||
error (0, 0, "too long filename \"%s\"", d->d_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (path + loc_path_len, d->d_name, d_name_len + 1);
|
|
||||||
if (stat64 (path, &st) < 0)
|
|
||||||
{
|
|
||||||
error (0, errno, "cannot stat \"%s\"", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (! S_ISDIR (st.st_mode))
|
|
||||||
continue;
|
|
||||||
if (cnt == 16384)
|
|
||||||
{
|
|
||||||
error (0, 0, "too many directories in \"%s\"", loc_path);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
list[cnt] = strdup (path);
|
|
||||||
if (list[cnt] == NULL)
|
|
||||||
{
|
|
||||||
error (0, errno, "cannot add file to list \"%s\"", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (primary != NULL && cnt > 0 && strcmp (primary, d->d_name) == 0)
|
|
||||||
{
|
|
||||||
char *p = list[0];
|
|
||||||
list[0] = list[cnt];
|
|
||||||
list[cnt] = p;
|
|
||||||
}
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
closedir (dirp);
|
|
||||||
/* Store the archive to the file specified as the second argument on the
|
|
||||||
command line or the default locale archive. */
|
|
||||||
fill_archive (&tmpl_ah, new_locar_fname,
|
|
||||||
install_langs_count, install_langs_list,
|
|
||||||
cnt, list, primary);
|
|
||||||
close_archive (&tmpl_ah);
|
|
||||||
truncate (tmpl_file, 0);
|
|
||||||
if (install_langs_count > 0)
|
|
||||||
{
|
|
||||||
free (ila_start);
|
|
||||||
free (install_langs_list);
|
|
||||||
}
|
|
||||||
char *tz_argv[] = { "/usr/sbin/tzdata-update", NULL };
|
|
||||||
execve (tz_argv[0], (char *const *)tz_argv, (char *const *)&tz_argv[1]);
|
|
||||||
exit (0);
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
Author: Florian Weimer <fweimer@redhat.com>
|
|
||||||
Date: Wed Jul 4 16:16:57 2018 +0200
|
|
||||||
|
|
||||||
Makeconfig (ASFLAGS): Always append required assembler flags.
|
|
||||||
|
|
||||||
Submitted upstream here:
|
|
||||||
|
|
||||||
https://sourceware.org/ml/libc-alpha/2018-07/msg00077.html
|
|
||||||
|
|
||||||
Otherwise, we lose essential flags such as -Wa,--noexecstack due to
|
|
||||||
the way += works in make due to the ASFLAGS command line override.
|
|
||||||
|
|
||||||
diff --git a/Makeconfig b/Makeconfig
|
|
||||||
index b0b27f0113ac18b8..92e76d6200bbcd5b 100644
|
|
||||||
--- a/Makeconfig
|
|
||||||
+++ b/Makeconfig
|
|
||||||
@@ -1047,7 +1047,7 @@ endif
|
|
||||||
ifndef ASFLAGS
|
|
||||||
ASFLAGS := $(filter -g% -fdebug-prefix-map=%,$(CFLAGS))
|
|
||||||
endif
|
|
||||||
-ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
|
|
||||||
+override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
|
|
||||||
|
|
||||||
ifndef BUILD_CC
|
|
||||||
BUILD_CC = $(CC)
|
|
|
@ -88,21 +88,21 @@ index 0000000..fdf460e
|
||||||
+<U0000>
|
+<U0000>
|
||||||
+..
|
+..
|
||||||
+<UFFFF>
|
+<UFFFF>
|
||||||
+<U10000>
|
+<U00010000>
|
||||||
+..
|
+..
|
||||||
+<U1FFFF>
|
+<U0001FFFF>
|
||||||
+<U20000>
|
+<U00020000>
|
||||||
+..
|
+..
|
||||||
+<U2FFFF>
|
+<U0002FFFF>
|
||||||
+<UE0000>
|
+<U000E0000>
|
||||||
+..
|
+..
|
||||||
+<UEFFFF>
|
+<U000EFFFF>
|
||||||
+<UF0000>
|
+<U000F0000>
|
||||||
+..
|
+..
|
||||||
+<UFFFFF>
|
+<U000FFFFF>
|
||||||
+<U100000>
|
+<U00100000>
|
||||||
+..
|
+..
|
||||||
+<U10FFFF>
|
+<U0010FFFF>
|
||||||
+UNDEFINED
|
+UNDEFINED
|
||||||
+order_end
|
+order_end
|
||||||
+END LC_COLLATE
|
+END LC_COLLATE
|
||||||
|
|
|
@ -8,14 +8,14 @@ behaviour which updates the locale archive. The Fedora install phase
|
||||||
in the spec file of the rpm will handle this manually.
|
in the spec file of the rpm will handle this manually.
|
||||||
|
|
||||||
diff --git a/localedata/Makefile b/localedata/Makefile
|
diff --git a/localedata/Makefile b/localedata/Makefile
|
||||||
index a5f3c92d58954dfc..56719c7c714aa0f1 100644
|
index 0eea396ad86da956..54caabda33728207 100644
|
||||||
--- a/localedata/Makefile
|
--- a/localedata/Makefile
|
||||||
+++ b/localedata/Makefile
|
+++ b/localedata/Makefile
|
||||||
@@ -218,6 +218,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-locales-dir
|
@@ -413,6 +413,7 @@ define build-one-locale
|
||||||
echo -n '...'; \
|
echo -n '...'; \
|
||||||
input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \
|
input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \
|
||||||
$(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \
|
$(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \
|
||||||
+ --no-archive \
|
+ --no-archive \
|
||||||
-i locales/$$input -f charmaps/$$charset \
|
-i locales/$$input -f charmaps/$$charset \
|
||||||
$(addprefix --prefix=,$(install_root)) $$locale \
|
$(addprefix --prefix=,$(install_root)) $$locale \
|
||||||
&& echo ' done'; \
|
&& echo ' done';
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
Short description: Allow access to internal locale archive functions.
|
|
||||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
|
||||||
Origin: PATCH
|
|
||||||
Upstream status: not-needed
|
|
||||||
|
|
||||||
This is a part of commit glibc-2.3.3-1492-ga891c7b,
|
|
||||||
needed for fedora/build-locale-archive.c only.
|
|
||||||
|
|
||||||
2007-04-16 Jakub Jelinek <jakub@redhat.com>
|
|
||||||
|
|
||||||
* locale/programs/locarchive.c (add_alias, insert_name): Remove static.
|
|
||||||
|
|
||||||
diff -Nrup a/locale/programs/locarchive.c b/locale/programs/locarchive.c
|
|
||||||
--- a/locale/programs/locarchive.c 2012-06-05 07:42:49.000000000 -0600
|
|
||||||
+++ b/locale/programs/locarchive.c 2012-06-07 12:15:21.585319540 -0600
|
|
||||||
@@ -252,9 +252,9 @@ oldlocrecentcmp (const void *a, const vo
|
|
||||||
/* forward decls for below */
|
|
||||||
static uint32_t add_locale (struct locarhandle *ah, const char *name,
|
|
||||||
locale_data_t data, bool replace);
|
|
||||||
-static void add_alias (struct locarhandle *ah, const char *alias,
|
|
||||||
- bool replace, const char *oldname,
|
|
||||||
- uint32_t *locrec_offset_p);
|
|
||||||
+void add_alias (struct locarhandle *ah, const char *alias,
|
|
||||||
+ bool replace, const char *oldname,
|
|
||||||
+ uint32_t *locrec_offset_p);
|
|
||||||
|
|
||||||
|
|
||||||
static bool
|
|
||||||
@@ -635,7 +635,7 @@ close_archive (struct locarhandle *ah)
|
|
||||||
#include "../../intl/explodename.c"
|
|
||||||
#include "../../intl/l10nflist.c"
|
|
||||||
|
|
||||||
-static struct namehashent *
|
|
||||||
+struct namehashent *
|
|
||||||
insert_name (struct locarhandle *ah,
|
|
||||||
const char *name, size_t name_len, bool replace)
|
|
||||||
{
|
|
||||||
@@ -693,7 +693,7 @@ insert_name (struct locarhandle *ah,
|
|
||||||
return &namehashtab[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void
|
|
||||||
+void
|
|
||||||
add_alias (struct locarhandle *ah, const char *alias, bool replace,
|
|
||||||
const char *oldname, uint32_t *locrec_offset_p)
|
|
||||||
{
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
The Fedora /etc/nsswitch.conf is based largely on the upstream
|
||||||
|
version with minor downstream distribution modifications for
|
||||||
|
use with SSSD and systemd.
|
||||||
|
|
||||||
|
diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf
|
||||||
|
index f55358811495c9f1..14c3cde8080a848c 100644
|
||||||
|
--- a/nss/nsswitch.conf
|
||||||
|
+++ b/nss/nsswitch.conf
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
#
|
||||||
|
# /etc/nsswitch.conf
|
||||||
|
#
|
||||||
|
-# An example Name Service Switch config file. This file should be
|
||||||
|
+# Name Service Switch config file. This file should be
|
||||||
|
# sorted with the most-used services at the beginning.
|
||||||
|
#
|
||||||
|
# Valid databases are: aliases, ethers, group, gshadow, hosts,
|
||||||
|
@@ -52,18 +52,20 @@
|
||||||
|
# shadow: db files
|
||||||
|
# group: db files
|
||||||
|
|
||||||
|
-# In alphabetical order. Re-order as required to optimize peformance.
|
||||||
|
+# In order of likelihood of use to accelerate lookup.
|
||||||
|
+passwd: sss files
|
||||||
|
+shadow: files sss
|
||||||
|
+group: sss files
|
||||||
|
+hosts: files dns myhostname
|
||||||
|
+services: files sss
|
||||||
|
+netgroup: sss
|
||||||
|
+automount: files sss
|
||||||
|
+
|
||||||
|
aliases: files
|
||||||
|
ethers: files
|
||||||
|
-group: files
|
||||||
|
gshadow: files
|
||||||
|
-hosts: files dns
|
||||||
|
initgroups: files
|
||||||
|
-netgroup: files
|
||||||
|
networks: files dns
|
||||||
|
-passwd: files
|
||||||
|
protocols: files
|
||||||
|
publickey: files
|
||||||
|
rpc: files
|
||||||
|
-shadow: files
|
||||||
|
-services: files
|
|
@ -1,38 +0,0 @@
|
||||||
Short description: Do not define _XOPEN_STREAMS.
|
|
||||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
|
||||||
Origin: PATCH
|
|
||||||
Bug-Fedora: #436349
|
|
||||||
Upstream status: not-submitted
|
|
||||||
|
|
||||||
This patch should go upstream. Not defining _XOPEN_STREAMS is the
|
|
||||||
same as setting it to -1 for POSIX conformance. The headers setting
|
|
||||||
needs to be reviewed indepedently.
|
|
||||||
|
|
||||||
This is part of commit glibc-2.3.3-1564-gd0b6ac6
|
|
||||||
|
|
||||||
* Fri Mar 14 2008 Jakub Jelinek <jakub@redhat.com> 2.7.90-11
|
|
||||||
- remove <stropts.h>, define _XOPEN_STREAMS -1 (#436349)
|
|
||||||
|
|
||||||
diff -Nrup a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
|
|
||||||
--- a/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-05 07:42:49.000000000 -0600
|
|
||||||
+++ b/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-07 12:15:21.817318674 -0600
|
|
||||||
@@ -188,4 +188,7 @@
|
|
||||||
/* Typed memory objects are not available. */
|
|
||||||
#define _POSIX_TYPED_MEMORY_OBJECTS -1
|
|
||||||
|
|
||||||
+/* Streams are not available. */
|
|
||||||
+#define _XOPEN_STREAMS -1
|
|
||||||
+
|
|
||||||
#endif /* bits/posix_opt.h */
|
|
||||||
diff -Nrup a/streams/Makefile b/streams/Makefile
|
|
||||||
--- a/streams/Makefile 2012-06-05 07:42:49.000000000 -0600
|
|
||||||
+++ b/streams/Makefile 2012-06-07 12:15:21.824318649 -0600
|
|
||||||
@@ -20,7 +20,7 @@
|
|
||||||
|
|
||||||
include ../Makeconfig
|
|
||||||
|
|
||||||
-headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
|
|
||||||
+#headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
|
|
||||||
routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach
|
|
||||||
|
|
||||||
include ../Rules
|
|
|
@ -1,32 +0,0 @@
|
||||||
This patch is similar to glibc-asflags.patch and is needed to change
|
|
||||||
the ld.so linker flags. It is needed to work around this valgrind
|
|
||||||
bug: https://bugzilla.redhat.com/show_bug.cgi?id=1600034
|
|
||||||
|
|
||||||
diff --git a/Makeconfig b/Makeconfig
|
|
||||||
index 92e76d6200bbcd5b..376181c8ff06dea7 100644
|
|
||||||
--- a/Makeconfig
|
|
||||||
+++ b/Makeconfig
|
|
||||||
@@ -363,12 +363,12 @@ endif
|
|
||||||
ifeq (yesyes,$(build-shared)$(have-z-combreloc))
|
|
||||||
combreloc-LDFLAGS = -Wl,-z,combreloc
|
|
||||||
LDFLAGS.so += $(combreloc-LDFLAGS)
|
|
||||||
-LDFLAGS-rtld += $(combreloc-LDFLAGS)
|
|
||||||
+override LDFLAGS-rtld += $(combreloc-LDFLAGS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
relro-LDFLAGS = -Wl,-z,relro
|
|
||||||
LDFLAGS.so += $(relro-LDFLAGS)
|
|
||||||
-LDFLAGS-rtld += $(relro-LDFLAGS)
|
|
||||||
+override LDFLAGS-rtld += $(relro-LDFLAGS)
|
|
||||||
|
|
||||||
ifeq (yes,$(have-hash-style))
|
|
||||||
# For the time being we unconditionally use 'both'. At some time we
|
|
||||||
@@ -376,7 +376,7 @@ ifeq (yes,$(have-hash-style))
|
|
||||||
# with --hash-style=gnu only.
|
|
||||||
hashstyle-LDFLAGS = -Wl,--hash-style=both
|
|
||||||
LDFLAGS.so += $(hashstyle-LDFLAGS)
|
|
||||||
-LDFLAGS-rtld += $(hashstyle-LDFLAGS)
|
|
||||||
+override LDFLAGS-rtld += $(hashstyle-LDFLAGS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (yes,$(enable-static-pie))
|
|
|
@ -1,272 +0,0 @@
|
||||||
Short description: RPM Post-upgrade cleanup program.
|
|
||||||
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
|
|
||||||
Origin: PATCH
|
|
||||||
Upstream status: not-needed
|
|
||||||
|
|
||||||
A helper program is needed to clean up the system configuration
|
|
||||||
early during RPM package installation, so that other scriptlets
|
|
||||||
can run successfully.
|
|
||||||
|
|
||||||
diff --git a/elf/Makefile b/elf/Makefile
|
|
||||||
index 2a432d8beebcd207..368dcae477fff2ae 100644
|
|
||||||
--- a/elf/Makefile
|
|
||||||
+++ b/elf/Makefile
|
|
||||||
@@ -117,6 +117,14 @@ others-extras = $(ldconfig-modules)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
+# This needs to be statically linked because it is executed at a time
|
|
||||||
+# when there might be incompatible shared objects on disk, and the
|
|
||||||
+# purpose of this program is to remove them (among other things).
|
|
||||||
+others-static += glibc_post_upgrade
|
|
||||||
+others += glibc_post_upgrade
|
|
||||||
+glibc_post_upgrade-modules := static-stubs
|
|
||||||
+CFLAGS-glibc_post_upgrade.c += -DGCONV_MODULES_DIR='"$(gconvdir)"'
|
|
||||||
+
|
|
||||||
# To find xmalloc.c and xstrdup.c
|
|
||||||
vpath %.c ../locale/programs
|
|
||||||
|
|
||||||
@@ -559,6 +567,8 @@ $(objpfx)sln: $(sln-modules:%=$(objpfx)%.o)
|
|
||||||
|
|
||||||
$(objpfx)ldconfig: $(ldconfig-modules:%=$(objpfx)%.o)
|
|
||||||
|
|
||||||
+$(objpfx)glibc_post_upgrade: $(glibc_post_upgrade-modules:%=$(objpfx)%.o)
|
|
||||||
+
|
|
||||||
SYSCONF-FLAGS := -D'SYSCONFDIR="$(sysconfdir)"'
|
|
||||||
CFLAGS-ldconfig.c += $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \
|
|
||||||
-D'SLIBDIR="$(slibdir)"'
|
|
||||||
diff --git a/elf/glibc_post_upgrade.c b/elf/glibc_post_upgrade.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000..19b59f70e2308032
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/elf/glibc_post_upgrade.c
|
|
||||||
@@ -0,0 +1,229 @@
|
|
||||||
+#include <sys/types.h>
|
|
||||||
+#include <sys/wait.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <sys/time.h>
|
|
||||||
+#include <dirent.h>
|
|
||||||
+#include <stddef.h>
|
|
||||||
+#include <fcntl.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+
|
|
||||||
+#define LD_SO_CONF "/etc/ld.so.conf"
|
|
||||||
+#define ICONVCONFIG "/usr/sbin/iconvconfig"
|
|
||||||
+
|
|
||||||
+#define verbose_exec(failcode, path...) \
|
|
||||||
+ do \
|
|
||||||
+ { \
|
|
||||||
+ char *const arr[] = { path, NULL }; \
|
|
||||||
+ vexec (failcode, arr); \
|
|
||||||
+ } while (0)
|
|
||||||
+
|
|
||||||
+__attribute__((noinline)) static void vexec (int failcode, char *const path[]);
|
|
||||||
+__attribute__((noinline)) static void says (const char *str);
|
|
||||||
+__attribute__((noinline)) static void sayn (long num);
|
|
||||||
+__attribute__((noinline)) static void message (char *const path[]);
|
|
||||||
+
|
|
||||||
+int
|
|
||||||
+main (void)
|
|
||||||
+{
|
|
||||||
+ char initpath[256];
|
|
||||||
+
|
|
||||||
+ char buffer[4096];
|
|
||||||
+ struct pref {
|
|
||||||
+ const char *p;
|
|
||||||
+ int len;
|
|
||||||
+ } prefix[] = { { "libc-", 5 }, { "libm-", 5 },
|
|
||||||
+ { "librt-", 6 }, { "libpthread-", 11 },
|
|
||||||
+ { "librtkaio-", 10 }, { "libthread_db-", 13 } };
|
|
||||||
+ int i, j, fd;
|
|
||||||
+ off_t base;
|
|
||||||
+ ssize_t ret;
|
|
||||||
+
|
|
||||||
+ /* In order to support in-place upgrades, we must immediately remove
|
|
||||||
+ obsolete platform directories after installing a new glibc
|
|
||||||
+ version. RPM only deletes files removed by updates near the end
|
|
||||||
+ of the transaction. If we did not remove the obsolete platform
|
|
||||||
+ directories here, they would be preferred by the dynamic linker
|
|
||||||
+ during the execution of subsequent RPM scriptlets, likely
|
|
||||||
+ resulting in process startup failures. */
|
|
||||||
+ const char *remove_dirs[] =
|
|
||||||
+ {
|
|
||||||
+#if defined (__i386__)
|
|
||||||
+ "/lib/i686",
|
|
||||||
+ "/lib/i686/nosegneg",
|
|
||||||
+#elif defined (__powerpc64__) && _CALL_ELF != 2
|
|
||||||
+ "/lib64/power6",
|
|
||||||
+#endif
|
|
||||||
+ };
|
|
||||||
+ for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
|
|
||||||
+ {
|
|
||||||
+ size_t rmlen = strlen (remove_dirs[j]);
|
|
||||||
+ fd = open (remove_dirs[j], O_RDONLY);
|
|
||||||
+ if (fd >= 0
|
|
||||||
+ && (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
|
|
||||||
+ >= (ssize_t) offsetof (struct dirent, d_name))
|
|
||||||
+ {
|
|
||||||
+ for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
|
|
||||||
+ {
|
|
||||||
+ struct dirent *d = (struct dirent *) (buffer + base);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
|
|
||||||
+ if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
|
|
||||||
+ {
|
|
||||||
+ char *p = d->d_name + prefix[i].len;
|
|
||||||
+
|
|
||||||
+ while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
|
|
||||||
+ if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
|
|
||||||
+ && p + 3 - d->d_name
|
|
||||||
+ < sizeof (initpath) - rmlen - 1)
|
|
||||||
+ {
|
|
||||||
+ memcpy (initpath, remove_dirs[j], rmlen);
|
|
||||||
+ initpath[rmlen] = '/';
|
|
||||||
+ strcpy (initpath + rmlen + 1, d->d_name);
|
|
||||||
+ unlink (initpath);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ base += d->d_reclen;
|
|
||||||
+ }
|
|
||||||
+ close (fd);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ int ldsocfd = open (LD_SO_CONF, O_RDONLY);
|
|
||||||
+ struct stat ldsocst;
|
|
||||||
+ if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
|
|
||||||
+ {
|
|
||||||
+ char p[ldsocst.st_size + 1];
|
|
||||||
+ if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
|
|
||||||
+ {
|
|
||||||
+ p[ldsocst.st_size] = '\0';
|
|
||||||
+ if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
|
|
||||||
+ {
|
|
||||||
+ close (ldsocfd);
|
|
||||||
+ ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
|
|
||||||
+ if (ldsocfd >= 0)
|
|
||||||
+ {
|
|
||||||
+ size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
|
|
||||||
+ if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
|
|
||||||
+ != slen
|
|
||||||
+ || write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
|
|
||||||
+ _exit (109);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (ldsocfd >= 0)
|
|
||||||
+ close (ldsocfd);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* If installing bi-arch glibc, rpm sometimes doesn't unpack all files
|
|
||||||
+ before running one of the lib's %post scriptlet. /sbin/ldconfig will
|
|
||||||
+ then be run by the other arch's %post. */
|
|
||||||
+ if (! access ("/sbin/ldconfig", X_OK))
|
|
||||||
+ verbose_exec (110,
|
|
||||||
+ (char *) "/sbin/ldconfig",
|
|
||||||
+ (char *) "/sbin/ldconfig");
|
|
||||||
+
|
|
||||||
+ if (! utimes (GCONV_MODULES_DIR "/gconv-modules.cache", NULL))
|
|
||||||
+ {
|
|
||||||
+ const char *iconv_cache = GCONV_MODULES_DIR "/gconv-modules.cache";
|
|
||||||
+ const char *iconv_dir = GCONV_MODULES_DIR;
|
|
||||||
+ verbose_exec (113,
|
|
||||||
+ (char *) ICONVCONFIG,
|
|
||||||
+ (char *) "/usr/sbin/iconvconfig",
|
|
||||||
+ (char *) "-o",
|
|
||||||
+ (char *) iconv_cache,
|
|
||||||
+ (char *) "--nostdlib",
|
|
||||||
+ (char *) iconv_dir);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ _exit(0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+vexec (int failcode, char *const path[])
|
|
||||||
+{
|
|
||||||
+ pid_t pid;
|
|
||||||
+ int status, save_errno;
|
|
||||||
+ int devnull = 0;
|
|
||||||
+
|
|
||||||
+ if (failcode < 0)
|
|
||||||
+ {
|
|
||||||
+ devnull = 1;
|
|
||||||
+ failcode = -failcode;
|
|
||||||
+ }
|
|
||||||
+ pid = vfork ();
|
|
||||||
+ if (pid == 0)
|
|
||||||
+ {
|
|
||||||
+ int fd;
|
|
||||||
+ if (devnull && (fd = open ("/dev/null", O_WRONLY)) >= 0)
|
|
||||||
+ {
|
|
||||||
+ dup2 (fd, 1);
|
|
||||||
+ dup2 (fd, 2);
|
|
||||||
+ close (fd);
|
|
||||||
+ }
|
|
||||||
+ execv (path[0], path + 1);
|
|
||||||
+ save_errno = errno;
|
|
||||||
+ message (path);
|
|
||||||
+ says (" exec failed with errno ");
|
|
||||||
+ sayn (save_errno);
|
|
||||||
+ says ("\n");
|
|
||||||
+ _exit (failcode);
|
|
||||||
+ }
|
|
||||||
+ else if (pid < 0)
|
|
||||||
+ {
|
|
||||||
+ save_errno = errno;
|
|
||||||
+ message (path);
|
|
||||||
+ says (" fork failed with errno ");
|
|
||||||
+ sayn (save_errno);
|
|
||||||
+ says ("\n");
|
|
||||||
+ _exit (failcode + 1);
|
|
||||||
+ }
|
|
||||||
+ if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
|
||||||
+ {
|
|
||||||
+ message (path);
|
|
||||||
+ says (" child terminated abnormally\n");
|
|
||||||
+ _exit (failcode + 2);
|
|
||||||
+ }
|
|
||||||
+ if (WEXITSTATUS (status))
|
|
||||||
+ {
|
|
||||||
+ message (path);
|
|
||||||
+ says (" child exited with exit code ");
|
|
||||||
+ sayn (WEXITSTATUS (status));
|
|
||||||
+ says ("\n");
|
|
||||||
+ _exit (WEXITSTATUS (status));
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+says (const char *str)
|
|
||||||
+{
|
|
||||||
+ write (1, str, strlen (str));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+sayn (long num)
|
|
||||||
+{
|
|
||||||
+ char string[sizeof (long) * 3 + 1];
|
|
||||||
+ char *p = string + sizeof (string) - 1;
|
|
||||||
+
|
|
||||||
+ *p = '\0';
|
|
||||||
+ if (num == 0)
|
|
||||||
+ *--p = '0';
|
|
||||||
+ else
|
|
||||||
+ while (num)
|
|
||||||
+ {
|
|
||||||
+ *--p = '0' + num % 10;
|
|
||||||
+ num = num / 10;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ says (p);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+message (char *const path[])
|
|
||||||
+{
|
|
||||||
+ says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
|
|
||||||
+ says (path[0]);
|
|
||||||
+}
|
|
|
@ -9,32 +9,32 @@ python3 during a transitional phase.
|
||||||
Author: Carlos O'Donell <carlos@redhat.com>
|
Author: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
diff --git a/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py
|
diff --git a/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py
|
||||||
index ea25f778c09bba9d..b53beb3c6e32c3cf 100755
|
index c1c438a1c9f0eae6..b7d3d7bcee87969d 100755
|
||||||
--- a/benchtests/scripts/compare_bench.py
|
--- a/benchtests/scripts/compare_bench.py
|
||||||
+++ b/benchtests/scripts/compare_bench.py
|
+++ b/benchtests/scripts/compare_bench.py
|
||||||
@@ -1,4 +1,4 @@
|
@@ -1,4 +1,4 @@
|
||||||
-#!/usr/bin/python
|
-#!/usr/bin/python
|
||||||
+#!/usr/bin/python3
|
+#!/usr/bin/python3
|
||||||
# Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
# Copyright (C) 2015-2019 Free Software Foundation, Inc.
|
||||||
# This file is part of the GNU C Library.
|
# This file is part of the GNU C Library.
|
||||||
#
|
#
|
||||||
diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py
|
diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py
|
||||||
index 602b3f954d4801a6..76bf1528a5418748 100644
|
index 7a55d19f038e64d4..72e6034243a8c9b6 100644
|
||||||
--- a/benchtests/scripts/import_bench.py
|
--- a/benchtests/scripts/import_bench.py
|
||||||
+++ b/benchtests/scripts/import_bench.py
|
+++ b/benchtests/scripts/import_bench.py
|
||||||
@@ -1,4 +1,4 @@
|
@@ -1,4 +1,4 @@
|
||||||
-#!/usr/bin/python
|
-#!/usr/bin/python
|
||||||
+#!/usr/bin/python3
|
+#!/usr/bin/python3
|
||||||
# Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
# Copyright (C) 2015-2019 Free Software Foundation, Inc.
|
||||||
# This file is part of the GNU C Library.
|
# This file is part of the GNU C Library.
|
||||||
#
|
#
|
||||||
diff --git a/benchtests/scripts/validate_benchout.py b/benchtests/scripts/validate_benchout.py
|
diff --git a/benchtests/scripts/validate_benchout.py b/benchtests/scripts/validate_benchout.py
|
||||||
index 6147f05bec3a4844..9a5c7947ee4ed7e9 100755
|
index 55d07c6bce5b5184..04129f9c26c2874c 100755
|
||||||
--- a/benchtests/scripts/validate_benchout.py
|
--- a/benchtests/scripts/validate_benchout.py
|
||||||
+++ b/benchtests/scripts/validate_benchout.py
|
+++ b/benchtests/scripts/validate_benchout.py
|
||||||
@@ -1,4 +1,4 @@
|
@@ -1,4 +1,4 @@
|
||||||
-#!/usr/bin/python
|
-#!/usr/bin/python
|
||||||
+#!/usr/bin/python3
|
+#!/usr/bin/python3
|
||||||
# Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
# Copyright (C) 2014-2019 Free Software Foundation, Inc.
|
||||||
# This file is part of the GNU C Library.
|
# This file is part of the GNU C Library.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,254 +0,0 @@
|
||||||
commit 4b25485f03158959cff45379eecc1d73c7dcdd11
|
|
||||||
Author: Florian Weimer <fweimer@redhat.com>
|
|
||||||
Date: Fri Aug 10 11:19:26 2018 +0200
|
|
||||||
|
|
||||||
Linux: Rewrite __old_getdents64 [BZ #23497]
|
|
||||||
|
|
||||||
Commit 298d0e3129c0b5137f4989275b13fe30d0733c4d ("Consolidate Linux
|
|
||||||
getdents{64} implementation") broke the implementation because it does
|
|
||||||
not take into account struct offset differences.
|
|
||||||
|
|
||||||
The new implementation is close to the old one, before the
|
|
||||||
consolidation, but has been cleaned up slightly.
|
|
||||||
|
|
||||||
(cherry picked from commit 690652882b499defb3d950dfeff8fe421d13cab5)
|
|
||||||
|
|
||||||
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
|
||||||
index f71cc39c7e257a0a..773aaea0e980bdd6 100644
|
|
||||||
--- a/sysdeps/unix/sysv/linux/Makefile
|
|
||||||
+++ b/sysdeps/unix/sysv/linux/Makefile
|
|
||||||
@@ -161,6 +161,7 @@ inhibit-glue = yes
|
|
||||||
|
|
||||||
ifeq ($(subdir),dirent)
|
|
||||||
sysdep_routines += getdirentries getdirentries64
|
|
||||||
+tests-internal += tst-readdir64-compat
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(subdir),nis)
|
|
||||||
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
|
|
||||||
index 3bde0cf4f0226f95..bc140b5a7fac3040 100644
|
|
||||||
--- a/sysdeps/unix/sysv/linux/getdents64.c
|
|
||||||
+++ b/sysdeps/unix/sysv/linux/getdents64.c
|
|
||||||
@@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents)
|
|
||||||
# include <shlib-compat.h>
|
|
||||||
|
|
||||||
# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
|
|
||||||
-# include <olddirent.h>
|
|
||||||
+# include <olddirent.h>
|
|
||||||
+# include <unistd.h>
|
|
||||||
|
|
||||||
-/* kernel definition of as of 3.2. */
|
|
||||||
-struct compat_linux_dirent
|
|
||||||
+static ssize_t
|
|
||||||
+handle_overflow (int fd, __off64_t offset, ssize_t count)
|
|
||||||
{
|
|
||||||
- /* Both d_ino and d_off are compat_ulong_t which are defined in all
|
|
||||||
- architectures as 'u32'. */
|
|
||||||
- uint32_t d_ino;
|
|
||||||
- uint32_t d_off;
|
|
||||||
- unsigned short d_reclen;
|
|
||||||
- char d_name[1];
|
|
||||||
-};
|
|
||||||
+ /* If this is the first entry in the buffer, we can report the
|
|
||||||
+ error. */
|
|
||||||
+ if (count == 0)
|
|
||||||
+ {
|
|
||||||
+ __set_errno (EOVERFLOW);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Otherwise, seek to the overflowing entry, so that the next call
|
|
||||||
+ will report the error, and return the data read so far.. */
|
|
||||||
+ if (__lseek64 (fd, offset, SEEK_SET) != 0)
|
|
||||||
+ return -1;
|
|
||||||
+ return count;
|
|
||||||
+}
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
__old_getdents64 (int fd, char *buf, size_t nbytes)
|
|
||||||
{
|
|
||||||
- ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes);
|
|
||||||
+ /* We do not move the individual directory entries. This is only
|
|
||||||
+ possible if the target type (struct __old_dirent64) is smaller
|
|
||||||
+ than the source type. */
|
|
||||||
+ _Static_assert (offsetof (struct __old_dirent64, d_name)
|
|
||||||
+ <= offsetof (struct dirent64, d_name),
|
|
||||||
+ "__old_dirent64 is larger than dirent64");
|
|
||||||
+ _Static_assert (__alignof__ (struct __old_dirent64)
|
|
||||||
+ <= __alignof__ (struct dirent64),
|
|
||||||
+ "alignment of __old_dirent64 is larger than dirent64");
|
|
||||||
|
|
||||||
- /* The kernel added the d_type value after the name. Change this now. */
|
|
||||||
- if (retval != -1)
|
|
||||||
+ ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
|
|
||||||
+ if (retval > 0)
|
|
||||||
{
|
|
||||||
- union
|
|
||||||
- {
|
|
||||||
- struct compat_linux_dirent k;
|
|
||||||
- struct dirent u;
|
|
||||||
- } *kbuf = (void *) buf;
|
|
||||||
-
|
|
||||||
- while ((char *) kbuf < buf + retval)
|
|
||||||
+ char *p = buf;
|
|
||||||
+ char *end = buf + retval;
|
|
||||||
+ while (p < end)
|
|
||||||
{
|
|
||||||
- char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1);
|
|
||||||
- memmove (kbuf->u.d_name, kbuf->k.d_name,
|
|
||||||
- strlen (kbuf->k.d_name) + 1);
|
|
||||||
- kbuf->u.d_type = d_type;
|
|
||||||
+ struct dirent64 *source = (struct dirent64 *) p;
|
|
||||||
+
|
|
||||||
+ /* Copy out the fixed-size data. */
|
|
||||||
+ __ino_t ino = source->d_ino;
|
|
||||||
+ __off64_t offset = source->d_off;
|
|
||||||
+ unsigned int reclen = source->d_reclen;
|
|
||||||
+ unsigned char type = source->d_type;
|
|
||||||
+
|
|
||||||
+ /* Check for ino_t overflow. */
|
|
||||||
+ if (__glibc_unlikely (ino != source->d_ino))
|
|
||||||
+ return handle_overflow (fd, offset, p - buf);
|
|
||||||
+
|
|
||||||
+ /* Convert to the target layout. Use a separate struct and
|
|
||||||
+ memcpy to side-step aliasing issues. */
|
|
||||||
+ struct __old_dirent64 result;
|
|
||||||
+ result.d_ino = ino;
|
|
||||||
+ result.d_off = offset;
|
|
||||||
+ result.d_reclen = reclen;
|
|
||||||
+ result.d_type = type;
|
|
||||||
+
|
|
||||||
+ /* Write the fixed-sized part of the result to the
|
|
||||||
+ buffer. */
|
|
||||||
+ size_t result_name_offset = offsetof (struct __old_dirent64, d_name);
|
|
||||||
+ memcpy (p, &result, result_name_offset);
|
|
||||||
+
|
|
||||||
+ /* Adjust the position of the name if necessary. Copy
|
|
||||||
+ everything until the end of the record, including the
|
|
||||||
+ terminating NUL byte. */
|
|
||||||
+ if (result_name_offset != offsetof (struct dirent64, d_name))
|
|
||||||
+ memmove (p + result_name_offset, source->d_name,
|
|
||||||
+ reclen - offsetof (struct dirent64, d_name));
|
|
||||||
|
|
||||||
- kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen);
|
|
||||||
+ p += reclen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000..43c4a8477c7403c5
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
|
|
||||||
@@ -0,0 +1,111 @@
|
|
||||||
+/* Test readdir64 compatibility symbol.
|
|
||||||
+ Copyright (C) 2018 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
|
|
||||||
+ <http://www.gnu.org/licenses/>. */
|
|
||||||
+
|
|
||||||
+#include <dirent.h>
|
|
||||||
+#include <dlfcn.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+#include <shlib-compat.h>
|
|
||||||
+#include <stdbool.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <support/check.h>
|
|
||||||
+
|
|
||||||
+/* Copied from <olddirent.h>. */
|
|
||||||
+struct __old_dirent64
|
|
||||||
+ {
|
|
||||||
+ __ino_t d_ino;
|
|
||||||
+ __off64_t d_off;
|
|
||||||
+ unsigned short int d_reclen;
|
|
||||||
+ unsigned char d_type;
|
|
||||||
+ char d_name[256];
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *);
|
|
||||||
+
|
|
||||||
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
|
|
||||||
+struct __old_dirent64 *compat_readdir64 (DIR *);
|
|
||||||
+compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
+do_test (void)
|
|
||||||
+{
|
|
||||||
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
|
|
||||||
+
|
|
||||||
+ /* Directory stream using the non-compat readdir64 symbol. The test
|
|
||||||
+ checks against this. */
|
|
||||||
+ DIR *dir_reference = opendir (".");
|
|
||||||
+ TEST_VERIFY_EXIT (dir_reference != NULL);
|
|
||||||
+ DIR *dir_test = opendir (".");
|
|
||||||
+ TEST_VERIFY_EXIT (dir_test != NULL);
|
|
||||||
+
|
|
||||||
+ /* This loop assumes that the enumeration order is consistent for
|
|
||||||
+ two different handles. Nothing should write to the current
|
|
||||||
+ directory (in the source tree) while this test runs, so there
|
|
||||||
+ should not be any difference due to races. */
|
|
||||||
+ size_t count = 0;
|
|
||||||
+ while (true)
|
|
||||||
+ {
|
|
||||||
+ errno = 0;
|
|
||||||
+ struct dirent64 *entry_reference = readdir64 (dir_reference);
|
|
||||||
+ if (entry_reference == NULL && errno != 0)
|
|
||||||
+ FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count);
|
|
||||||
+ struct __old_dirent64 *entry_test = compat_readdir64 (dir_test);
|
|
||||||
+ if (entry_reference == NULL)
|
|
||||||
+ {
|
|
||||||
+ if (errno == EOVERFLOW)
|
|
||||||
+ {
|
|
||||||
+ TEST_VERIFY (entry_reference->d_ino
|
|
||||||
+ != (__ino_t) entry_reference->d_ino);
|
|
||||||
+ printf ("info: inode number overflow at entry %zu\n", count);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (errno != 0)
|
|
||||||
+ FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Check that both streams end at the same time. */
|
|
||||||
+ if (entry_reference == NULL)
|
|
||||||
+ {
|
|
||||||
+ TEST_VERIFY (entry_test == NULL);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ TEST_VERIFY_EXIT (entry_test != NULL);
|
|
||||||
+
|
|
||||||
+ /* Check that the entries are the same. */
|
|
||||||
+ TEST_COMPARE_BLOB (entry_reference->d_name,
|
|
||||||
+ strlen (entry_reference->d_name),
|
|
||||||
+ entry_test->d_name, strlen (entry_test->d_name));
|
|
||||||
+ TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino);
|
|
||||||
+ TEST_COMPARE (entry_reference->d_off, entry_test->d_off);
|
|
||||||
+ TEST_COMPARE (entry_reference->d_type, entry_test->d_type);
|
|
||||||
+ TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen);
|
|
||||||
+
|
|
||||||
+ ++count;
|
|
||||||
+ }
|
|
||||||
+ printf ("info: %zu directory entries found\n", count);
|
|
||||||
+ TEST_VERIFY (count >= 3); /* ".", "..", and some source files. */
|
|
||||||
+
|
|
||||||
+ TEST_COMPARE (closedir (dir_test), 0);
|
|
||||||
+ TEST_COMPARE (closedir (dir_reference), 0);
|
|
||||||
+#endif
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#include <support/test-driver.c>
|
|
|
@ -1,139 +0,0 @@
|
||||||
Author: Florian Weimer <fweimer@redhat.com>
|
|
||||||
Date: Wed Jul 4 11:34:36 2018 +0200
|
|
||||||
|
|
||||||
Add --with-nonshared-cflags option to configure
|
|
||||||
|
|
||||||
Submitted upstream:
|
|
||||||
|
|
||||||
https://sourceware.org/ml/libc-alpha/2018-07/msg00071.html
|
|
||||||
|
|
||||||
diff --git a/INSTALL b/INSTALL
|
|
||||||
index 0a22aa7d01e6e87b..0f80d9d615db6d42 100644
|
|
||||||
--- a/INSTALL
|
|
||||||
+++ b/INSTALL
|
|
||||||
@@ -90,6 +90,15 @@ if 'CFLAGS' is specified it must enable optimization. For example:
|
|
||||||
library will still be usable, but functionality may be lost--for
|
|
||||||
example, you can't build a shared libc with old binutils.
|
|
||||||
|
|
||||||
+'--with-nonshared-cflags=CFLAGS'
|
|
||||||
+ Use additional compiler flags CFLAGS to build the parts of the
|
|
||||||
+ library which are always statically linked into applications and
|
|
||||||
+ libraries even with shared linking (that is, the object files
|
|
||||||
+ contained in 'lib*_nonshared.a' libraries). The build process will
|
|
||||||
+ automatically use the appropriate flags, but this option can be
|
|
||||||
+ used to set additional flags required for building applications and
|
|
||||||
+ libraries, to match local policy.
|
|
||||||
+
|
|
||||||
'--disable-shared'
|
|
||||||
Don't build shared libraries even if it is possible. Not all
|
|
||||||
systems support shared libraries; you need ELF support and
|
|
||||||
diff --git a/Makeconfig b/Makeconfig
|
|
||||||
index 608ffe648c80c724..b0b27f0113ac18b8 100644
|
|
||||||
--- a/Makeconfig
|
|
||||||
+++ b/Makeconfig
|
|
||||||
@@ -1038,7 +1038,7 @@ object-suffixes-for-libc += .oS
|
|
||||||
# Must build the routines as PIC, though, because they can end up in (users')
|
|
||||||
# shared objects. We don't want to use CFLAGS-os because users may, for
|
|
||||||
# example, make that processor-specific.
|
|
||||||
-CFLAGS-.oS = $(CFLAGS-.o) $(PIC-ccflag)
|
|
||||||
+CFLAGS-.oS = $(CFLAGS-.o) $(PIC-ccflag) $(extra-nonshared-cflags)
|
|
||||||
CPPFLAGS-.oS = $(CPPFLAGS-.o) -DPIC -DLIBC_NONSHARED=1
|
|
||||||
libtype.oS = lib%_nonshared.a
|
|
||||||
endif
|
|
||||||
diff --git a/config.make.in b/config.make.in
|
|
||||||
index d9891b2cd8ec3fbf..a6fe48d31f4d2725 100644
|
|
||||||
--- a/config.make.in
|
|
||||||
+++ b/config.make.in
|
|
||||||
@@ -110,6 +110,7 @@ BUILD_CC = @BUILD_CC@
|
|
||||||
CFLAGS = @CFLAGS@
|
|
||||||
CPPFLAGS-config = @CPPFLAGS@
|
|
||||||
CPPUNDEFS = @CPPUNDEFS@
|
|
||||||
+extra-nonshared-cflags = @extra_nonshared_cflags@
|
|
||||||
ASFLAGS-config = @ASFLAGS_config@
|
|
||||||
AR = @AR@
|
|
||||||
NM = @NM@
|
|
||||||
diff --git a/configure b/configure
|
|
||||||
index ef1830221522b7a5..fec0efff8216addd 100755
|
|
||||||
--- a/configure
|
|
||||||
+++ b/configure
|
|
||||||
@@ -684,6 +684,7 @@ force_install
|
|
||||||
bindnow
|
|
||||||
hardcoded_path_in_tests
|
|
||||||
enable_timezone_tools
|
|
||||||
+extra_nonshared_cflags
|
|
||||||
use_default_link
|
|
||||||
sysheaders
|
|
||||||
ac_ct_CXX
|
|
||||||
@@ -762,6 +763,7 @@ with_binutils
|
|
||||||
with_selinux
|
|
||||||
with_headers
|
|
||||||
with_default_link
|
|
||||||
+with_nonshared_cflags
|
|
||||||
enable_sanity_checks
|
|
||||||
enable_shared
|
|
||||||
enable_profile
|
|
||||||
@@ -1479,6 +1481,8 @@ Optional Packages:
|
|
||||||
--with-headers=PATH location of system headers to use (for example
|
|
||||||
/usr/src/linux/include) [default=compiler default]
|
|
||||||
--with-default-link do not use explicit linker scripts
|
|
||||||
+ --with-nonshared-cflags=FLAGS
|
|
||||||
+ build nonshared libraries with additional FLAGS
|
|
||||||
--with-cpu=CPU select code for CPU variant
|
|
||||||
|
|
||||||
Some influential environment variables:
|
|
||||||
@@ -3336,6 +3340,16 @@ else
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
+
|
|
||||||
+# Check whether --with-nonshared-cflags was given.
|
|
||||||
+if test "${with_nonshared_cflags+set}" = set; then :
|
|
||||||
+ withval=$with_nonshared_cflags; extra_nonshared_cflags=$withval
|
|
||||||
+else
|
|
||||||
+ extra_nonshared_cflags=
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
# Check whether --enable-sanity-checks was given.
|
|
||||||
if test "${enable_sanity_checks+set}" = set; then :
|
|
||||||
enableval=$enable_sanity_checks; enable_sanity=$enableval
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index dc517017f588626a..154185d70de38928 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -154,6 +154,14 @@ AC_ARG_WITH([default-link],
|
|
||||||
[use_default_link=$withval],
|
|
||||||
[use_default_link=default])
|
|
||||||
|
|
||||||
+dnl Additional build flags injection.
|
|
||||||
+AC_ARG_WITH([nonshared-cflags],
|
|
||||||
+ AC_HELP_STRING([--with-nonshared-cflags=FLAGS],
|
|
||||||
+ [build nonshared libraries with additional FLAGS]),
|
|
||||||
+ [extra_nonshared_cflags=$withval],
|
|
||||||
+ [extra_nonshared_cflags=])
|
|
||||||
+AC_SUBST(extra_nonshared_cflags)
|
|
||||||
+
|
|
||||||
AC_ARG_ENABLE([sanity-checks],
|
|
||||||
AC_HELP_STRING([--disable-sanity-checks],
|
|
||||||
[really do not use threads (should not be used except in special situations) @<:@default=yes@:>@]),
|
|
||||||
diff --git a/manual/install.texi b/manual/install.texi
|
|
||||||
index 422da1447eb4dc68..eaf0cd09e7501b96 100644
|
|
||||||
--- a/manual/install.texi
|
|
||||||
+++ b/manual/install.texi
|
|
||||||
@@ -117,6 +117,15 @@ problem and suppress these constructs, so that the library will still be
|
|
||||||
usable, but functionality may be lost---for example, you can't build a
|
|
||||||
shared libc with old binutils.
|
|
||||||
|
|
||||||
+@item --with-nonshared-cflags=@var{cflags}
|
|
||||||
+Use additional compiler flags @var{cflags} to build the parts of the
|
|
||||||
+library which are always statically linked into applications and
|
|
||||||
+libraries even with shared linking (that is, the object files contained
|
|
||||||
+in @file{lib*_nonshared.a} libraries). The build process will
|
|
||||||
+automatically use the appropriate flags, but this option can be used to
|
|
||||||
+set additional flags required for building applications and libraries,
|
|
||||||
+to match local policy.
|
|
||||||
+
|
|
||||||
@c disable static doesn't work currently
|
|
||||||
@c @item --disable-static
|
|
||||||
@c Don't build static libraries. Static libraries aren't that useful these
|
|
1160
glibc.spec
1160
glibc.spec
File diff suppressed because it is too large
Load Diff
|
@ -1,274 +0,0 @@
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <elf.h>
|
|
||||||
|
|
||||||
#define LD_SO_CONF "/etc/ld.so.conf"
|
|
||||||
#define ICONVCONFIG "/usr/sbin/iconvconfig"
|
|
||||||
|
|
||||||
#define verbose_exec(failcode, path...) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
char *const arr[] = { path, NULL }; \
|
|
||||||
vexec (failcode, arr); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
__attribute__((noinline)) void vexec (int failcode, char *const path[]);
|
|
||||||
__attribute__((noinline)) void says (const char *str);
|
|
||||||
__attribute__((noinline)) void sayn (long num);
|
|
||||||
__attribute__((noinline)) void message (char *const path[]);
|
|
||||||
__attribute__((noinline)) int check_elf (const char *name);
|
|
||||||
|
|
||||||
int
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
struct stat statbuf;
|
|
||||||
char initpath[256];
|
|
||||||
|
|
||||||
char buffer[4096];
|
|
||||||
struct pref {
|
|
||||||
char *p;
|
|
||||||
int len;
|
|
||||||
} prefix[] = { { "libc-", 5 }, { "libm-", 5 },
|
|
||||||
{ "librt-", 6 }, { "libpthread-", 11 },
|
|
||||||
{ "librtkaio-", 10 }, { "libthread_db-", 13 } };
|
|
||||||
int i, j, fd;
|
|
||||||
off_t base;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
/* In order to support in-place upgrades, we must immediately remove
|
|
||||||
obsolete platform directories after installing a new glibc
|
|
||||||
version. RPM only deletes files removed by updates near the end
|
|
||||||
of the transaction. If we did not remove the obsolete platform
|
|
||||||
directories here, they would be preferred by the dynamic linker
|
|
||||||
during the execution of subsequent RPM scriptlets, likely
|
|
||||||
resulting in process startup failures. */
|
|
||||||
const char *remove_dirs[] =
|
|
||||||
{
|
|
||||||
#if defined (__i386__)
|
|
||||||
"/lib/i686",
|
|
||||||
"/lib/i686/nosegneg",
|
|
||||||
#elif defined (__powerpc64__) && _CALL_ELF != 2
|
|
||||||
"/lib64/power6",
|
|
||||||
"/lib64/power7",
|
|
||||||
"/lib64/power8",
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
|
|
||||||
{
|
|
||||||
size_t rmlen = strlen (remove_dirs[j]);
|
|
||||||
fd = open (remove_dirs[j], O_RDONLY);
|
|
||||||
if (fd >= 0
|
|
||||||
&& (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
|
|
||||||
>= (ssize_t) offsetof (struct dirent, d_name))
|
|
||||||
{
|
|
||||||
for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
|
|
||||||
{
|
|
||||||
struct dirent *d = (struct dirent *) (buffer + base);
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
|
|
||||||
if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
|
|
||||||
{
|
|
||||||
char *p = d->d_name + prefix[i].len;
|
|
||||||
|
|
||||||
while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
|
|
||||||
if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
|
|
||||||
&& p + 3 - d->d_name
|
|
||||||
< sizeof (initpath) - rmlen - 1)
|
|
||||||
{
|
|
||||||
memcpy (initpath, remove_dirs[j], rmlen);
|
|
||||||
initpath[rmlen] = '/';
|
|
||||||
strcpy (initpath + rmlen + 1, d->d_name);
|
|
||||||
unlink (initpath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base += d->d_reclen;
|
|
||||||
}
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ldsocfd = open (LD_SO_CONF, O_RDONLY);
|
|
||||||
struct stat ldsocst;
|
|
||||||
if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
|
|
||||||
{
|
|
||||||
char p[ldsocst.st_size + 1];
|
|
||||||
if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
|
|
||||||
{
|
|
||||||
p[ldsocst.st_size] = '\0';
|
|
||||||
if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
|
|
||||||
{
|
|
||||||
close (ldsocfd);
|
|
||||||
ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
|
|
||||||
if (ldsocfd >= 0)
|
|
||||||
{
|
|
||||||
size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
|
|
||||||
if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
|
|
||||||
!= slen
|
|
||||||
|| write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
|
|
||||||
_exit (109);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ldsocfd >= 0)
|
|
||||||
close (ldsocfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If installing bi-arch glibc, rpm sometimes doesn't unpack all files
|
|
||||||
before running one of the lib's %post scriptlet. /sbin/ldconfig will
|
|
||||||
then be run by the other arch's %post. */
|
|
||||||
if (! access ("/sbin/ldconfig", X_OK))
|
|
||||||
verbose_exec (110, "/sbin/ldconfig", "/sbin/ldconfig");
|
|
||||||
|
|
||||||
if (! utimes (GCONV_MODULES_DIR "/gconv-modules.cache", NULL))
|
|
||||||
{
|
|
||||||
char *iconv_cache = GCONV_MODULES_DIR"/gconv-modules.cache";
|
|
||||||
char *iconv_dir = GCONV_MODULES_DIR;
|
|
||||||
verbose_exec (113, ICONVCONFIG, "/usr/sbin/iconvconfig",
|
|
||||||
"-o", iconv_cache,
|
|
||||||
"--nostdlib", iconv_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
_exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
vexec (int failcode, char *const path[])
|
|
||||||
{
|
|
||||||
pid_t pid;
|
|
||||||
int status, save_errno;
|
|
||||||
int devnull = 0;
|
|
||||||
|
|
||||||
if (failcode < 0)
|
|
||||||
{
|
|
||||||
devnull = 1;
|
|
||||||
failcode = -failcode;
|
|
||||||
}
|
|
||||||
pid = vfork ();
|
|
||||||
if (pid == 0)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
if (devnull && (fd = open ("/dev/null", O_WRONLY)) >= 0)
|
|
||||||
{
|
|
||||||
dup2 (fd, 1);
|
|
||||||
dup2 (fd, 2);
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
execv (path[0], path + 1);
|
|
||||||
save_errno = errno;
|
|
||||||
message (path);
|
|
||||||
says (" exec failed with errno ");
|
|
||||||
sayn (save_errno);
|
|
||||||
says ("\n");
|
|
||||||
_exit (failcode);
|
|
||||||
}
|
|
||||||
else if (pid < 0)
|
|
||||||
{
|
|
||||||
save_errno = errno;
|
|
||||||
message (path);
|
|
||||||
says (" fork failed with errno ");
|
|
||||||
sayn (save_errno);
|
|
||||||
says ("\n");
|
|
||||||
_exit (failcode + 1);
|
|
||||||
}
|
|
||||||
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
|
||||||
{
|
|
||||||
message (path);
|
|
||||||
says (" child terminated abnormally\n");
|
|
||||||
_exit (failcode + 2);
|
|
||||||
}
|
|
||||||
if (WEXITSTATUS (status))
|
|
||||||
{
|
|
||||||
message (path);
|
|
||||||
says (" child exited with exit code ");
|
|
||||||
sayn (WEXITSTATUS (status));
|
|
||||||
says ("\n");
|
|
||||||
_exit (WEXITSTATUS (status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
says (const char *str)
|
|
||||||
{
|
|
||||||
write (1, str, strlen (str));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sayn (long num)
|
|
||||||
{
|
|
||||||
char string[sizeof (long) * 3 + 1];
|
|
||||||
char *p = string + sizeof (string) - 1;
|
|
||||||
|
|
||||||
*p = '\0';
|
|
||||||
if (num == 0)
|
|
||||||
*--p = '0';
|
|
||||||
else
|
|
||||||
while (num)
|
|
||||||
{
|
|
||||||
*--p = '0' + num % 10;
|
|
||||||
num = num / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
says (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
message (char *const path[])
|
|
||||||
{
|
|
||||||
says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
|
|
||||||
says (path[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
check_elf (const char *name)
|
|
||||||
{
|
|
||||||
/* Play safe, if we can't open or read, assume it might be
|
|
||||||
ELF for the current arch. */
|
|
||||||
int ret = 1;
|
|
||||||
int fd = open (name, O_RDONLY);
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
Elf32_Ehdr ehdr;
|
|
||||||
if (read (fd, &ehdr, offsetof (Elf32_Ehdr, e_version))
|
|
||||||
== offsetof (Elf32_Ehdr, e_version))
|
|
||||||
{
|
|
||||||
ret = 0;
|
|
||||||
if (ehdr.e_ident[EI_CLASS]
|
|
||||||
== (sizeof (long) == 8 ? ELFCLASS64 : ELFCLASS32))
|
|
||||||
{
|
|
||||||
#if defined __i386__
|
|
||||||
ret = ehdr.e_machine == EM_386;
|
|
||||||
#elif defined __x86_64__
|
|
||||||
ret = ehdr.e_machine == EM_X86_64;
|
|
||||||
#elif defined __powerpc64__
|
|
||||||
ret = ehdr.e_machine == EM_PPC64;
|
|
||||||
#elif defined __powerpc__
|
|
||||||
ret = ehdr.e_machine == EM_PPC;
|
|
||||||
#elif defined __s390__ || defined __s390x__
|
|
||||||
ret = ehdr.e_machine == EM_S390;
|
|
||||||
#elif defined __x86_64__
|
|
||||||
ret = ehdr.e_machine == EM_X86_64;
|
|
||||||
#elif defined __sparc__
|
|
||||||
if (sizeof (long) == 8)
|
|
||||||
ret = ehdr.e_machine == EM_SPARCV9;
|
|
||||||
else
|
|
||||||
ret = (ehdr.e_machine == EM_SPARC
|
|
||||||
|| ehdr.e_machine == EM_SPARC32PLUS);
|
|
||||||
#else
|
|
||||||
ret = 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
#
|
|
||||||
# /etc/nsswitch.conf
|
|
||||||
#
|
|
||||||
# An example Name Service Switch config file. This file should be
|
|
||||||
# sorted with the most-used services at the beginning.
|
|
||||||
#
|
|
||||||
# The entry '[NOTFOUND=return]' means that the search for an
|
|
||||||
# entry should stop if the search in the previous entry turned
|
|
||||||
# up nothing. Note that if the search failed due to some other reason
|
|
||||||
# (like no NIS server responding) then the search continues with the
|
|
||||||
# next entry.
|
|
||||||
#
|
|
||||||
# Valid entries include:
|
|
||||||
#
|
|
||||||
# nisplus Use NIS+ (NIS version 3)
|
|
||||||
# nis Use NIS (NIS version 2), also called YP
|
|
||||||
# dns Use DNS (Domain Name Service)
|
|
||||||
# files Use the local files in /etc
|
|
||||||
# db Use the pre-processed /var/db files
|
|
||||||
# compat Use /etc files plus *_compat pseudo-databases
|
|
||||||
# hesiod Use Hesiod (DNS) for user lookups
|
|
||||||
# sss Use sssd (System Security Services Daemon)
|
|
||||||
# [NOTFOUND=return] Stop searching if not found so far
|
|
||||||
#
|
|
||||||
# 'sssd' performs its own 'files'-based caching, so it should
|
|
||||||
# generally come before 'files'.
|
|
||||||
|
|
||||||
# To use 'db', install the nss_db package, and put the 'db' in front
|
|
||||||
# of 'files' for entries you want to be looked up first in the
|
|
||||||
# databases, like this:
|
|
||||||
#
|
|
||||||
# passwd: db files
|
|
||||||
# shadow: db files
|
|
||||||
# group: db files
|
|
||||||
|
|
||||||
passwd: sss files
|
|
||||||
shadow: files sss
|
|
||||||
group: sss files
|
|
||||||
|
|
||||||
hosts: files dns myhostname
|
|
||||||
|
|
||||||
bootparams: files
|
|
||||||
|
|
||||||
ethers: files
|
|
||||||
netmasks: files
|
|
||||||
networks: files
|
|
||||||
protocols: files
|
|
||||||
rpc: files
|
|
||||||
services: files sss
|
|
||||||
|
|
||||||
netgroup: sss
|
|
||||||
|
|
||||||
publickey: files
|
|
||||||
|
|
||||||
automount: files sss
|
|
||||||
aliases: files
|
|
2
sources
2
sources
|
@ -1 +1 @@
|
||||||
SHA512 (glibc-2.28.tar.xz) = 521f820953ff07c69ece4c2186f59fc061a7f9747932cd70ef2995c2b2deee76eeb6de700d85071cdca5949179aa8ccee75eda7feca1394121ec7b821ad0a3f3
|
SHA512 (glibc-2.30.9000-100-g1a6566094d.tar.xz) = e6054a8f1367fde262f023c76f7eaf5ce588613c4894b8d577c7e1c3159a2dfcefb7c60e301340b823cd8e6d2f8d264d7da83e61034b9180836d392d5db4c5ba
|
||||||
|
|
Loading…
Reference in New Issue