aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1996-09-28 03:24:10 +0000
committerUlrich Drepper <drepper@redhat.com>1996-09-28 03:24:10 +0000
commitd68171edce96cb59b5cb869f6a82afcc50db00be (patch)
treef149db9027e600965c482e090c29bd058eea3454
parentc40298232a7ed3fb1b64eb4ffe352829deb79694 (diff)
downloadglibc-d68171edce96cb59b5cb869f6a82afcc50db00be.zip
glibc-d68171edce96cb59b5cb869f6a82afcc50db00be.tar.gz
glibc-d68171edce96cb59b5cb869f6a82afcc50db00be.tar.bz2
update from main archive 960927cvs/libc-961001cvs/libc-960929cvs/libc-960928
Sat Sep 28 03:02:49 1996 Ulrich Drepper <drepper@cygnus.com> * dirent/Makefile (routines): Add readdir_r. * dirent/readdir_r.c: New file. Wrapper around readdir.c. * dirent/dirent.h: Add prototype for readdir_r. * misc/hsearch_r.c (ENTRY): Make field `used' of type `unsigned int' to prevent warnings. * sysdeps/unix/sysv/linux/getsysstats.c (get_proc_path): Initialize `result'. Sat Sep 28 01:16:42 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/generic/strsep.c: Rename to __strsep and make strsep weak alias. * string/string.h: Add prototype for __strsep. * misc/mntent_r.c: Use __strsep instead of strsep to keep namespace clean. * sysdeps/stub/nanosleep.c: Rename to __libc_nanosleep and make __nanosleep and nanosleep weak aliases. * sysdeps/unix/sysv/linux/syscalls.list: Add __nanosleep as weak alias. * sysdeps/unix/sysv/linux/sleep.c: Call __nanosleep instead of nanosleep to keep namespace clean. * sysdeps/posix/ttyname.c (ttyname): Add cast to prevent warning. * sysdeps/posix/ttyname_r.c (ttyname_r): Likewise. * sysdeps/posix/getcwd.c (__getcwd): Likewise. * sysdeps/unix/nlist.c: Use ISO C definition since we don't always have prototype. * login/Makefile (headers): Add pty.h. * login/pty.h: New file. * sysdeps/generic/pty.h: Include <pty.h>. * login/pututline_r.c: Add cast to prevent warning. * gmon/gmon.c: Add prototype for __profile_frequency. (monstartup): Add cast to prevent warning. * sysdeps/generic/prof-freq.c: Change to use ISO C style definition. * locale/programs/ld-time.c (time_output): Write `era' information in correct order. Sat Sep 28 00:11:08 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/syscalls.list: Add weak alias `adjtimex'. Set caller for mlock, mlockall, mremap, munlock, and munlockall to EXTRA. Reported by Matthias Urlichs <smurf@smurf.noris.de>. 1996-09-27 Paul Eggert <eggert@twinsun.com> * strftime.c (strftime): Output incomplete formats like %E at end of string. 1996-09-27 Paul Eggert <eggert@twinsun.com> * strftime.c (strftime): Add support for %EC and %Ey. Fix support for %EY. This uses the new _nl_get_era_entry function. Fri Sep 27 14:12:27 1996 Ulrich Drepper <drepper@cygnus.com> Security related patch by Elliot Lee <sopwith@redhat.com> and David Holland <dholland@eecs.harvard.edu>. * inet/rexec.c (rexec): Increase size of `num' array from 8 to 32. * inet/ruserpass.c (ruserpass): Don't allow $HOME envvar to not exist. * sysdeps/generic/getenv.c (__secure_getenv): New function. Return NULL when programs runs with SUID or SGID enabled. * sysdeps/stub/getenv.c: Make __secure_getenv an alias of getenv. * stdlib/stdlib.h: Add prototype for __secure_getenv. * locale/setlocale.c: Use __secure_getenv. * resolv/res_init.c: Likewise. * resolv/res_query.c: Likewise. * inet/ruserpass.c: Likewise. * sysdeps/posix/tempname.c: Likewise. * malloc/mtrace.c: Likewise. * catgets/catgets.c: Likewise. Make temporary file handling functions reentrant. * stdio-common/tmpnam.c: Rewrite to have own buffer to write result to. The called __stdio_gen_tempname function must be thread safe. * stdio-common/tmpnam_r.c: New file. * stdio/stdio.h: Add prototype for `tmpnam_r'. Change prototype for __stdio_gen_tempname. * stdio/libio.h: Likewise. * sysdeps/posix/tempname.c: Add new parameters and use them instead of static buffer. Don't reset `indeces' when PID changed between calls. Don't fail for long running programs when index counter once reached the limit. * sysdeps/stub/tempname.c: Likewise. * stdio-common/tempnam.c: Provide local buffer as extra argument to __stdio_gen_tempname. This makes this function reentrant. * stdio-common/tmpfile.c: Likewise. * stdio-common/temptest.c: Provide extra argument to __stdio_gen_tempname. * manual/filesys.texi: Describe tmpnam_r and add comments about reentrancy of the functions. * inet/rcmd.c: Fixed address length handling. * sysdeps/posix/mk-stdiolim.c: Count final \0 byte in L_tmpnam value. * time/strftime.c: Remove unused variables alt_digits and end_alt_digits. * sysdeps/unix/sysv/linux/sys/sysinfo.h: Correct prototype names for get_nprocs and get_nprocs_conf. * sysdeps/generic/sys/sysinfo.h: Likewise. * stdlib/test-canon.c: Finally do the right fix. * misc/Makefile: Only compile force-wrapper when compiling reentrant libc.
-rw-r--r--ChangeLog128
-rw-r--r--catgets/catgets.c2
-rw-r--r--dirent/Makefile2
-rw-r--r--dirent/dirent.h7
-rw-r--r--dirent/readdir_r.c37
-rw-r--r--gmon/gmon.c4
-rw-r--r--inet/rcmd.c9
-rw-r--r--inet/rexec.c4
-rw-r--r--inet/ruserpass.c11
-rw-r--r--libio/stdio.h6
-rw-r--r--locale/programs/ld-time.c6
-rw-r--r--locale/setlocale.c15
-rw-r--r--login/Makefile2
-rw-r--r--login/pty.h43
-rw-r--r--login/pututline_r.c2
-rw-r--r--manual/filesys.texi77
-rw-r--r--misc/Makefile7
-rw-r--r--misc/hsearch_r.c2
-rw-r--r--misc/mntent_r.c8
-rw-r--r--nss/nss_dns/dns-host.c6
-rw-r--r--resolv/res_debug.c2
-rw-r--r--resolv/res_init.c4
-rw-r--r--resolv/res_query.c2
-rw-r--r--stdio-common/tempnam.c14
-rw-r--r--stdio-common/temptest.c3
-rw-r--r--stdio-common/tmpfile.c8
-rw-r--r--stdio-common/tmpnam.c43
-rw-r--r--stdio-common/tmpnam_r.c37
-rw-r--r--stdio/stdio.h9
-rw-r--r--stdlib/stdlib.h4
-rw-r--r--stdlib/test-canon.c20
-rw-r--r--string/string.h1
-rw-r--r--sysdeps/generic/getenv.c23
-rw-r--r--sysdeps/generic/prof-freq.c2
-rw-r--r--sysdeps/generic/pty.c3
-rw-r--r--sysdeps/generic/strsep.c3
-rw-r--r--sysdeps/generic/sys/sysinfo.h8
-rw-r--r--sysdeps/posix/getcwd.c4
-rw-r--r--sysdeps/posix/mk-stdiolim.c8
-rw-r--r--sysdeps/posix/tempname.c58
-rw-r--r--sysdeps/posix/ttyname.c2
-rw-r--r--sysdeps/posix/ttyname_r.c2
-rw-r--r--sysdeps/stub/getenv.c1
-rw-r--r--sysdeps/stub/nanosleep.c6
-rw-r--r--sysdeps/stub/tempname.c4
-rw-r--r--sysdeps/unix/nlist.c4
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c9
-rw-r--r--sysdeps/unix/sysv/linux/sleep.c2
-rw-r--r--sysdeps/unix/sysv/linux/sys/sysinfo.h8
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list14
-rw-r--r--time/strftime.c56
-rw-r--r--time/time.h2
52 files changed, 547 insertions, 197 deletions
diff --git a/ChangeLog b/ChangeLog
index d28ec2d..decbf31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,126 @@
-Mon Sep 23 15:31:04 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+Sat Sep 28 03:02:49 1996 Ulrich Drepper <drepper@cygnus.com>
- * hurd/Makefile ($(includedir)/rpc/netdb.h): There is no make
- variable `top_srcdir' in libc; use $(..) instead.
+ * dirent/Makefile (routines): Add readdir_r.
+ * dirent/readdir_r.c: New file. Wrapper around readdir.c.
+ * dirent/dirent.h: Add prototype for readdir_r.
- * sysdeps/mach/hurd/Makefile (rtld-installed-name): Delete special
- definition. It was a *Mistake*. (With a capital M.)
+ * misc/hsearch_r.c (ENTRY): Make field `used' of type `unsigned int'
+ to prevent warnings.
- * sysdeps/mach/getsysstats.c (__get_nprocs): Renamed from
- __get_nproc.
- (__get_nprocs_conf): Renamed from __get_nproc_conf.
+ * sysdeps/unix/sysv/linux/getsysstats.c (get_proc_path):
+ Initialize `result'.
+
+Sat Sep 28 01:16:42 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/generic/strsep.c: Rename to __strsep and make strsep
+ weak alias.
+ * string/string.h: Add prototype for __strsep.
+ * misc/mntent_r.c: Use __strsep instead of strsep to keep
+ namespace clean.
+
+ * sysdeps/stub/nanosleep.c: Rename to __libc_nanosleep and make
+ __nanosleep and nanosleep weak aliases.
+ * sysdeps/unix/sysv/linux/syscalls.list: Add __nanosleep as weak
+ alias.
+ * sysdeps/unix/sysv/linux/sleep.c: Call __nanosleep instead of
+ nanosleep to keep namespace clean.
+
+ * sysdeps/posix/ttyname.c (ttyname): Add cast to prevent warning.
+ * sysdeps/posix/ttyname_r.c (ttyname_r): Likewise.
+ * sysdeps/posix/getcwd.c (__getcwd): Likewise.
+
+ * sysdeps/unix/nlist.c: Use ISO C definition since we don't always
+ have prototype.
+
+ * login/Makefile (headers): Add pty.h.
+ * login/pty.h: New file.
+ * sysdeps/generic/pty.h: Include <pty.h>.
+ * login/pututline_r.c: Add cast to prevent warning.
+
+ * gmon/gmon.c: Add prototype for __profile_frequency.
+ (monstartup): Add cast to prevent warning.
+ * sysdeps/generic/prof-freq.c: Change to use ISO C style definition.
+
+ * locale/programs/ld-time.c (time_output): Write `era' information
+ in correct order.
+
+Sat Sep 28 00:11:08 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/unix/sysv/linux/syscalls.list: Add weak alias
+ `adjtimex'.
+ Set caller for mlock, mlockall, mremap, munlock, and munlockall
+ to EXTRA.
+ Reported by Matthias Urlichs <smurf@smurf.noris.de>.
+
+1996-09-27 Paul Eggert <eggert@twinsun.com>
+
+ * strftime.c (strftime): Output incomplete formats like %E
+ at end of string.
+
+1996-09-27 Paul Eggert <eggert@twinsun.com>
+
+ * strftime.c (strftime): Add support for %EC and %Ey.
+ Fix support for %EY. This uses the new _nl_get_era_entry function.
+
+Fri Sep 27 14:12:27 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ Security related patch by Elliot Lee <sopwith@redhat.com> and
+ David Holland <dholland@eecs.harvard.edu>.
+
+ * inet/rexec.c (rexec): Increase size of `num' array from 8 to 32.
+ * inet/ruserpass.c (ruserpass): Don't allow $HOME envvar to not exist.
+
+ * sysdeps/generic/getenv.c (__secure_getenv): New function. Return
+ NULL when programs runs with SUID or SGID enabled.
+ * sysdeps/stub/getenv.c: Make __secure_getenv an alias of getenv.
+ * stdlib/stdlib.h: Add prototype for __secure_getenv.
+
+ * locale/setlocale.c: Use __secure_getenv.
+ * resolv/res_init.c: Likewise.
+ * resolv/res_query.c: Likewise.
+ * inet/ruserpass.c: Likewise.
+ * sysdeps/posix/tempname.c: Likewise.
+ * malloc/mtrace.c: Likewise.
+ * catgets/catgets.c: Likewise.
+
+ Make temporary file handling functions reentrant.
+
+ * stdio-common/tmpnam.c: Rewrite to have own buffer to write
+ result to. The called __stdio_gen_tempname function must be
+ thread safe.
+ * stdio-common/tmpnam_r.c: New file.
+ * stdio/stdio.h: Add prototype for `tmpnam_r'.
+ Change prototype for __stdio_gen_tempname.
+ * stdio/libio.h: Likewise.
+ * sysdeps/posix/tempname.c: Add new parameters and use them instead
+ of static buffer.
+ Don't reset `indeces' when PID changed between calls.
+ Don't fail for long running programs when index counter once
+ reached the limit.
+ * sysdeps/stub/tempname.c: Likewise.
+ * stdio-common/tempnam.c: Provide local buffer as extra argument
+ to __stdio_gen_tempname. This makes this function reentrant.
+ * stdio-common/tmpfile.c: Likewise.
+ * stdio-common/temptest.c: Provide extra argument to
+ __stdio_gen_tempname.
+ * manual/filesys.texi: Describe tmpnam_r and add comments about
+ reentrancy of the functions.
+
+ * inet/rcmd.c: Fixed address length handling.
+
+ * sysdeps/posix/mk-stdiolim.c: Count final \0 byte in L_tmpnam value.
+
+ * time/strftime.c: Remove unused variables alt_digits and
+ end_alt_digits.
+
+ * sysdeps/unix/sysv/linux/sys/sysinfo.h: Correct prototype names
+ for get_nprocs and get_nprocs_conf.
+ * sysdeps/generic/sys/sysinfo.h: Likewise.
+
+ * stdlib/test-canon.c: Finally do the right fix.
+
+ * misc/Makefile: Only compile force-wrapper when compiling
+ reentrant libc.
Fri Sep 27 03:49:56 1996 Ulrich Drepper <drepper@cygnus.com>
diff --git a/catgets/catgets.c b/catgets/catgets.c
index 0abc182..7c45b45 100644
--- a/catgets/catgets.c
+++ b/catgets/catgets.c
@@ -79,7 +79,7 @@ catopen (const char *cat_name, int flag)
return (nl_catd) -1;
}
- if (getenv ("NLSPATH") != NULL)
+ if (__secure_getenv ("NLSPATH") != NULL)
result->nlspath = __strdup (getenv ("NLSPATH"));
else
result->nlspath = __strdup (NLSPATH);
diff --git a/dirent/Makefile b/dirent/Makefile
index b6a4219..8d706df 100644
--- a/dirent/Makefile
+++ b/dirent/Makefile
@@ -22,7 +22,7 @@
subdir := dirent
headers := dirent.h direntry.h
-routines := opendir closedir readdir rewinddir \
+routines := opendir closedir readdir readdir_r rewinddir \
seekdir telldir scandir alphasort \
getdents dirfd
distribute := dirstream.h
diff --git a/dirent/dirent.h b/dirent/dirent.h
index 02a5e6a..06e92cb 100644
--- a/dirent/dirent.h
+++ b/dirent/dirent.h
@@ -116,6 +116,13 @@ extern int closedir __P ((DIR * __dirp));
extern struct dirent *__readdir __P ((DIR * __dirp));
extern struct dirent *readdir __P ((DIR * __dirp));
+#ifdef __USE_REENTRANT
+/* Reentrant versio of `readdir'. Return in RESULT a pointer to the
+ next entry. */
+extern int readdir_r __P ((DIR *__dirp, struct dirent *entry,
+ struct dirent **result));
+#endif
+
/* Rewind DIRP to the beginning of the directory. */
extern void rewinddir __P ((DIR * __dirp));
diff --git a/dirent/readdir_r.c b/dirent/readdir_r.c
new file mode 100644
index 0000000..b997966
--- /dev/null
+++ b/dirent/readdir_r.c
@@ -0,0 +1,37 @@
+/* readdir_r - Reentrant version of readdir.
+Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <dirent.h>
+
+/* Some systems have reentrancy problems with their `readdir'
+ implementation so they have an additional `readdir_r' version. The
+ GNU version does not have these problems but for compatibility
+ reasons we provide this function. It is simply a wrapper around
+ the normal function.
+
+ The actual definition of this functions varies very strong from
+ system to system. We chose to follow the POSIX version. */
+int
+readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+ *result = readdir (dirp);
+
+ return *result != NULL ? 0 : -1;
+}
diff --git a/gmon/gmon.c b/gmon/gmon.c
index a450d11..ecf7518 100644
--- a/gmon/gmon.c
+++ b/gmon/gmon.c
@@ -45,6 +45,8 @@
#include <string.h>
#include <unistd.h>
+extern int __profile_frequency (void);
+
struct __bb *__bb_head; /* Head of basic-block list or NULL. */
struct gmonparam _gmonparam = { GMON_PROF_OFF };
@@ -128,7 +130,7 @@ DEFUN(monstartup, (lowpc, highpc), u_long lowpc AND u_long highpc)
p->tos[0].link = 0;
o = p->highpc - p->lowpc;
- if (p->kcountsize < o)
+ if (p->kcountsize < (u_long) o)
{
#ifndef hp300
s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
diff --git a/inet/rcmd.c b/inet/rcmd.c
index 1c63e95..a9756d1 100644
--- a/inet/rcmd.c
+++ b/inet/rcmd.c
@@ -52,6 +52,9 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
#include <ctype.h>
#include <string.h>
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+
+
int __ivaliduser __P((FILE *, u_int32_t, const char *, const char *));
static int __icheckhost __P((u_int32_t, char *));
@@ -92,7 +95,8 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
}
fcntl(s, F_SETOWN, pid);
sin.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
+ bcopy(hp->h_addr_list[0], &sin.sin_addr,
+ MIN (sizeof (sin.sin_addr), hp->h_length));
sin.sin_port = rport;
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
break;
@@ -114,7 +118,8 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
__set_errno (oerrno);
perror(0);
hp->h_addr_list++;
- bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
+ bcopy(hp->h_addr_list[0], &sin.sin_addr,
+ MIN (sizeof (sin.sin_addr), hp->h_length));
(void)fprintf(stderr, _("Trying %s...\n"),
inet_ntoa(sin.sin_addr));
continue;
diff --git a/inet/rexec.c b/inet/rexec.c
index 297e444..7533410 100644
--- a/inet/rexec.c
+++ b/inet/rexec.c
@@ -91,9 +91,9 @@ retry:
(void) write(s, "", 1);
port = 0;
} else {
- char num[8];
+ char num[32];
int s2, sin2len;
-
+
s2 = socket(AF_INET, SOCK_STREAM, 0);
if (s2 < 0) {
(void) close(s);
diff --git a/inet/ruserpass.c b/inet/ruserpass.c
index cff9493..a0a4b97 100644
--- a/inet/ruserpass.c
+++ b/inet/ruserpass.c
@@ -87,9 +87,14 @@ ruserpass(host, aname, apass)
int t, i, c, usedefault = 0;
struct stat stb;
- hdir = getenv("HOME");
- if (hdir == NULL)
- hdir = ".";
+ hdir = __secure_getenv("HOME");
+ if (hdir == NULL) {
+ /* If we can't get HOME, fail instead of trying ".",
+ which is no improvement. This really should call
+ getpwuid(getuid()). */
+ /*hdir = ".";*/
+ return -1;
+ }
buf = alloca (strlen (hdir) + 8);
diff --git a/libio/stdio.h b/libio/stdio.h
index 3b399e5..c71cf4d 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -135,10 +135,14 @@ extern int sprintf __P ((char*, __const char* format, ...));
extern int sscanf __P ((__const char* string, __const char* format, ...));
extern FILE* tmpfile __P ((void));
extern char* tmpnam __P ((char*));
+#ifdef __USE_REENTRANT
+extern char* tmpnam_r __P ((char*));
+#endif
#ifdef __USE_SVID
extern char *tempnam __P ((__const char *__dir, __const char *__pfx));
#endif
-extern char *__stdio_gen_tempname __P ((__const char *dir, __const char *pfx,
+extern char *__stdio_gen_tempname __P ((char *__buf, size_t bufsize,
+ __const char *dir, __const char *pfx,
int dir_search, size_t *lenptr,
FILE **streamptr));
extern int ungetc __P ((int c, FILE* fp));
diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
index 1b118ae..6f961b6 100644
--- a/locale/programs/ld-time.c
+++ b/locale/programs/ld-time.c
@@ -548,11 +548,11 @@ time_output (struct localedef_t *locale, const char *output_path)
++last_idx;
#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define ERA_B1 time->era_entries
-# define ERA_B2 time->era_entries_ob
-#else
# define ERA_B1 time->era_entries_ob
# define ERA_B2 time->era_entries
+#else
+# define ERA_B1 time->era_entries
+# define ERA_B2 time->era_entries_ob
#endif
idx[1 + last_idx] = idx[last_idx];
for (num = 0; num < time->cur_num_era; ++num)
diff --git a/locale/setlocale.c b/locale/setlocale.c
index 76320f8..ceec1a6 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -227,6 +227,7 @@ setlocale (int category, const char *locale)
{
char *locale_path;
size_t locale_path_len;
+ const char *locpath_var;
char *composite;
/* Sanity check for CATEGORY argument. */
@@ -248,15 +249,11 @@ setlocale (int category, const char *locale)
locale_path = NULL;
locale_path_len = 0;
- if (!__libc_enable_secure)
- {
- char *locpath_var = getenv ("LOCPATH");
-
- if (locpath_var != NULL && locpath_var[0] != '\0')
- if (__argz_create_sep (locpath_var, ':',
- &locale_path, &locale_path_len) != 0)
- return NULL;
- }
+ locpath_var = __secure_getenv ("LOCPATH");
+ if (locpath_var != NULL && locpath_var[0] != '\0')
+ if (__argz_create_sep (locpath_var, ':',
+ &locale_path, &locale_path_len) != 0)
+ return NULL;
if (__argz_append (&locale_path, &locale_path_len,
LOCALE_PATH, sizeof (LOCALE_PATH)) != 0)
diff --git a/login/Makefile b/login/Makefile
index 9968743..56a6aeb 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -22,7 +22,7 @@
subdir := login
-headers := utmp.h utmpbits.h lastlog.h
+headers := utmp.h utmpbits.h lastlog.h pty.h
routines := setutent endutent getutent getutid getutline pututline \
setutent_r endutent_r getutent_r getutid_r getutline_r \
diff --git a/login/pty.h b/login/pty.h
new file mode 100644
index 0000000..da78742
--- /dev/null
+++ b/login/pty.h
@@ -0,0 +1,43 @@
+/* pty.h - Functions for pseudo TTY handlung.
+Copyright (C) 1996 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef _PTY_H
+
+#define _PTY_H 1
+#include <features.h>
+
+#include <termios.h>
+
+
+__BEGIN_DECLS
+
+/* Create pseudo tty master slave pair with NAME and set terminal
+ attributes according to TERMP and WINP and return handles for both
+ ends in AMASTER and ASLAVE. */
+extern int openpty __P ((int *__amaster, int *__aslave, char *__name,
+ struct termios *__termp, struct winsize *__winp));
+
+/* Create child process and establish the slave pseudo terminal as the
+ child's controlling terminal. */
+extern int forkpty __P ((int *__amaster, char *__name,
+ struct termios *__termp, struct winsize *__winp));
+
+__END_DECLS
+
+#endif /* pty.h */
diff --git a/login/pututline_r.c b/login/pututline_r.c
index 42ea3cd..33ba96f 100644
--- a/login/pututline_r.c
+++ b/login/pututline_r.c
@@ -96,7 +96,7 @@ __pututline_r (const struct utmp *id, struct utmp_data *utmp_data)
if (result >= 0)
/* Position file correctly. */
if (utmp_data->loc_utmp < (off_t) sizeof (struct utmp)
- || utmp_data->loc_utmp - sizeof (struct utmp) > st.st_size)
+ || (off_t) (utmp_data->loc_utmp - sizeof (struct utmp)) > st.st_size)
/* Not located at any valid entry. Add at the end. */
{
result = lseek (utmp_data->ut_fd, 0L, SEEK_END);
diff --git a/manual/filesys.texi b/manual/filesys.texi
index d2afe86..e269663 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -261,7 +261,7 @@ are declared in the header file @file{dirent.h}.
@comment dirent.h
@comment POSIX.1
@deftp {Data Type} DIR
-The @code{DIR} data type represents a directory stream.
+The @code{DIR} data type represents a directory stream.
@end deftp
You shouldn't ever allocate objects of the @code{struct dirent} or
@@ -333,7 +333,7 @@ The @var{dirstream} argument is not valid.
@comment POSIX.1
@deftypefun int closedir (DIR *@var{dirstream})
This function closes the directory stream @var{dirstream}. It returns
-@code{0} on success and @code{-1} on failure.
+@code{0} on success and @code{-1} on failure.
The following @code{errno} error conditions are defined for this
function:
@@ -443,7 +443,7 @@ following @code{errno} error conditions are defined for this function:
@item EACCES
You are not allowed to write the directory in which the new link is to
be written.
-@ignore
+@ignore
Some implementations also require that the existing file be accessible
by the caller, and use this error to report failure for that reason.
@end ignore
@@ -627,7 +627,7 @@ The function @code{unlink} is declared in the header file @file{unistd.h}.
This function returns @code{0} on successful completion, and @code{-1}
on error. In addition to the usual file name errors
-(@pxref{File Name Errors}), the following @code{errno} error conditions are
+(@pxref{File Name Errors}), the following @code{errno} error conditions are
defined for this function:
@table @code
@@ -672,7 +672,7 @@ are two additional @code{errno} error conditions defined for
@table @code
@item ENOTEMPTY
@itemx EEXIST
-The directory to be deleted is not empty.
+The directory to be deleted is not empty.
@end table
These two error codes are synonymous; some systems use one, and some use
@@ -851,20 +851,20 @@ This section contains information about how you can inquire about and
modify these attributes of files.
@menu
-* Attribute Meanings:: The names of the file attributes,
+* Attribute Meanings:: The names of the file attributes,
and what their values mean.
* Reading Attributes:: How to read the attributes of a file.
* Testing File Type:: Distinguishing ordinary files,
- directories, links...
+ directories, links...
* File Owner:: How ownership for new files is determined,
and how to change it.
* Permission Bits:: How information about a file's access
- mode is stored.
+ mode is stored.
* Access Permission:: How the system decides who can access a file.
* Setting Permissions:: How permissions for new files are assigned,
and how to change them.
* Testing File Access:: How to find out if your process can
- access a file.
+ access a file.
* File Times:: About the time attributes of a file.
@end menu
@@ -1079,7 +1079,7 @@ a socket, and so on. For information about the access permission,
@ref{Permission Bits}.
There are two predefined ways you can access the file type portion of
-the file mode. First of all, for each type of file, there is a
+the file mode. First of all, for each type of file, there is a
@dfn{predicate macro} which examines a file mode value and returns
true or false---is the file of that type, or not. Secondly, you can
mask out the rest of the file mode to get just a file type code.
@@ -1260,7 +1260,7 @@ bits may not be appropriate for the new owner.) The other file
permission bits are not changed.
The return value is @code{0} on success and @code{-1} on failure.
-In addition to the usual file name errors (@pxref{File Name Errors}),
+In addition to the usual file name errors (@pxref{File Name Errors}),
the following @code{errno} error conditions are defined for this function:
@table @code
@@ -1421,7 +1421,7 @@ This is equivalent to @samp{(S_IROTH | S_IWOTH | S_IXOTH)}.
@comment POSIX
@item S_ISUID
@vindex S_ISUID
-This is the set-user-ID on execute bit, usually 04000.
+This is the set-user-ID on execute bit, usually 04000.
@xref{How Change Persona}.
@comment sys/stat.h
@@ -1462,7 +1462,7 @@ arose since the last run.
On some modern systems where the sticky bit has no useful meaning for an
executable file, you cannot set the bit at all for a non-directory.
-If you try, @code{chmod} fails with @code{EFTYPE};
+If you try, @code{chmod} fails with @code{EFTYPE};
@pxref{Setting Permissions}.
Some systems (particularly SunOS) have yet another use for the sticky
@@ -1527,7 +1527,7 @@ The bits that are set in the file creation mask identify permissions
that are always to be disabled for newly created files. For example, if
you set all the ``other'' access bits in the mask, then newly created
files are not accessible at all to processes in the ``other''
-category, even if the @var{mode} argument specified to the creation
+category, even if the @var{mode} argument specified to the creation
function would permit such access. In other words, the file creation
mask is the complement of the ordinary access permissions you want to
grant.
@@ -1671,7 +1671,7 @@ files off-limits to ordinary users---for example, to modify
@file{/etc/passwd}. Programs designed to be run by ordinary users but
access such files use the setuid bit feature so that they always run
with @code{root} as the effective user ID.
-
+
Such a program may also access files specified by the user, files which
conceptually are being accessed explicitly by the user. Since the
program runs as @code{root}, it has permission to access whatever file
@@ -1776,7 +1776,7 @@ Argument that means, test for existence of the file.
Each file has three timestamps associated with it: its access time,
its modification time, and its attribute modification time. These
correspond to the @code{st_atime}, @code{st_mtime}, and @code{st_ctime}
-members of the @code{stat} structure; see @ref{File Attributes}.
+members of the @code{stat} structure; see @ref{File Attributes}.
All of these times are represented in calendar time format, as
@code{time_t} objects. This data type is defined in @file{time.h}.
@@ -1832,7 +1832,7 @@ named @var{filename}.
If @var{times} is a null pointer, then the access and modification times
of the file are set to the current time. Otherwise, they are set to the
values from the @code{actime} and @code{modtime} members (respectively)
-of the @code{utimbuf} structure pointed at by @var{times}.
+of the @code{utimbuf} structure pointed at by @var{times}.
The attribute modification time for the file is set to the current time
in either case (since changing the timestamps is itself a modification
@@ -1938,12 +1938,14 @@ this file, you must remove the old file explicitly first.
If you need to use a temporary file in your program, you can use the
@code{tmpfile} function to open it. Or you can use the @code{tmpnam}
-function make a name for a temporary file and then open it in the usual
-way with @code{fopen}.
+(better: @code{tmpnam_r}) function make a name for a temporary file and
+then open it in the usual way with @code{fopen}.
The @code{tempnam} function is like @code{tmpnam} but lets you choose
what directory temporary files will go in, and something about what
-their file names will look like.
+their file names will look like. Important for multi threaded programs
+is that @code{tempnam} is reentrant while @code{tmpnam} is not since it
+returns a pointer to a static buffer.
These facilities are declared in the header file @file{stdio.h}.
@pindex stdio.h
@@ -1956,6 +1958,8 @@ calling @code{fopen} with mode @code{"wb+"}. The file is deleted
automatically when it is closed or when the program terminates. (On
some other ANSI C systems the file may fail to be deleted if the program
terminates abnormally).
+
+This function is reentrant.
@end deftypefun
@comment stdio.h
@@ -1964,14 +1968,26 @@ terminates abnormally).
This function constructs and returns a file name that is a valid file
name and that does not name any existing file. If the @var{result}
argument is a null pointer, the return value is a pointer to an internal
-static string, which might be modified by subsequent calls. Otherwise,
-the @var{result} argument should be a pointer to an array of at least
-@code{L_tmpnam} characters, and the result is written into that array.
-
-It is possible for @code{tmpnam} to fail if you call it too many times.
-This is because the fixed length of a temporary file name gives room for
-only a finite number of different names. If @code{tmpnam} fails, it
-returns a null pointer.
+static string, which might be modified by subsequent calls and therefore
+makes this function non-reentrant. Otherwise, the @var{result} argument
+should be a pointer to an array of at least @code{L_tmpnam} characters,
+and the result is written into that array.
+
+It is possible for @code{tmpnam} to fail if you call it too many times
+without removing previously created files. This is because the fixed
+length of a temporary file name gives room for only a finite number of
+different names. If @code{tmpnam} fails, it returns a null pointer.
+@end deftypefun
+
+@comment stdio.h
+@comment GNU
+@deftypefun {char *} tmpnam_r (char *@var{result})
+This function is nearly identical to the @code{tmpnam} function. But it
+does not allow @var{result} to be a null pointer. In the later case a
+null pointer is returned.
+
+This function is reentrant because the non-reentrant situation of
+@code{tmpnam} cannot happen here.
@end deftypefun
@comment stdio.h
@@ -2006,13 +2022,16 @@ prefix for the file name. The return value is a string newly allocated
with @code{malloc}; you should release its storage with @code{free} when
it is no longer needed.
+Because the string is dynamically allocated this function is reentrant.
+
The directory prefix for the temporary file name is determined by testing
each of the following, in sequence. The directory must exist and be
writable.
@itemize @bullet
@item
-The environment variable @code{TMPDIR}, if it is defined.
+The environment variable @code{TMPDIR}, if it is defined. For security
+reasons this only happens if the program is not SUID or SGID enabled.
@item
The @var{dir} argument, if it is not a null pointer.
diff --git a/misc/Makefile b/misc/Makefile
index 00f5f78..e6ad0d0 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -55,7 +55,12 @@ routines := brk sbrk sstk ioctl \
efgcvt efgcvt_r qefgcvt qefgcvt_r \
hsearch hsearch_r tsearch lsearch \
err error ustat \
- getsysstats force-wrapper
+ getsysstats
+
+ifneq (,$(filter %REENTRANT, $(defines)))
+routines += force-wrapper
+endif
+
aux := init-misc
distribute := bsd-compat.c
extra-objs := bsd-compat.o
diff --git a/misc/hsearch_r.c b/misc/hsearch_r.c
index 95813e4..d0fb3e1 100644
--- a/misc/hsearch_r.c
+++ b/misc/hsearch_r.c
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
which describes the current status. */
typedef struct _ENTRY
{
- int used;
+ unsigned int used;
ENTRY entry;
}
_ENTRY;
diff --git a/misc/mntent_r.c b/misc/mntent_r.c
index 9395525..70da258 100644
--- a/misc/mntent_r.c
+++ b/misc/mntent_r.c
@@ -74,16 +74,16 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
/* skip empty lines and comment lines: */
} while (head[0] == '\0' || head[0] == '#');
- mp->mnt_fsname = strsep (&head, " \t") ?: (char *) "";
+ mp->mnt_fsname = __strsep (&head, " \t") ?: (char *) "";
if (head)
head += strspn (head, " \t");
- mp->mnt_dir = strsep (&head, " \t") ?: (char *) "";
+ mp->mnt_dir = __strsep (&head, " \t") ?: (char *) "";
if (head)
head += strspn (head, " \t");
- mp->mnt_type = strsep (&head, " \t") ?: (char *) "";
+ mp->mnt_type = __strsep (&head, " \t") ?: (char *) "";
if (head)
head += strspn (head, " \t");
- mp->mnt_opts = strsep (&head, " \t") ?: (char *) "";
+ mp->mnt_opts = __strsep (&head, " \t") ?: (char *) "";
switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0)
{
case 0:
diff --git a/nss/nss_dns/dns-host.c b/nss/nss_dns/dns-host.c
index 9a01c9f..f8d5d37 100644
--- a/nss/nss_dns/dns-host.c
+++ b/nss/nss_dns/dns-host.c
@@ -501,7 +501,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
++had_error;
continue;
}
- strcpy (bp, tbuf);
+ strcpy (bp, tbuf); /* Cannot overflow. */
result->h_name = bp;
bp += n;
linebuflen -= n;
@@ -524,7 +524,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
++had_error;
continue;
}
- strcpy (bp, tbuf);
+ strcpy (bp, tbuf); /* Cannot overflow. */
tname = bp;
bp += n;
linebuflen -= n;
@@ -650,7 +650,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
n = strlen (qname) + 1; /* For the \0. */
if (n > linebuflen)
goto try_again;
- strcpy (bp, qname);
+ strcpy (bp, qname); /* Cannot overflow. */
result->h_name = bp;
bp += n;
linebuflen -= n;
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 61724bf..842e63c 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -1046,7 +1046,7 @@ const char *
p_time(value)
u_int32_t value;
{
- static char nbuf[40];
+ static char nbuf[60];
int secs, mins, hours, days;
register char *p;
diff --git a/resolv/res_init.c b/resolv/res_init.c
index caeb337..c8a74f6 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -216,7 +216,7 @@ res_init()
_res.pfcode = 0;
/* Allow user to override the local domain definition */
- if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+ if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) {
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
haveenv++;
@@ -421,7 +421,7 @@ res_init()
#endif /* !RFC1535 */
}
- if ((cp = getenv("RES_OPTIONS")) != NULL)
+ if ((cp = __secure_getenv("RES_OPTIONS")) != NULL)
res_setoptions(cp, "env");
_res.options |= RES_INIT;
return (0);
diff --git a/resolv/res_query.c b/resolv/res_query.c
index e989802..ac50a9c 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -363,7 +363,7 @@ hostalias(name)
if (_res.options & RES_NOALIASES)
return (NULL);
- file = getenv("HOSTALIASES");
+ file = __secure_getenv("HOSTALIASES");
if (file == NULL || (fp = fopen(file, "r")) == NULL)
return (NULL);
setbuf(fp, NULL);
diff --git a/stdio-common/tempnam.c b/stdio-common/tempnam.c
index 14988a8..a86ac08 100644
--- a/stdio-common/tempnam.c
+++ b/stdio-common/tempnam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1996 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
@@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
-#include <ansidecl.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
@@ -32,19 +31,20 @@ Cambridge, MA 02139, USA. */
P_tmpdir is tried and finally "/tmp". The storage for the filename
is allocated by `malloc'. */
char *
-DEFUN(tempnam, (dir, pfx), CONST char *dir AND CONST char *pfx)
+tempnam (const char *dir, const char *pfx)
{
+ char buf[FILENAME_MAX];
size_t len;
register char *s;
- register char *t = __stdio_gen_tempname(dir, pfx, 1, &len, (FILE **) NULL);
+ register char *t = __stdio_gen_tempname (buf, sizeof (buf), dir, pfx, 1,
+ &len, (FILE **) NULL);
if (t == NULL)
return NULL;
- s = (char *) malloc(len);
+ s = (char *) malloc (len);
if (s == NULL)
return NULL;
- (void) memcpy(s, t, len);
- return s;
+ return (char *) memcpy (s, t, len);
}
diff --git a/stdio-common/temptest.c b/stdio-common/temptest.c
index 3747198..09786b2 100644
--- a/stdio-common/temptest.c
+++ b/stdio-common/temptest.c
@@ -7,12 +7,13 @@ char *files[500];
int
main ()
{
+ char buf[FILENAME_MAX];
char *fn;
FILE *fp;
int i;
for (i = 0; i < 500; i++) {
- fn = __stdio_gen_tempname((CONST char *) NULL,
+ fn = __stdio_gen_tempname(buf, sizeof (buf), (CONST char *) NULL,
"file", 0, (size_t *) NULL, (FILE **) NULL);
if (fn == NULL) {
printf ("__stdio_gen_tempname failed\n");
diff --git a/stdio-common/tmpfile.c b/stdio-common/tmpfile.c
index dfe11ad..924df9b 100644
--- a/stdio-common/tmpfile.c
+++ b/stdio-common/tmpfile.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1996 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
@@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
-#include <ansidecl.h>
#include <stdio.h>
@@ -25,12 +24,13 @@ Cambridge, MA 02139, USA. */
If we couldn't generate a unique filename or the file couldn't
be opened, NULL is returned. */
FILE *
-DEFUN_VOID(tmpfile)
+tmpfile ()
{
+ char buf[FILENAME_MAX];
char *filename;
FILE *f;
- filename = __stdio_gen_tempname ((char *) NULL, "tmpf", 0,
+ filename = __stdio_gen_tempname (buf, sizeof (buf), (char *) NULL, "tmpf", 0,
(size_t *) NULL, &f);
if (filename == NULL)
return NULL;
diff --git a/stdio-common/tmpnam.c b/stdio-common/tmpnam.c
index 88dd0a4..44397bc 100644
--- a/stdio-common/tmpnam.c
+++ b/stdio-common/tmpnam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1996 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
@@ -16,27 +16,34 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
-#include <ansidecl.h>
-#include <stddef.h>
#include <stdio.h>
#include <string.h>
-/* Generate a unique filename in P_tmpdir. */
+/* Generate a unique filename in P_tmpdir.
+
+ This function is *not* thread safe! */
char *
-DEFUN(tmpnam, (s), register char *s)
+tmpnam (char *s)
{
- register char *t = __stdio_gen_tempname((CONST char *) NULL,
- (CONST char *) NULL, 0,
- (size_t *) NULL, (FILE **) NULL);
-
- if (t == NULL)
- return NULL;
-
- if (s != NULL)
- (void) strcpy(s, t);
- else
- s = t;
-
- return s;
+ /* By using two buffers we manage to be thread safe in the case
+ where S != NULL. */
+ static char buf[L_tmpnam];
+ char *tmpbuf[L_tmpnam];
+ char *result;
+
+ /* In the following call we use the buffer pointed to by S if
+ non-NULL although we don't know the size. But we limit the size
+ to FILENAME_MAX characters in any case. */
+ result = __stdio_gen_tempname (s ?: tmpbuf, L_tmpnam, (const char *) NULL,
+ (const char *) NULL, 0,
+ (size_t *) NULL, (FILE **) NULL);
+
+ if (result != NULL && s == NULL)
+ {
+ memcpy (buf, result, L_tmpnam);
+ result = buf;
+ }
+
+ return result;
}
diff --git a/stdio-common/tmpnam_r.c b/stdio-common/tmpnam_r.c
new file mode 100644
index 0000000..2794e77
--- /dev/null
+++ b/stdio-common/tmpnam_r.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1993, 1996 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <string.h>
+
+
+/* Generate a unique filename in P_tmpdir. If S is NULL return NULL.
+ This makes this function thread safe. */
+char *
+tmpnam_r (char *s)
+{
+ if (s == NULL)
+ return NULL;
+
+ /* In the following call we use the buffer pointed to by S if
+ non-NULL although we don't know the size. But we limit the size
+ to L_tmpnam characters in any case. */
+ return __stdio_gen_tempname (s, L_tmpnam, (const char *) NULL,
+ (const char *) NULL, 0,
+ (size_t *) NULL, (FILE **) NULL);
+}
diff --git a/stdio/stdio.h b/stdio/stdio.h
index 47348a6..8072625 100644
--- a/stdio/stdio.h
+++ b/stdio/stdio.h
@@ -156,7 +156,8 @@ extern int __stdio_open __P ((__const char *__file, __io_mode __m,
/* Put out an error message for when stdio needs to die. */
extern void __stdio_errmsg __P ((__const char *__msg, size_t __len));
/* Generate a unique file name (and possibly open it with mode "w+b"). */
-extern char *__stdio_gen_tempname __P ((__const char *__dir,
+extern char *__stdio_gen_tempname __P ((char *__buf, size_t __bufsize,
+ __const char *__dir,
__const char *__pfx,
int __dir_search,
size_t *__lenptr,
@@ -294,6 +295,12 @@ extern FILE *tmpfile __P ((void));
/* Generate a temporary filename. */
extern char *tmpnam __P ((char *__s));
+#ifdef __USE_REENTRANT
+/* This is the reentrant variant of `tmpnam'. The only difference is
+ that it does not allow S to be NULL. */
+extern char *tmpnam_r __P ((char *__s));
+#endif
+
#ifdef __USE_SVID
/* Generate a unique temporary filename using up to five characters of PFX
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 7da32b9..cb48aa1 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -361,6 +361,10 @@ extern void exit __P ((int __status)) __attribute__ ((__noreturn__));
/* Return the value of envariable NAME, or NULL if it doesn't exist. */
extern char *getenv __P ((__const char *__name));
+/* This function is similar to the above but returns NULL if the
+ programs is running with SUID or SGID enabled. */
+extern char *__secure_getenv __P ((__const char *__name));
+
#ifdef __USE_SVID
/* The SVID says this is in <stdio.h>, but this seems a better place. */
/* Put STRING, which is of the form "NAME=VALUE", in the environment.
diff --git a/stdlib/test-canon.c b/stdlib/test-canon.c
index f411067..95a5b78 100644
--- a/stdlib/test-canon.c
+++ b/stdlib/test-canon.c
@@ -107,7 +107,7 @@ check_path (const char * result, const char * expected)
}
-void
+int
main (int argc, char ** argv)
{
char * result;
@@ -117,12 +117,12 @@ main (int argc, char ** argv)
getcwd (cwd, sizeof(buf));
cwd_len = strlen (cwd);
- for (i = 0; i < sizeof (symlinks) / sizeof (symlinks[0]); ++i)
+ for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i)
symlink (symlinks[i].value, symlinks[i].name);
fd = open("doesExist", O_CREAT | O_EXCL, 0777);
- for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+ for (i = 0; i < (int) (sizeof (tests) / sizeof (tests[0])); ++i)
{
buf[0] = '\0';
result = realpath (tests[i].in, buf);
@@ -148,7 +148,7 @@ main (int argc, char ** argv)
if (!tests[i].out && errno != tests[i].error)
{
printf ("%s: flunked test %d (expected errno %d, got %d)\n",
- argv[0], i, tests[i].errno, errno);
+ argv[0], i, tests[i].error, errno);
++errors;
continue;
}
@@ -165,17 +165,15 @@ main (int argc, char ** argv)
if (fd >= 0)
unlink("doesExist");
- for (i = 0; i < sizeof (symlinks) / sizeof (symlinks[0]); ++i)
+ for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i)
unlink (symlinks[i].name);
- if (errors == 0)
- {
- puts ("No errors.");
- exit (EXIT_SUCCESS);
- }
- else
+ if (errors != 0)
{
printf ("%d errors.\n", errors);
exit (EXIT_FAILURE);
}
+
+ puts ("No errors.");
+ return EXIT_SUCCESS;
}
diff --git a/string/string.h b/string/string.h
index 53b6096..8b9fd5c 100644
--- a/string/string.h
+++ b/string/string.h
@@ -209,6 +209,7 @@ extern int strncasecmp __P ((__const char *__s1, __const char *__s2,
/* Return the next DELIM-delimited token from *STRINGP,
terminating it with a '\0', and update *STRINGP to point past it. */
+extern char *__strsep __P ((char **__stringp, __const char *__delim));
extern char *strsep __P ((char **__stringp, __const char *__delim));
#endif
diff --git a/sysdeps/generic/getenv.c b/sysdeps/generic/getenv.c
index d4099a9..daf2927 100644
--- a/sysdeps/generic/getenv.c
+++ b/sysdeps/generic/getenv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1994, 1996 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
@@ -16,7 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
-#include <ansidecl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -28,17 +27,29 @@ Cambridge, MA 02139, USA. */
/* Return the value of the environment variable NAME. */
char *
-DEFUN(getenv, (name), register CONST char *name)
+getenv (name)
+ const char *name;
{
- register CONST size_t len = strlen(name);
- register char **ep;
+ const size_t len = strlen (name);
+ char **ep;
if (__environ == NULL)
return NULL;
for (ep = __environ; *ep != NULL; ++ep)
- if (!strncmp(*ep, name, len) && (*ep)[len] == '=')
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
return &(*ep)[len + 1];
return NULL;
}
+
+
+/* Some programs and especially the libc itself have to be careful
+ what values to accept from the environment. This special version
+ checks for SUID or SGID first before doing any work. */
+char *
+__secure_getenv (name)
+ const char *name;
+{
+ return __libc_enable_secure ? NULL : getenv (name);
+}
diff --git a/sysdeps/generic/prof-freq.c b/sysdeps/generic/prof-freq.c
index 4ad4212..ff08514 100644
--- a/sysdeps/generic/prof-freq.c
+++ b/sysdeps/generic/prof-freq.c
@@ -37,7 +37,7 @@
#include <sys/time.h>
int
-__profile_frequency ()
+__profile_frequency (void)
{
/*
* Discover the tick frequency of the machine if something goes wrong,
diff --git a/sysdeps/generic/pty.c b/sysdeps/generic/pty.c
index dda21258..6995417 100644
--- a/sysdeps/generic/pty.c
+++ b/sysdeps/generic/pty.c
@@ -46,6 +46,7 @@ static char sccsid[] = "@(#)pty.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <string.h>
#include <grp.h>
+#include <pty.h>
int
openpty(amaster, aslave, name, termp, winp)
@@ -105,7 +106,7 @@ forkpty(amaster, name, termp, winp)
struct termios *termp;
struct winsize *winp;
{
- extern int login_tty();
+ extern int login_tty __P ((int fd));
int master, slave, pid;
if (openpty(&master, &slave, name, termp, winp) == -1)
diff --git a/sysdeps/generic/strsep.c b/sysdeps/generic/strsep.c
index 6fbcb08..15c5891 100644
--- a/sysdeps/generic/strsep.c
+++ b/sysdeps/generic/strsep.c
@@ -19,7 +19,7 @@ Boston, MA 02111-1307, USA. */
#include <string.h>
char *
-strsep (char **stringp, const char *delim)
+__strsep (char **stringp, const char *delim)
{
char *begin, *end;
@@ -41,3 +41,4 @@ strsep (char **stringp, const char *delim)
return begin;
}
+weak_alias (__strsep, strsep)
diff --git a/sysdeps/generic/sys/sysinfo.h b/sysdeps/generic/sys/sysinfo.h
index e9f6674..f68fcc0 100644
--- a/sysdeps/generic/sys/sysinfo.h
+++ b/sysdeps/generic/sys/sysinfo.h
@@ -22,12 +22,12 @@ Boston, MA 02111-1307, USA. */
#include <features.h>
/* Return number of configured processors. */
-extern int __get_nproc_conf __P ((void));
-extern int get_nproc_conf __P ((void));
+extern int __get_nprocs_conf __P ((void));
+extern int get_nprocs_conf __P ((void));
/* Return number of available processors. */
-extern int __get_nproc __P ((void));
-extern int get_nproc __P ((void));
+extern int __get_nprocs __P ((void));
+extern int get_nprocs __P ((void));
/* Return number of physical pages of memory in the system. */
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index a9536b9..825599f 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -298,7 +298,7 @@ __getcwd (buf, size)
(d->d_name[1] == '\0' ||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
continue;
- if (mount_point || d->d_ino == thisino)
+ if (mount_point || (ino_t) d->d_ino == thisino)
{
char name[dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN (d)];
memcpy (name, dotp, dotlist + dotsize - dotp);
@@ -326,7 +326,7 @@ __getcwd (buf, size)
{
size_t namlen = _D_EXACT_NAMLEN (d);
- if (pathp - path < namlen)
+ if ((size_t) (pathp - path) < namlen)
{
if (buf != NULL)
{
diff --git a/sysdeps/posix/mk-stdiolim.c b/sysdeps/posix/mk-stdiolim.c
index da78a98..5df460e 100644
--- a/sysdeps/posix/mk-stdiolim.c
+++ b/sysdeps/posix/mk-stdiolim.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1996 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
@@ -23,7 +23,7 @@ main()
{
/* These values correspond to the code in sysdeps/posix/tempname.c.
Change the values here if you change that code. */
- printf("#define L_tmpnam %u\n", sizeof("/usr/tmp/") + 8);
+ printf("#define L_tmpnam %u\n", sizeof("/usr/tmp/") + 9);
printf("#define TMP_MAX %u\n", 62 * 62 * 62);
puts ("#ifdef __USE_POSIX");
@@ -36,7 +36,7 @@ main()
is the case in the Hurd). ANSI still requires that FOPEN_MAX and
FILENAME_MAX be defined, however. */
- printf("#define FOPEN_MAX %u\n",
+ printf("#define FOPEN_MAX %u\n",
#ifdef OPEN_MAX
OPEN_MAX
@@ -51,7 +51,7 @@ main()
);
- printf("#define FILENAME_MAX %u\n",
+ printf("#define FILENAME_MAX %u\n",
#ifdef PATH_MAX
PATH_MAX
#else
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index 6fd698e..d58024f 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -81,21 +81,24 @@ static const char letters[] =
existing file will be returned. When the cycle reaches its end
(12345ZZZ), NULL is returned. */
char *
-__stdio_gen_tempname (const char *dir, const char *pfx, int dir_search,
- size_t *lenptr, FILE **streamptr)
+__stdio_gen_tempname (char *buf, size_t bufsize, const char *dir,
+ const char *pfx, int dir_search, size_t *lenptr,
+ FILE **streamptr)
{
int saverrno = errno;
static const char tmpdir[] = P_tmpdir;
static size_t indices[2];
size_t *idx;
- static char buf[FILENAME_MAX];
+#if 0
static pid_t oldpid = (pid_t) 0;
+#endif
pid_t pid = __getpid();
register size_t len, plen, dlen;
+ int wrapped;
if (dir_search)
{
- register const char *d = getenv ("TMPDIR");
+ register const char *d = __secure_getenv ("TMPDIR");
if (d != NULL && !diraccess (d))
d = NULL;
if (d == NULL && dir != NULL && diraccess (dir))
@@ -133,34 +136,51 @@ __stdio_gen_tempname (const char *dir, const char *pfx, int dir_search,
dir = tmpdir;
idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0];
+#if 0
+ /* XXX Is this ever useful??? At least when using a thread package
+ which uses different PIDs for the threads it is not helpful. */
if (pid != oldpid)
{
oldpid = pid;
indices[0] = indices[1] = 0;
}
+#endif
+ wrapped = 0; /* We have not yet wrapped around the index counter. */
len = dlen + 1 + plen + 5 + 3;
- while (*idx < ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
- (sizeof (letters) - 1)))
+ while (1)
{
- const size_t i = (*idx)++;
+ const size_t i;
+
+ if (*idx >= ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
+ (sizeof (letters) - 1)))
+ {
+ if (wrapped)
+ /* We really wrapped around this call. Can't believe it
+ but nevertheless stop the endless loop. */
+ break;
+
+ indices[0] = indices[1] = 0;
+ wrapped = 1;
+ }
+
+ i = (*idx)++;
/* Construct a file name and see if it already exists.
We use a single counter in *IDX to cycle each of three
character positions through each of 62 possible letters. */
- if (sizeof (buf) < len ||
- sprintf (buf, "%.*s/%.*s%.5d%c%c%c",
- (int) dlen, dir, (int) plen,
- pfx, pid % 100000,
- letters[i % (sizeof (letters) - 1)],
- letters[(i / (sizeof (letters) - 1))
- % (sizeof (letters) - 1)],
- letters[(i / ((sizeof (letters) - 1) *
- (sizeof (letters) - 1)))
- % (sizeof (letters) - 1)]
- ) != (int) len)
+ if (__snprintf (buf, bufsize, "%.*s/%.*s%.5d%c%c%c",
+ (int) dlen, dir, (int) plen,
+ pfx, pid % 100000,
+ letters[i % (sizeof (letters) - 1)],
+ letters[(i / (sizeof (letters) - 1))
+ % (sizeof (letters) - 1)],
+ letters[(i / ((sizeof (letters) - 1) *
+ (sizeof (letters) - 1)))
+ % (sizeof (letters) - 1)]
+ ) != (int) len)
return NULL;
if (streamptr != NULL)
@@ -176,7 +196,7 @@ __stdio_gen_tempname (const char *dir, const char *pfx, int dir_search,
struct _IO_FILE_plus *fp;
fp = (struct _IO_FILE_plus *)
- malloc(sizeof (struct _IO_FILE_plus));
+ malloc (sizeof (struct _IO_FILE_plus));
if (fp == NULL)
{
/* We lost trying to create a stream (out of memory?).
diff --git a/sysdeps/posix/ttyname.c b/sysdeps/posix/ttyname.c
index be82827..9668117 100644
--- a/sysdeps/posix/ttyname.c
+++ b/sysdeps/posix/ttyname.c
@@ -57,7 +57,7 @@ ttyname (fd)
return NULL;
while ((d = readdir (dirstream)) != NULL)
- if (d->d_fileno == myino)
+ if ((ino_t) d->d_fileno == myino)
{
size_t dlen = _D_ALLOC_NAMLEN (d);
if (sizeof (dev) + dlen > namelen)
diff --git a/sysdeps/posix/ttyname_r.c b/sysdeps/posix/ttyname_r.c
index 1fb4b04..d7f6026 100644
--- a/sysdeps/posix/ttyname_r.c
+++ b/sysdeps/posix/ttyname_r.c
@@ -72,7 +72,7 @@ __ttyname_r (fd, buf, buflen)
buflen -= sizeof (dev);
while ((d = readdir (dirstream)) != NULL)
- if (d->d_fileno == myino)
+ if ((ino_t) d->d_fileno == myino)
{
char *cp;
diff --git a/sysdeps/stub/getenv.c b/sysdeps/stub/getenv.c
index fab9f08..f12964e 100644
--- a/sysdeps/stub/getenv.c
+++ b/sysdeps/stub/getenv.c
@@ -27,6 +27,7 @@ getenv (name)
__set_errno (ENOSYS);
return NULL;
}
+strong_alias (getenv, __secure_getenv)
stub_warning (getenv)
diff --git a/sysdeps/stub/nanosleep.c b/sysdeps/stub/nanosleep.c
index 0995bb9..bdc9d28 100644
--- a/sysdeps/stub/nanosleep.c
+++ b/sysdeps/stub/nanosleep.c
@@ -22,9 +22,13 @@ Boston, MA 02111-1307, USA. */
/* Pause execution for a number of nanoseconds. */
int
-nanosleep (const struct timespec *requested_time, struct timespec *remaining)
+__libc_nanosleep (const struct timespec *requested_time,
+ struct timespec *remaining)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (nanosleep)
+
+weak_alias (__libc_nanosleep, __nanosleep)
+weak_alias (__libc_nanosleep, nanosleep)
diff --git a/sysdeps/stub/tempname.c b/sysdeps/stub/tempname.c
index 939c70f..e383457 100644
--- a/sysdeps/stub/tempname.c
+++ b/sysdeps/stub/tempname.c
@@ -26,7 +26,9 @@ Cambridge, MA 02139, USA. */
Return the generated filename or NULL if one could not
be generated, putting the length of the string in *LENPTR. */
char *
-__stdio_gen_tempname (dir, pfx, dir_search, lenptr)
+__stdio_gen_tempname (buf, bufsize, dir, pfx, dir_search, lenptr)
+ char *buf;
+ size_t bufsize;
const char *dir;
const char *pfx;
int dir_search;
diff --git a/sysdeps/unix/nlist.c b/sysdeps/unix/nlist.c
index b40aedb..ffdd21d 100644
--- a/sysdeps/unix/nlist.c
+++ b/sysdeps/unix/nlist.c
@@ -26,9 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
which is terminated by an element with a NULL `n_un.n_name' member,
and fill in the elements of NL. */
int
-nlist (file, nl)
- const char *file;
- struct nlist *nl;
+nlist (const char *file, struct nlist *nl)
{
FILE *f;
struct exec header;
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index c4c6fd7..349da98 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -33,14 +33,11 @@ get_proc_path (char *buffer, size_t bufsize)
FILE *fp;
struct mntent mount_point;
struct mntent *entry;
- char *result;
+ char *result = NULL;
/* First find the mount point of the proc filesystem. */
fp = __setmntent (_PATH_MNTTAB, "r");
- if (fp == NULL)
- /* Cannot find mount table file. */
- result = NULL;
- else
+ if (fp != NULL)
{
while ((entry = __getmntent_r (fp, &mount_point, buffer, bufsize))
!= NULL)
@@ -108,7 +105,7 @@ weak_alias (__get_nprocs, get_nprocs)
/* As far as I know Linux has no separate numbers for configured and
available processors. So make the `get_nprocs_conf' function an
- prototype. */
+ alias. */
strong_alias (__get_nprocs, __get_nprocs_conf)
weak_alias (__get_nprocs, get_nprocs_conf)
diff --git a/sysdeps/unix/sysv/linux/sleep.c b/sysdeps/unix/sysv/linux/sleep.c
index 1094df5..a4cf47b 100644
--- a/sysdeps/unix/sysv/linux/sleep.c
+++ b/sysdeps/unix/sysv/linux/sleep.c
@@ -26,7 +26,7 @@ sleep (unsigned int seconds)
struct timespec ts = { tv_sec: (long int) seconds, tv_nsec: 0 };
unsigned int result;
- if (nanosleep (&ts, &ts) == 0)
+ if (__nanosleep (&ts, &ts) == 0)
result = 0;
else
/* Round remaining time. */
diff --git a/sysdeps/unix/sysv/linux/sys/sysinfo.h b/sysdeps/unix/sysv/linux/sys/sysinfo.h
index 1fabb06..fbdb1de 100644
--- a/sysdeps/unix/sysv/linux/sys/sysinfo.h
+++ b/sysdeps/unix/sysv/linux/sys/sysinfo.h
@@ -29,12 +29,12 @@ extern int sysinfo __P ((struct sysinfo *__info));
/* Return number of configured processors. */
-extern int __get_nproc_conf __P ((void));
-extern int get_nproc_conf __P ((void));
+extern int __get_nprocs_conf __P ((void));
+extern int get_nprocs_conf __P ((void));
/* Return number of available processors. */
-extern int __get_nproc __P ((void));
-extern int get_nproc __P ((void));
+extern int __get_nprocs __P ((void));
+extern int get_nprocs __P ((void));
/* Return number of physical pages of memory in the system. */
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 3601b5f..f831b41 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -1,6 +1,6 @@
# File name Caller Syscall name # args Strong name Weak names
-adjtimex adjtime adjtimex 1 __adjtimex
+adjtimex adjtime adjtimex 1 __adjtimex adjtimex
bdflush EXTRA bdflush 2 bdflush
create_module EXTRA create_module 3 create_module
delete_module EXTRA delete_module 3 delete_module
@@ -20,13 +20,13 @@ iopl - iopl 1 iopl
ipc msgget ipc 5 __ipc
klogctl EXTRA syslog 3 klogctl
llseek EXTRA _llseek 5 llseek
-mlock - mlock 2 __mlock mlock
-mlockall - mlockall 1 __mlockall mlockall
+mlock EXTRA mlock 2 __mlock mlock
+mlockall EXTRA mlockall 1 __mlockall mlockall
mount EXTRA mount 5 __mount mount
-mremap - mremap 4 __mremap mremap
-munlock - munlock 2 __munlock munlock
-munlockall - munlockall 0 __munlockall munlockall
-nanosleep - nanosleep 2 __libc_nanosleep nanosleep
+mremap EXTRA mremap 4 __mremap mremap
+munlock EXTRA munlock 2 __munlock munlock
+munlockall EXTRA munlockall 0 __munlockall munlockall
+nanosleep - nanosleep 2 __libc_nanosleep __nanosleep nanosleep
pause - pause 0 __libc_pause pause
personality init-first personality 1 __personality personality
pipe - pipe 1 __pipe pipe
diff --git a/time/strftime.c b/time/strftime.c
index 9d23cf7..36088d0 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -24,6 +24,7 @@ Cambridge, MA 02139, USA. */
# define HAVE_LIMITS_H 1
# define HAVE_MBLEN 1
# define HAVE_MBRLEN 1
+# define HAVE_STRUCT_ERA_ENTRY 1
# define HAVE_TM_GMTOFF 1
# define HAVE_TM_ZONE 1
# define MULTIBYTE_IS_FORMAT_SAFE 1
@@ -260,12 +261,9 @@ strftime (s, maxsize, format, tp)
const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
const char *const ampm = _NL_CURRENT (LC_TIME,
hour12 > 11 ? PM_STR : AM_STR);
- size_t aw_len = strlen(a_wkday);
- size_t am_len = strlen(a_month);
+ size_t aw_len = strlen (a_wkday);
+ size_t am_len = strlen (a_month);
size_t ap_len = strlen (ampm);
-
- const char *alt_digits = _NL_CURRENT (LC_TIME, ALT_DIGITS);
- const char *end_alt_digits = _NL_CURRENT (LC_TIME, ALT_DIGITS + 1);
#else
const char *const f_wkday = weekday_name[tp->tm_wday];
const char *const f_month = month_name[tp->tm_mon];
@@ -423,9 +421,6 @@ strftime (s, maxsize, format, tp)
#define DO_NUMBER_SPACEPAD(d, v) \
digits = d; number_value = v; goto do_number_spacepad
- case '\0': /* GNU extension: % at end of format. */
- --f;
- /* Fall through. */
case '%':
if (modifier != 0)
goto bad_format;
@@ -480,8 +475,17 @@ strftime (s, maxsize, format, tp)
case 'C': /* POSIX.2 extension. */
if (modifier == 'O')
goto bad_format;
-#ifdef _NL_CURRENT
- /* XXX %EC is not implemented yet. */
+#if HAVE_STRUCT_ERA_ENTRY
+ if (modifier == 'E')
+ {
+ struct era_entry *era = _nl_get_era_entry (tp);
+ if (era)
+ {
+ size_t len = strlen (era->name_fmt);
+ cpy (len, era->name_fmt);
+ break;
+ }
+ }
#endif
{
int year = tp->tm_year + TM_YEAR_BASE;
@@ -769,10 +773,16 @@ strftime (s, maxsize, format, tp)
DO_NUMBER (1, tp->tm_wday);
case 'Y':
-#ifdef _NL_CURRENT
- if (modifier == 'E'
- && *(subfmt = _NL_CURRENT (LC_TIME, ERA_YEAR)) != '\0')
- goto subformat;
+#if HAVE_STRUCT_ERA_ENTRY
+ if (modifier == 'E')
+ {
+ struct era_entry *era = _nl_get_era_entry (tp);
+ if (era)
+ {
+ subfmt = strchr (era->name_fmt, '\0') + 1;
+ goto subformat;
+ }
+ }
#endif
if (modifier == 'O')
goto bad_format;
@@ -780,8 +790,17 @@ strftime (s, maxsize, format, tp)
DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
case 'y':
-#ifdef _NL_CURRENT
- /* XXX %Ey is not implemented yet. */
+#if HAVE_STRUCT_ERA_ENTRY
+ if (modifier == 'E')
+ {
+ struct era_entry *era = _nl_get_era_entry (tp);
+ if (era)
+ {
+ int delta = tp->tm_year - era->start_date[0];
+ DO_NUMBER (1, (era->offset
+ + (era->direction == '-' ? -delta : delta)));
+ }
+ }
#endif
DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
@@ -837,6 +856,9 @@ strftime (s, maxsize, format, tp)
DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
}
+ case '\0': /* GNU extension: % at end of format. */
+ --f;
+ /* Fall through. */
default:
/* Unknown format; output the format, including the '%',
since this is most likely the right thing to do if a
@@ -844,7 +866,7 @@ strftime (s, maxsize, format, tp)
bad_format:
{
int flen;
- for (flen = 2; f[1 - flen] != '%'; flen++)
+ for (flen = 1; f[1 - flen] != '%'; flen++)
continue;
cpy (flen, &f[1 - flen]);
}
diff --git a/time/time.h b/time/time.h
index f4c27f9..2dc25ab 100644
--- a/time/time.h
+++ b/time/time.h
@@ -265,6 +265,8 @@ extern int dysize __P ((int __year));
#ifdef __USE_POSIX
/* Pause execution for a number of nanoseconds. */
+extern int __nanosleep __P ((__const struct timespec *__requested_time,
+ struct timespec *__remaining));
extern int nanosleep __P ((__const struct timespec *__requested_time,
struct timespec *__remaining));
#endif