From jakub@redhat.com Mon Dec 4 13:11:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 04 Dec 2006 13:11:00 -0000 Subject: [PATCH] Fix ttyname and ttyname_r Message-ID: <20061204131047.GG9556@sunsite.mff.cuni.cz> Hi! ttyname{,_r} cleanup from April this year moved isatty check before readlink which detected EBADF. As isatty (-1) == 0 (-1 stands for any invalid fd), this results in ttyname{,_r} returning ENOTTY (errno resp. return value) instead of EBADF. I don't think we can argument that invalid file descriptor does not refer to a terminal either and therefore it can return ENOTTY. As isatty function isn't documented to set any particular errno, I chose to inline isatty, i.e. call tcgetattr which is documented to set EBADF resp. ENOTTY, exactly what we need for ttyname{,_r}. 2006-12-04 Jakub Jelinek * sysdeps/unix/sysv/linux/ttyname.c: Include termios.h. (ttyname): Use tcgetattr instead of isatty, don't set errno to ENOTTY. * sysdeps/unix/sysv/linux/ttyname_r.c: Include termios.h. (__ttyname_r): Use tcgetattr instead of isatty, don't set errno to ENOTTY. * io/Makefile: Add rules to build and run tst-ttyname_r test. * io/tst-ttyname_r.c: New test. --- libc/sysdeps/unix/sysv/linux/ttyname.c.jj 2006-04-19 09:26:48.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/ttyname.c 2006-12-04 13:43:24.000000000 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -118,12 +119,12 @@ ttyname (int fd) int dostat = 0; char *name; int save = errno; + struct termios term; - if (__builtin_expect (!__isatty (fd), 0)) - { - __set_errno (ENOTTY); - return NULL; - } + /* isatty check, tcgetattr is used because it sets the correct + errno (EBADF resp. ENOTTY) on error. */ + if (__builtin_expect (__tcgetattr (fd, &term) < 0, 0)) + return NULL; /* We try using the /proc filesystem. */ *_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0'; --- libc/sysdeps/unix/sysv/linux/ttyname_r.c.jj 2006-04-19 09:26:48.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/ttyname_r.c 2006-12-04 13:43:35.000000000 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -115,11 +116,11 @@ __ttyname_r (int fd, char *buf, size_t b return ERANGE; } - if (__builtin_expect (!__isatty (fd), 0)) - { - __set_errno (ENOTTY); - return ENOTTY; - } + /* isatty check, tcgetattr is used because it sets the correct + errno (EBADF resp. ENOTTY) on error. */ + struct termios term; + if (__builtin_expect (__tcgetattr (fd, &term) < 0, 0)) + return errno; /* We try using the /proc filesystem. */ *_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0'; --- libc/io/Makefile.jj 2006-10-31 23:05:31.000000000 +0100 +++ libc/io/Makefile 2006-12-04 13:41:42.000000000 +0100 @@ -66,7 +66,7 @@ tests := test-utime test-stat test-stat tst-openat tst-unlinkat tst-fstatat tst-futimesat \ tst-renameat tst-fchownat tst-fchmodat tst-faccessat \ tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \ - tst-mknodat tst-mkfifoat + tst-mknodat tst-mkfifoat tst-ttyname_r distribute := ftwtest-sh --- libc/io/tst-ttyname_r.c.jj 2006-12-04 13:35:15.000000000 +0100 +++ libc/io/tst-ttyname_r.c 2006-12-04 13:41:02.000000000 +0100 @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include + +static int temp_fd; + +static void +do_prepare (void) +{ + char *temp_file; + temp_fd = create_temp_file ("tst-ttyname_r.", &temp_file); + if (temp_fd == -1) + error (1, errno, "cannot create temporary file"); +} + +static int +do_test (void) +{ + int ret = 0; + char buf[sysconf (_SC_TTY_NAME_MAX) + 1]; + int res = ttyname_r (-1, buf, sizeof (buf)); + if (res != EBADF) + { + printf ("1st ttyname_r returned with res %d\n", res); + ret++; + } + res = ttyname_r (temp_fd, buf, sizeof (buf)); + if (res != ENOTTY) + { + printf ("2nd ttyname_r returned with res %d\n", res); + ret++; + } + return ret; +} Jakub From jakub@redhat.com Tue Dec 5 19:52:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 05 Dec 2006 19:52:00 -0000 Subject: [PATCH] Fix nis_getnames Message-ID: <20061205195208.GI9556@sunsite.mff.cuni.cz> Hi! NIS_PATH is already in UNSECURE_ENVVARS, so ld.so unsetenv's it during start of suid/sgid programs, so all this __secure_getenv does is prohibit suid/sgid programs to setenv NIS_PATH to some value and expect nis_lookup or nis_list with EXPAND_NAME flag set to use it. 2006-12-05 Jakub Jelinek * nis/nis_subr.c (nis_getnames): Revert last change. --- libc/nis/nis_subr.c.jj 2006-10-19 17:26:39.000000000 +0200 +++ libc/nis/nis_subr.c 2006-12-05 20:47:11.000000000 +0100 @@ -178,7 +178,7 @@ nis_getnames (const_nis_name name) } /* Get the search path, where we have to search "name" */ - path = __secure_getenv ("NIS_PATH"); + path = getenv ("NIS_PATH"); if (path == NULL) path = strdupa ("$"); else Jakub From jakub@redhat.com Tue Dec 5 19:55:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 05 Dec 2006 19:55:00 -0000 Subject: cs_CZ LC_TIME changes Message-ID: <20061205195457.GJ9556@sunsite.mff.cuni.cz> Hi! This has been discussed with cs_CZ locale maintainer http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=218438 and others. Also, online Czech papers like http://www.lidovky.cz, http://zpravy.idnes.cz, http://www.aktualne.cz when writing dates numerically use the 5.1.2006 style, with no 0 nor space padding. 2006-12-05 Jakub Jelinek * locales/cs_CZ (LC_TIME): Change d_fmt to %e.%m.%Y from %-d.%-m.%Y. Change d_t_fmt to %a %-d. %B %Y, %H:%M:%S %Z from %a %e. %B %Y, %H:%M:%S %Z. --- libc/localedata/locales/cs_CZ 2006-07-31 00:19:44.000000000 +0200 +++ libc/localedata/locales/cs_CZ 2006-12-05 14:52:11.000000000 +0100 @@ -2440,9 +2440,9 @@ abmon "";/ week 7;19971201;4 -d_t_fmt "" +d_t_fmt "" -d_fmt "" +d_fmt "" t_fmt "" Jakub From drepper@redhat.com Tue Dec 5 21:26:00 2006 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 05 Dec 2006 21:26:00 -0000 Subject: [PATCH] Fix ttyname and ttyname_r In-Reply-To: <20061204131047.GG9556@sunsite.mff.cuni.cz> References: <20061204131047.GG9556@sunsite.mff.cuni.cz> Message-ID: <4575E3FD.7060804@redhat.com> Applied. -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? From drepper@redhat.com Tue Dec 5 21:27:00 2006 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 05 Dec 2006 21:27:00 -0000 Subject: [PATCH] Fix nis_getnames In-Reply-To: <20061205195208.GI9556@sunsite.mff.cuni.cz> References: <20061205195208.GI9556@sunsite.mff.cuni.cz> Message-ID: <4575E427.4040307@redhat.com> Applied. -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? From drepper@redhat.com Tue Dec 5 21:28:00 2006 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 05 Dec 2006 21:28:00 -0000 Subject: cs_CZ LC_TIME changes In-Reply-To: <20061205195457.GJ9556@sunsite.mff.cuni.cz> References: <20061205195457.GJ9556@sunsite.mff.cuni.cz> Message-ID: <4575E474.6040709@redhat.com> Applied. -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? From jakub@redhat.com Wed Dec 6 13:26:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 06 Dec 2006 13:26:00 -0000 Subject: [PATCH] Fix glibc build on s390{,x} Message-ID: <20061206132501.GK9556@sunsite.mff.cuni.cz> Hi! When asm/unistd.h contains __NR_epoll_pwait on s390/s390x, glibc fails to build. While sysdeps/unix/sysv/linux/s390/s390-{32,64}/sysdep.h has been extended some month ago to handle 6 argument syscalls, sysdep-cancel.h has not and epoll_pwait is a 6 argument cancellable syscall. 2006-12-06 Jakub Jelinek * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Handle 6 argument cancellable syscalls. (STM_6, LM_6, LR7_0, LR7_1, LR7_2, LR7_3, LR7_4, LR7_5, LR7_6): Define. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Handle 6 argument cancellable syscalls. (STM_6, LM_6, LR7_0, LR7_1, LR7_2, LR7_3, LR7_4, LR7_5, LR7_6): Define. --- libc/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h.jj 2006-10-30 00:24:40.000000000 +0100 +++ libc/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h 2006-12-06 11:58:40.000000000 +0100 @@ -45,7 +45,13 @@ L(pseudo_cancel): \ bas %r14,0(%r1,%r13); \ lr %r0,%r2; \ LM_##args \ - DO_CALL(syscall_name, args); \ + .if SYS_ify (syscall_name) < 256; \ + svc SYS_ify (syscall_name); \ + .else; \ + lhi %r1,SYS_ify (syscall_name); \ + svc 0; \ + .endif; \ + LR7_##args \ l %r1,2f-0b(%r13); \ lr %r12,%r2; \ lr %r2,%r0; \ @@ -89,6 +95,7 @@ L(pseudo_end): #define STM_3 stm %r2,%r4,8(%r15); #define STM_4 stm %r2,%r5,8(%r15); #define STM_5 stm %r2,%r5,8(%r15); +#define STM_6 stm %r2,%r7,8(%r15); #define LM_0 /* Nothing */ #define LM_1 l %r2,8+96(%r15); @@ -96,6 +103,18 @@ L(pseudo_end): #define LM_3 lm %r2,%r4,8+96(%r15); #define LM_4 lm %r2,%r5,8+96(%r15); #define LM_5 lm %r2,%r5,8+96(%r15); +#define LM_6 lm %r2,%r5,8+96(%r15); \ + cfi_offset (%r7, -68); \ + l %r7,96+96(%r15); + +#define LR7_0 /* Nothing */ +#define LR7_1 /* Nothing */ +#define LR7_2 /* Nothing */ +#define LR7_3 /* Nothing */ +#define LR7_4 /* Nothing */ +#define LR7_5 /* Nothing */ +#define LR7_6 l %r7,28+96(%r15); \ + cfi_restore (%r7); # ifndef __ASSEMBLER__ # define SINGLE_THREAD_P \ --- libc/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h.jj 2006-10-30 00:24:40.000000000 +0100 +++ libc/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h 2006-12-06 12:11:14.000000000 +0100 @@ -42,7 +42,13 @@ L(pseudo_cancel): \ brasl %r14,CENABLE; \ lgr %r0,%r2; \ LM_##args \ - DO_CALL(syscall_name, args); \ + .if SYS_ify (syscall_name) < 256; \ + svc SYS_ify (syscall_name); \ + .else; \ + lghi %r1,SYS_ify (syscall_name); \ + svc 0; \ + .endif; \ + LR7_##args \ lgr %r13,%r2; \ lgr %r2,%r0; \ brasl %r14,CDISABLE; \ @@ -85,6 +91,7 @@ L(pseudo_end): #define STM_3 stmg %r2,%r4,16(%r15); #define STM_4 stmg %r2,%r5,16(%r15); #define STM_5 stmg %r2,%r5,16(%r15); +#define STM_6 stmg %r2,%r7,16(%r15); #define LM_0 /* Nothing */ #define LM_1 lg %r2,16+160(%r15); @@ -92,6 +99,18 @@ L(pseudo_end): #define LM_3 lmg %r2,%r4,16+160(%r15); #define LM_4 lmg %r2,%r5,16+160(%r15); #define LM_5 lmg %r2,%r5,16+160(%r15); +#define LM_6 lmg %r2,%r5,16+160(%r15); \ + cfi_offset (%r7, -104); \ + lg %r7,160+160(%r15); + +#define LR7_0 /* Nothing */ +#define LR7_1 /* Nothing */ +#define LR7_2 /* Nothing */ +#define LR7_3 /* Nothing */ +#define LR7_4 /* Nothing */ +#define LR7_5 /* Nothing */ +#define LR7_6 lg %r7,56+160(%r15); \ + cfi_restore (%r7); # if defined IS_IN_libpthread || !defined NOT_IN_libc # ifndef __ASSEMBLER__ Jakub From jakub@redhat.com Fri Dec 8 09:53:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 08 Dec 2006 09:53:00 -0000 Subject: [PATCH] Fix wide stdio In-Reply-To: <456B009E.6060403@redhat.com> References: <20061124130448.GK3849@sunsite.mff.cuni.cz> <45670D02.6010402@redhat.com> <20061127140506.GN3849@sunsite.mff.cuni.cz> <456B009E.6060403@redhat.com> Message-ID: <20061208095248.GB3819@sunsite.mff.cuni.cz> On Mon, Nov 27, 2006 at 07:13:34AM -0800, Ulrich Drepper wrote: > Jakub Jelinek wrote: > >I'd like to understand what's still screwed up big time after the patch > >I posted. > > Any buffer provided must be associated with the wide char buffer for > wide streams, not the underlying temporary buffer. This requires, if > setvbuf is called before the decision is made, to move the buffer from > being used in the output buffer to being used as the wide char buffer. > Along with handling alignment issues etc this is a terribly complex change. This updated patch should handle that. It doesn't really swap the buffers (which is not necessary IMHO, no app should care about that), just sizes the wide buffer the same as how big the setvbuf buffer is. If setvbuf has not been called (and the narrow buffer is therefore libio allocated, not user allocated), it preserves the old behavior where the wide buffer has been sizeof (wchar_t) times bigger than the narrow buffer. It also fixes a bug where f = fopen ("/dev/tty", "w"); setvbuf (f, buf, _IOFBF, len); fwprintf (f, L"something"); would not honor the full buffered request, _IO_wfile_doallocate used to override it to line buffered. Also, one unneeded stat has been removed. 2006-12-08 Jakub Jelinek * libio/genops.c (__uflow): Fix a typo. * libio/wfiledoalloc.c (_IO_wfile_doallocate): Don't stat nor set _IO_LINE_BUF bit here. Size the wide buffer based on the narrow buffer size. 2006-11-24 Jakub Jelinek * libio/libio.h (_IO_FLAGS2_USER_WBUF): Define. * libio/wgenops.c (_IO_wsetb, _IO_wdefault_finish): Test and set _IO_FLAGS2_USER_WBUF bit in _flags2 instead of _IO_USER_BUF bit in _flags. * libio/wstrops.c (_IO_wstr_overflow, enlarge_userbuf, _IO_wstr_finish): Likewise. * libio/wmemstream.c (open_wmemstream): Likewise. * libio/fileops.c (_IO_new_file_close_it): Call _IO_set[bgp] even for wide streams. --- libc/libio/fileops.c 19 Jan 2006 00:38:35 -0000 1.110 +++ libc/libio/fileops.c 5 Dec 2006 15:39:22 -0000 @@ -174,14 +174,8 @@ _IO_new_file_close_it (fp) close_status = _IO_SYSCLOSE (fp); /* Free buffer. */ - if (fp->_mode <= 0) - { - INTUSE(_IO_setb) (fp, NULL, NULL, 0); - _IO_setg (fp, NULL, NULL, NULL); - _IO_setp (fp, NULL, NULL); - } #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T - else + if (fp->_mode > 0) { if (_IO_have_wbackup (fp)) INTUSE(_IO_free_wbackup_area) (fp); @@ -190,6 +184,9 @@ _IO_new_file_close_it (fp) _IO_wsetp (fp, NULL, NULL); } #endif + INTUSE(_IO_setb) (fp, NULL, NULL, 0); + _IO_setg (fp, NULL, NULL, NULL); + _IO_setp (fp, NULL, NULL); INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; --- libc/libio/genops.c 1 Mar 2006 05:32:48 -0000 1.70 +++ libc/libio/genops.c 5 Dec 2006 15:39:22 -0000 @@ -367,7 +367,7 @@ __uflow (fp) #endif if (fp->_mode == 0) - _IO_fwide (fp, -11); + _IO_fwide (fp, -1); if (_IO_in_put_mode (fp)) if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF) return EOF; --- libc/libio/libio.h 14 Jan 2006 12:09:46 -0000 1.64 +++ libc/libio/libio.h 5 Dec 2006 15:39:22 -0000 @@ -142,6 +142,7 @@ #ifdef _LIBC # define _IO_FLAGS2_FORTIFY 4 #endif +#define _IO_FLAGS2_USER_WBUF 8 /* These are "formatting flags" matching the iostream fmtflags enum values. */ #define _IO_SKIPWS 01 --- libc/libio/wfiledoalloc.c 6 Jul 2002 06:35:54 -0000 1.6 +++ libc/libio/wfiledoalloc.c 5 Dec 2006 15:39:22 -0000 @@ -1,4 +1,5 @@ -/* Copyright (C) 1993, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1999, 2000, 2002, 2006 + 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 @@ -85,35 +86,20 @@ _IO_wfile_doallocate (fp) _IO_FILE *fp; { _IO_size_t size; - int couldbetty; wchar_t *p; - struct _G_stat64 st; /* Allocate room for the external buffer. */ if (fp->_IO_buf_base == NULL) INTUSE(_IO_file_doallocate) (fp); - if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0) - { - couldbetty = 0; - size = _IO_BUFSIZ; -#if 0 - /* do not try to optimise fseek() */ - fp->_flags |= __SNPT; -#endif - } - else - { - couldbetty = S_ISCHR (st.st_mode); -#if _IO_HAVE_ST_BLKSIZE - size = st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize; -#else - size = _IO_BUFSIZ; -#endif - } + /* If narrow buffer is user allocated (set by setvbuf etc.), + use that size as the size of the wide buffer, when it is + allocated by _IO_file_doallocate, multiply that by size + of the wide character. */ + size = fp->_IO_buf_end - fp->_IO_buf_base; + if ((fp->_flags & _IO_USER_BUF)) + size = (size + sizeof (wchar_t) - 1) / sizeof (wchar_t); ALLOC_WBUF (p, size * sizeof (wchar_t), EOF); INTUSE(_IO_wsetb) (fp, p, p + size, 1); - if (couldbetty && isatty (fp->_fileno)) - fp->_flags |= _IO_LINE_BUF; return 1; } --- libc/libio/wgenops.c 12 Feb 2006 21:20:57 -0000 1.14 +++ libc/libio/wgenops.c 5 Dec 2006 15:39:22 -0000 @@ -115,14 +115,14 @@ _IO_wsetb (f, b, eb, a) wchar_t *eb; int a; { - if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) + if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF)) FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t)); f->_wide_data->_IO_buf_base = b; f->_wide_data->_IO_buf_end = eb; if (a) - f->_flags &= ~_IO_USER_BUF; + f->_flags2 &= ~_IO_FLAGS2_USER_WBUF; else - f->_flags |= _IO_USER_BUF; + f->_flags2 |= _IO_FLAGS2_USER_WBUF; } INTDEF(_IO_wsetb) @@ -198,7 +198,7 @@ _IO_wdefault_finish (fp, dummy) int dummy; { struct _IO_marker *mark; - if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) { FREE_BUF (fp->_wide_data->_IO_buf_base, _IO_wblen (fp) * sizeof (wchar_t)); --- libc/libio/wmemstream.c 30 Sep 2006 00:06:33 -0000 1.3 +++ libc/libio/wmemstream.c 5 Dec 2006 15:39:22 -0000 @@ -92,7 +92,7 @@ open_wmemstream (bufloc, sizeloc) _IO_fwide (&new_f->fp._sf._sbf._f, 1); _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf, _IO_BUFSIZ / sizeof (wchar_t), buf); - new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF; + new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF; new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc; new_f->fp._sf._s._free_buffer = (_IO_free_type) free; --- libc/libio/wstrops.c 14 Aug 2006 22:14:53 -0000 1.11 +++ libc/libio/wstrops.c 5 Dec 2006 15:39:22 -0000 @@ -88,7 +88,7 @@ _IO_wstr_overflow (fp, c) pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only)) { - if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ + if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* not allowed to enlarge */ return WEOF; else { @@ -182,7 +182,7 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64 _IO_ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base; /* Try to enlarge the buffer. */ - if (fp->_flags & _IO_USER_BUF) + if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* User-provided buffer. */ return 1; @@ -335,7 +335,7 @@ _IO_wstr_finish (fp, dummy) _IO_FILE *fp; int dummy; { - if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base); fp->_wide_data->_IO_buf_base = NULL; Jakub From jakub@redhat.com Sat Dec 9 10:01:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Sat, 09 Dec 2006 10:01:00 -0000 Subject: [PATCH] Fix hasmntopt Message-ID: <20061209100103.GC3819@sunsite.mff.cuni.cz> Hi! As the attached testcase shows, hasmntopt wrongly returns a match even if opt option is not present in the list, but some longer option with opt prefix is. Furthermore, it unnecessarily restarts searching for comma at rest, while there can't be any further matches between rest and p. 2006-12-09 Jakub Jelinek * misc/mntent_r.c (__hasmntopt): Check p[optlen] even when p == rest. Start searching for next comma at p rather than rest. * misc/Makefile (tests): Add tst-mntent2. * misc/tst-mntent2.c: New test. --- libc/misc/mntent_r.c.jj 2003-12-18 00:29:02.000000000 +0100 +++ libc/misc/mntent_r.c 2006-12-09 01:19:43.000000000 +0100 @@ -1,5 +1,6 @@ /* Utilities for reading/writing fstab, mtab, etc. - Copyright (C) 1995-2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 + 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 @@ -278,14 +279,11 @@ __hasmntopt (const struct mntent *mnt, c while ((p = strstr (rest, opt)) != NULL) { - if (p == rest - || (p[-1] == ',' - && (p[optlen] == '\0' || - p[optlen] == '=' || - p[optlen] == ','))) + if ((p == rest || p[-1] == ',') + && (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ',')) return p; - rest = strchr (rest, ','); + rest = strchr (p, ','); if (rest == NULL) break; ++rest; --- libc/misc/Makefile.jj 2006-06-17 19:00:58.000000000 +0200 +++ libc/misc/Makefile 2006-12-09 10:38:11.000000000 +0100 @@ -78,7 +78,7 @@ endif gpl2lgpl := error.c error.h tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ - tst-error1 tst-pselect tst-insremque + tst-error1 tst-pselect tst-insremque tst-mntent2 ifeq (no,$(cross-compiling)) tests: $(objpfx)tst-error1-mem endif --- libc/misc/tst-mntent2.c.jj 2006-12-09 10:25:10.000000000 +0100 +++ libc/misc/tst-mntent2.c 2006-12-09 10:35:42.000000000 +0100 @@ -0,0 +1,41 @@ +#include +#include +#include + + +int +main (void) +{ + int result = 0; + struct mntent mef; + + mef.mnt_fsname = strdupa ("/dev/sdf6"); + mef.mnt_dir = strdupa ("/some dir"); + mef.mnt_type = strdupa ("ext3"); + mef.mnt_opts = strdupa ("opt1,opt2,noopt=6,rw,norw,brw"); + mef.mnt_freq = 1; + mef.mnt_passno = 2; + +#define TEST(opt, found) \ + if (!!hasmntopt (&mef, (opt)) != (found)) \ + { \ + printf ("Option %s was %sfound\n", (opt), (found) ? "not " : ""); \ + result = 1; \ + } + + TEST ("opt1", 1) + TEST ("opt2", 1) + TEST ("noopt", 1) + TEST ("rw", 1) + TEST ("norw", 1) + TEST ("brw", 1) + TEST ("opt", 0) + TEST ("oopt", 0) + TEST ("w", 0) + TEST ("r", 0) + TEST ("br", 0) + TEST ("nor", 0) + TEST ("or", 0) + + return result; +} Jakub From jakub@redhat.com Sat Dec 9 12:08:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Sat, 09 Dec 2006 12:08:00 -0000 Subject: [PATCH] Fix initshells Message-ID: <20061209120814.GD3819@sunsite.mff.cuni.cz> Hi! If /etc/shells ends with an empty line, initshells ends with an endless loop (because fgets with length 1 always succeeds, doesn't need to read anything from the file, just stores '\0'). In addition to this if /etc/shells contains e.g. / / / / / / / / then setusershell (); endusershell (); causes heap corruption. I'm attaching two patches, some fixes are common to both patches, but they differ in how the endless loop with empty newline at end is solved. P3 adds an extra condition to the loop, P5 increases the strings buffer by one byte, so that fgets itself cures this. I have also coded up a third solution, as we never shrink the strings buffer, we might as well just fread the whole file into the strings buffer and instead of fgets simply look for '\n's in it. While that is tiny bit more efficient, it compiled into bigger code (on x86-64) and I believe for this type of functions smaller code is better code. Jakub -------------- next part -------------- 2006-12-09 Jakub Jelinek * misc/getusershell.c (initshells): Check for integer overflows. Avoid endless loop if /etc/shells ends with an empty line. Don't use calloc for shells array. Disallow / as shell. --- libc/misc/getusershell.c.jj 2006-05-15 20:56:36.000000000 +0200 +++ libc/misc/getusershell.c 2006-12-09 12:16:30.000000000 +0100 @@ -98,7 +98,7 @@ initshells() register char **sp, *cp; register FILE *fp; struct stat64 statb; - int flen; + size_t flen; free(shells); shells = NULL; @@ -114,9 +114,11 @@ initshells() okshells[1] = _PATH_CSHELL; return (char **) okshells; } - if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) + if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3) goto init_okshells; - shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); + if ((strings = malloc(statb.st_size + 1)) == NULL) + goto init_okshells; + shells = malloc(statb.st_size / 3 * sizeof (char *)); if (shells == NULL) { free(strings); strings = NULL; @@ -124,11 +126,12 @@ initshells() } sp = shells; cp = strings; - flen = statb.st_size; - while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) { + flen = statb.st_size + 1; + while (cp < strings + flen - 1 + && fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) { while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; - if (*cp == '#' || *cp == '\0') + if (*cp == '#' || *cp == '\0' || cp[1] == '\0') continue; *sp++ = cp; while (!isspace(*cp) && *cp != '#' && *cp != '\0') -------------- next part -------------- 2006-12-09 Jakub Jelinek * misc/getusershell.c (initshells): Check for integer overflows. Make strings buffer one bigger as fgets always succeeds when second argument is 1. Don't use calloc for shells array. Disallow / as shell. --- libc/misc/getusershell.c.jj 2006-05-15 20:56:36.000000000 +0200 +++ libc/misc/getusershell.c 2006-12-09 12:53:05.000000000 +0100 @@ -98,7 +98,7 @@ initshells() register char **sp, *cp; register FILE *fp; struct stat64 statb; - int flen; + size_t flen; free(shells); shells = NULL; @@ -114,9 +114,11 @@ initshells() okshells[1] = _PATH_CSHELL; return (char **) okshells; } - if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) + if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3) goto init_okshells; - shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); + if ((strings = malloc(statb.st_size + 2)) == NULL) + goto init_okshells; + shells = malloc(statb.st_size / 3 * sizeof (char *)); if (shells == NULL) { free(strings); strings = NULL; @@ -124,11 +126,11 @@ initshells() } sp = shells; cp = strings; - flen = statb.st_size; + flen = statb.st_size + 2; while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) { while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; - if (*cp == '#' || *cp == '\0') + if (*cp == '#' || *cp == '\0' || cp[1] == '\0') continue; *sp++ = cp; while (!isspace(*cp) && *cp != '#' && *cp != '\0') From drepper@redhat.com Wed Dec 13 23:20:00 2006 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 13 Dec 2006 23:20:00 -0000 Subject: [PATCH] Fix wide stdio In-Reply-To: <20061208095248.GB3819@sunsite.mff.cuni.cz> References: <20061124130448.GK3849@sunsite.mff.cuni.cz> <45670D02.6010402@redhat.com> <20061127140506.GN3849@sunsite.mff.cuni.cz> <456B009E.6060403@redhat.com> <20061208095248.GB3819@sunsite.mff.cuni.cz> Message-ID: <45808AA8.1020507@redhat.com> I don't particularly like the patch since I think the wide buffer should be controlled by the user. But a) it's a lot of work and I don't foresee having time for something as unimportant as this and b) nobody really cares about this (the effects should be opaque) If and when the opportunity arrives to make the correct fix it can be made on top of the new code. -- ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA ??? From jakub@redhat.com Thu Dec 14 17:20:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 14 Dec 2006 17:20:00 -0000 Subject: [PATCH] Fix tst-pselect failure handling Message-ID: <20061214172036.GJ3819@sunsite.mff.cuni.cz> Hi! When tst-pselect.c fails (quite often when running on kernel that doesn't have pselect6 syscall, because pselect is then not atomic, but even 2.6.18 x86_64 kernel it fails rather quickly with pselect6 syscall when running while misc/tst-pselect; do :; done), test-skeleton.c only kills its immediate child, while the other child sticks around forever. The following patch is one possibility to avoid this: 2006-12-14 Jakub Jelinek * misc/tst-pselect.c (do_test): Break the child loop if parent was killed by timeout handler. --- libc/misc/tst-pselect.c.jj 2006-09-18 09:11:59.000000000 +0200 +++ libc/misc/tst-pselect.c 2006-12-14 16:35:33.000000000 +0100 @@ -61,12 +61,15 @@ do_test (void) FD_SET (fds[0][0], &rfds); int e; + /* Break the loop if our parent is killed by test-skeleton.c's + timeout handler. */ + pid_t ppid = getppid (); do { errno = 0; e = pselect (fds[0][0] + 1, &rfds, NULL, NULL, &to, &ss); } - while (e == 0); + while (e == 0 && getppid () == ppid); if (e != -1) { Jakub From jakub@redhat.com Thu Dec 14 18:47:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 14 Dec 2006 18:47:00 -0000 Subject: [PATCH] One more tst-pselect fix Message-ID: <20061214184706.GK3819@sunsite.mff.cuni.cz> Hi! The reason why tst-pselect fails even with pselect6 syscall seems to be incorrect use of sigblock, sigblock's argument is an old style signal mask, not the signal itself. 2006-12-14 Jakub Jelinek * misc/tst-pselect.c (do_test): Fix sigblock argument. --- libc/misc/tst-pselect.c.jj 2006-12-14 19:24:23.000000000 +0100 +++ libc/misc/tst-pselect.c 2006-12-14 19:44:45.000000000 +0100 @@ -38,7 +38,7 @@ do_test (void) return 1; } - if (sigblock (SIGUSR1) != 0) + if (sigblock (sigmask (SIGUSR1)) != 0) { puts ("sigblock failed"); return 1; Jakub From jakub@redhat.com Mon Dec 18 11:41:00 2006 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 18 Dec 2006 11:41:00 -0000 Subject: [PATCH] Fix {j,m}rand48{,_r} (BZ #3747) Message-ID: <20061218114136.GL3819@sunsite.mff.cuni.cz> Hi! http://www.opengroup.org/onlinepubs/009695399/functions/drand48.html requires: "The mrand48() and jrand48() functions shall return signed long integers uniformly distributed over the interval [-2^31,2^31)." We do that on 32-bit arches, but on 64-bit architectures we return signed long integers uniformly distributed over the interval [0,2^32). Fixed thusly: 2006-12-18 Jakub Jelinek [BZ #3747] * stdlib/jrand48_r.c (__jrand48_r): Make sure result is in the [-2^31 .. 2^31) range. * stdlib/tst-rand48.c (main): Fix expected values for 64-bit targets. * stdlib/tst-rand48-2.c: New test. * stdlib/Makefile (tests): Add tst-rand48-2. --- libc/stdlib/jrand48_r.c.jj 2001-07-06 06:55:41.000000000 +0200 +++ libc/stdlib/jrand48_r.c 2006-12-18 11:46:57.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1995, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1997, 1998, 2001, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , August 1995. @@ -30,7 +30,7 @@ __jrand48_r (xsubi, buffer, result) return -1; /* Store the result. */ - *result = ((xsubi[2] << 16) | xsubi[1]) & 0xffffffffl; + *result = (int32_t) ((xsubi[2] << 16) | xsubi[1]); return 0; } --- libc/stdlib/Makefile.jj 2006-12-11 21:34:14.000000000 +0100 +++ libc/stdlib/Makefile 2006-12-18 12:22:20.000000000 +0100 @@ -67,7 +67,7 @@ tests := tst-strtol tst-strtod testmb t tst-xpg-basename tst-random tst-random2 tst-bsearch \ tst-limits tst-rand48 bug-strtod tst-setcontext \ test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ - tst-atof1 tst-atof2 tst-strtod2 + tst-atof1 tst-atof2 tst-strtod2 tst-rand48-2 include ../Makeconfig --- libc/stdlib/tst-rand48.c.jj 2001-01-20 04:32:19.000000000 +0100 +++ libc/stdlib/tst-rand48.c 2006-12-18 12:33:59.000000000 +0100 @@ -44,10 +44,10 @@ main (void) } l = mrand48 (); - if (l != 0xa28c1003l) + if (l != -0x5d73effdl) { printf ("mrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0xa28c1003l, l); + __LINE__ - 4, -0x5d73effdl, l); result = 1; } @@ -60,10 +60,10 @@ main (void) } l = mrand48 (); - if (l != 0x9e88f474l) + if (l != -0x61770b8cl) { printf ("mrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0x9e88f474l, l); + __LINE__ - 4, -0x61770b8cl, l); result = 1; } @@ -92,10 +92,10 @@ main (void) } l = mrand48 (); - if (l != 0xeb7a1fa3l) + if (l != -0x1485e05dl) { printf ("mrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0xeb7a1fa3l, l); + __LINE__ - 4, -0x1485e05dl, l); result = 1; } @@ -171,10 +171,10 @@ main (void) } l = mrand48 (); - if (l != 0xa28c1003l) + if (l != -0x5d73effdl) { printf ("mrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0xa28c1003l, l); + __LINE__ - 4, -0x5d73effdl, l); result = 1; } @@ -187,10 +187,10 @@ main (void) } l = mrand48 (); - if (l != 0x9e88f474l) + if (l != -0x61770b8cl) { printf ("mrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0x9e88f474l, l); + __LINE__ - 4, -0x61770b8cl, l); result = 1; } @@ -231,10 +231,10 @@ main (void) } l = mrand48 (); - if (l != 0xeb7a1fa3l) + if (l != -0x1485e05dl) { printf ("mrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0xeb7a1fa3l, l); + __LINE__ - 4, -0x1485e05dl, l); result = 1; } @@ -287,10 +287,10 @@ main (void) } l = jrand48 (xs); - if (l != 0xf568c7a0l) + if (l != -0xa973860l) { printf ("jrand48() in line %d failed: expected %lx, seen %lx\n", - __LINE__ - 4, 0xf568c7a0l, l); + __LINE__ - 4, -0xa973860l, l); result = 1; } --- libc/stdlib/tst-rand48-2.c.jj 2006-12-18 12:12:01.000000000 +0100 +++ libc/stdlib/tst-rand48-2.c 2006-12-18 12:20:26.000000000 +0100 @@ -0,0 +1,113 @@ +#include +#include +#include +#include + +int +main (void) +{ + time_t t = time (NULL); + int i, ret = 0; + double d; + long int l; + struct drand48_data data; + unsigned short int buf[3]; + + srand48 ((long int) t); + for (i = 0; i < 50; i++) + if ((d = drand48 ()) < 0.0 || d >= 1.0) + { + printf ("drand48 %d %g\n", i, d); + ret = 1; + } + + srand48_r ((long int) t, &data); + for (i = 0; i < 50; i++) + if (drand48_r (&data, &d) != 0 || d < 0.0 || d >= 1.0) + { + printf ("drand48_r %d %g\n", i, d); + ret = 1; + } + + buf[2] = (t & 0xffff0000) >> 16; buf[1] = (t & 0xffff); buf[0] = 0x330e; + for (i = 0; i < 50; i++) + if ((d = erand48 (buf)) < 0.0 || d >= 1.0) + { + printf ("erand48 %d %g\n", i, d); + ret = 1; + } + + buf[2] = (t & 0xffff0000) >> 16; buf[1] = (t & 0xffff); buf[0] = 0x330e; + for (i = 0; i < 50; i++) + if (erand48_r (buf, &data, &d) != 0 || d < 0.0 || d >= 1.0) + { + printf ("erand48_r %d %g\n", i, d); + ret = 1; + } + + srand48 ((long int) t); + for (i = 0; i < 50; i++) + if ((l = lrand48 ()) < 0 || l > INT32_MAX) + { + printf ("lrand48 %d %ld\n", i, l); + ret = 1; + } + + srand48_r ((long int) t, &data); + for (i = 0; i < 50; i++) + if (lrand48_r (&data, &l) != 0 || l < 0 || l > INT32_MAX) + { + printf ("lrand48_r %d %ld\n", i, l); + ret = 1; + } + + buf[2] = (t & 0xffff0000) >> 16; buf[1] = (t & 0xffff); buf[0] = 0x330e; + for (i = 0; i < 50; i++) + if ((l = nrand48 (buf)) < 0 || l > INT32_MAX) + { + printf ("nrand48 %d %ld\n", i, l); + ret = 1; + } + + buf[2] = (t & 0xffff0000) >> 16; buf[1] = (t & 0xffff); buf[0] = 0x330e; + for (i = 0; i < 50; i++) + if (nrand48_r (buf, &data, &l) != 0 || l < 0 || l > INT32_MAX) + { + printf ("nrand48_r %d %ld\n", i, l); + ret = 1; + } + + srand48 ((long int) t); + for (i = 0; i < 50; i++) + if ((l = mrand48 ()) < INT32_MIN || l > INT32_MAX) + { + printf ("mrand48 %d %ld\n", i, l); + ret = 1; + } + + srand48_r ((long int) t, &data); + for (i = 0; i < 50; i++) + if (mrand48_r (&data, &l) != 0 || l < INT32_MIN || l > INT32_MAX) + { + printf ("mrand48_r %d %ld\n", i, l); + ret = 1; + } + + buf[2] = (t & 0xffff0000) >> 16; buf[1] = (t & 0xffff); buf[0] = 0x330e; + for (i = 0; i < 50; i++) + if ((l = jrand48 (buf)) < INT32_MIN || l > INT32_MAX) + { + printf ("jrand48 %d %ld\n", i, l); + ret = 1; + } + + buf[2] = (t & 0xffff0000) >> 16; buf[1] = (t & 0xffff); buf[0] = 0x330e; + for (i = 0; i < 50; i++) + if (jrand48_r (buf, &data, &l) != 0 || l < INT32_MIN || l > INT32_MAX) + { + printf ("jrand48_r %d %ld\n", i, l); + ret = 1; + } + + return ret; +} Jakub