This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
a localedef bug
- To: libc-alpha at sources dot redhat dot com
- Subject: a localedef bug
- From: Bruno Haible <haible at ilog dot fr>
- Date: Tue, 5 Jun 2001 15:27:38 +0200 (CEST)
Hi,
localedef opens its output files via creat(), which temporarily truncates the
file to length 0. But at the same time other processes have this file mmapped.
When they access the file's contents they get a bus error. I got such "Bus
error (core dumped)" from gdb and bash. The bash backtrace shows
#0 0x400d1cf4 in __strtol_internal (nptr=0x80c1f90 "500", endptr=0xbfffe640,
base=10, group=0) at ../sysdeps/generic/strtol.c:306
306 while (ISSPACE (*s))
This patch fixes the bug by calling unlink() before creat().
2001-06-04 Bruno Haible <haible@clisp.cons.org>
* locale/programs/locfile.c (write_locale_data): Before creat(),
unlink the file, to avoid crashing the processes that mmap it. Change
a double slash to a single slash. Free fname in case of error return.
--- glibc-20010430/locale/programs/locfile.c.bak Mon Jun 4 21:09:42 2001
+++ glibc-20010430/locale/programs/locfile.c Mon Jun 4 22:22:30 2001
@@ -338,30 +338,33 @@
data. This means we need to have a directory LC_MESSAGES in
which we place the file under the name SYS_LC_MESSAGES. */
sprintf (fname, "%s%s", output_path, category);
+ fd = -2;
if (strcmp (category, "LC_MESSAGES") == 0)
{
struct stat st;
if (stat (fname, &st) < 0)
{
- if (mkdir (fname, 0777) < 0)
- fd = creat (fname, 0666);
- else
+ if (mkdir (fname, 0777) >= 0)
{
fd = -1;
errno = EISDIR;
}
}
- else if (S_ISREG (st.st_mode))
- fd = creat (fname, 0666);
- else
+ else if (!S_ISREG (st.st_mode))
{
fd = -1;
errno = EISDIR;
}
}
- else
- fd = creat (fname, 0666);
+
+ /* Create the locale file with nlinks == 1; this avoids crashing processes
+ which currently use the locale. */
+ if (fd == -2)
+ {
+ unlink (fname);
+ fd = creat (fname, 0666);
+ }
if (fd == -1)
{
@@ -369,7 +372,8 @@
if (errno == EISDIR)
{
- sprintf (fname, "%1$s/%2$s/SYS_%2$s", output_path, category);
+ sprintf (fname, "%1$s%2$s/SYS_%2$s", output_path, category);
+ unlink (fname);
fd = creat (fname, 0666);
if (fd == -1)
save_err = errno;
@@ -381,6 +385,7 @@
error (0, save_err, _("\
cannot open output file `%s' for category `%s'"),
fname, category);
+ free (fname);
return;
}
}