X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Recipient: djgpp AT delorie DOT com Message-ID: <57169780.10702@gmx.de> Date: Tue, 19 Apr 2016 22:39:28 +0200 From: "Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via djgpp AT delorie DOT com]" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.13) Gecko/20101206 SUSE/3.1.7 Thunderbird/3.1.7 MIME-Version: 1.0 To: djgpp AT delorie DOT com Subject: Re: Different dup2 behaviour between DOS/DJGPP and posix. References: <5706CAFA DOT 1060201 AT gmx DOT de> <5706E3D9 DOT 9070401 AT gmx DOT de> <57091A44 DOT 1090309 AT gmx DOT de> In-Reply-To: <57091A44.1090309@gmx.de> Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:N+KpSwdjQiHrPdEuDW/KPG1hpi27xEf7GRF+b6npuZmAPc/uck9 5yd9ahkr3+QrS0YEPbdAMUhy+bBEKBDPsYDj5xD1gWAEy54JeMZccm7vVA8lrM02I3x622p Iau5Q9Q7uzUU6iUX8iHdTe1wxHQo7qEy3f/AuB/0+sjVTOhsVbC++iHv2t76LpRfAgq2aHO cUXl8Cp9ZEQGk6sMX4caQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:EVtS0Dpx5as=:N5RfIjsYxfaydo/vr7UX9Q zbb5qnXLaQY2/vLcTeAqPb13DtU8AS4T6pGZ9bHkUaR1vw5emfvkWZhvt8Oqdg+yKGaDkYOZt 2WP4IkKuETU8g+HBMTnQyYtf9B01IX8ekzV5sUIjXoHAoVH9fYLQbKHV/fROzHo51N3sV3QQl 4kG62UBjIvwTQtlDbMCBxGNg3YQ2U7dEBKTPeH+ZoMOUT8GIBC+ISiZAB2TaAtQaoQhHPVWoM drR6YnNDazsA1qF0LbJy3QXBaf13ck1rBm0VFJ4qrZcDl2HeJYYwVVJCyBAI7/GZztG5qUJv8 unITaGTO0F5KAH2Sr2RDdqFo7+PjJb+HiMGvN9DfJbnydb16reBRzCH7Wf4IXHz9uLkEIIGeW 2TLZ1I6f4O4AAYkS3Ix9+MOGZ8GyYpmH3HosnhcYw81AcIxCOhocSxqbyYVISwnSu7txVqXQh CrYf2TwTnrCEJzu8mA5gU/vQ3Wd/HFfC4shKScyDcLQhVDYUBy0vpH2kqOL1I9lDmI6FM2mD4 KfQ2Vq81no37G0FN3RhBmmTVMWeTCPIYzeUiL84clL8ap7UrWZrTTeNMPtrpXKwKNEVo7mmdo juUuD87qHf4OINyeW65Rle+GTr2IMd7GlLQUNtGITPU/pccIVGrjp62xnsJneRvP0yKsk2Aub YY647+V1+yJaFhTRDAj1pHcnxUpkC1Vr59tbss1CWpSNkr7g2yIotLJ2MjNbFX5ss2L50Z+xA SqqHwfAlR0x/mxasQjro68+3vCc2DlgEKrbi0vqQmVJzLRuwirxyYD5opdD0yE3MJCH1sf/xI F1l8c/r Reply-To: djgpp AT delorie DOT com Am 09.04.2016 17:05, schrieb Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via djgpp AT delorie DOT com]: > Am 08.04.2016 00:48, schrieb Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via djgpp AT delorie DOT com]: >> Am 07.04.2016 23:02, schrieb Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via djgpp AT delorie DOT com]: >> [snip] >>> The question is why DOS/DJGPP allows to close STDIN and reopen it with FD 0 >>> meanwhile posix seems not to allow this. Is this behaviour expected? >>> I have inspected the code of dup2 and the implementation seems OK. >>> >>> The consequence of this check is that Autoconf assumes that DJGPP's dup2 >>> implementaion does not work. >> >> >> OK I think I have got it. It is a bug in the DJGPP implementation of dup2. >> According to http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html >> The dup2() function shall fail if: >> >> [EBADF] >> The fildes argument is not a valid open file descriptor or the argument fildes2 is negative or greater than or equal to {OPEN_MAX}. >> >> >> The current implementation checks first if fd == newfd and if this is the case >> it returns inmediatly with newfd. Here some fix will be required because no one >> of the 3 conditions are checked. May be these error conditions were not in effect >> in those days when dup2 was implemented. >> >> >> Regards, >> Juan M. Guerrero > > > I have implemented a small fix that shall check for the validity of the > passed file descriptors to dup2. This change should increase the posix > compliance of the dup2 implementation a little bit. I have also added > a small check program that performs the same checks than the autoconf > check that called my attention to this issue. > > As usual suggestions, objections and comments are welcome. If I do not > get a response in a rasonable period of time I will commit the changes > to the repository. > OFYI, I have committed the patch below. Regards, Juan M. Guerrero Index: djgpp/src/docs/kb/wc.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc.txi,v retrieving revision 1.5 diff -U 5 -r1.5 wc.txi --- djgpp/src/docs/kb/wc.txi 3 May 2015 10:14:56 -0000 1.5 +++ djgpp/src/docs/kb/wc.txi 19 Apr 2016 20:15:41 -0000 @@ -1,18 +1,20 @@ @node What Changed, Known Bugs, Introduction, Top @chapter What Changed @menu -* Changes in 2.01:: DJGPP 2.01 -* Changes in 2.02:: DJGPP 2.02 -* Changes in 2.03:: DJGPP 2.03 -* Changes in 2.04:: DJGPP 2.04 -* Changes in 2.05:: DJGPP 2.05 +* Changes in 2.01:: DJGPP 2.01 +* Changes in 2.02:: DJGPP 2.02 +* Changes in 2.03:: DJGPP 2.03 +* Changes in 2.04:: DJGPP 2.04 +* Changes in 2.05:: DJGPP 2.05 +* Changes in 2.06:: DJGPP 2.06 @end menu @include wc201.txi @include wc202.txi @include wc203.txi @include wc204.txi @include wc205.txi +@include wc206.txi Index: djgpp/src/docs/kb/wc205.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc205.txi,v retrieving revision 1.15 diff -U 5 -r1.15 wc205.txiOFYI, I have committed the patch below. Regards, Juan M. Guerrero Index: djgpp/src/docs/kb/wc.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc.txi,v retrieving revision 1.5 diff -U 5 -r1.5 wc.txi --- djgpp/src/docs/kb/wc.txi 3 May 2015 10:14:56 -0000 1.5 +++ djgpp/src/docs/kb/wc.txi 19 Apr 2016 20:15:41 -0000 @@ -1,18 +1,20 @@ @node What Changed, Known Bugs, Introduction, Top @chapter What Changed @menu -* Changes in 2.01:: DJGPP 2.01 -* Changes in 2.02:: DJGPP 2.02 -* Changes in 2.03:: DJGPP 2.03 -* Changes in 2.04:: DJGPP 2.04 -* Changes in 2.05:: DJGPP 2.05 +* Changes in 2.01:: DJGPP 2.01 +* Changes in 2.02:: DJGPP 2.02 +* Changes in 2.03:: DJGPP 2.03 +* Changes in 2.04:: DJGPP 2.04 +* Changes in 2.05:: DJGPP 2.05 +* Changes in 2.06:: DJGPP 2.06 @end menu @include wc201.txi @include wc202.txi @include wc203.txi @include wc204.txi @include wc205.txi +@include wc206.txi Index: djgpp/src/docs/kb/wc205.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc205.txi,v retrieving revision 1.15 diff -U 5 -r1.15 wc205.txi --- djgpp/src/docs/kb/wc205.txi 23 Aug 2015 14:27:40 -0000 1.15 +++ djgpp/src/docs/kb/wc205.txi 19 Apr 2016 20:15:41 -0000 @@ -1,6 +1,6 @@ -@node Changes in 2.05, , Changes in 2.04, What Changed +@node Changes in 2.05, Changes in 2.06, Changes in 2.04, What Changed @section Changes in 2.05 Here is a list of changes from DJGPP V2.04 to DJGPP V2.05 DJGPP v2.04 was actually never released and stayed in beta stage much too Index: djgpp/src/libc/posix/unistd/dup2.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/dup2.c,v retrieving revision 1.6 diff -U 5 -r1.6 dup2.c --- djgpp/src/libc/posix/unistd/dup2.c 19 Aug 2001 16:50:26 -0000 1.6 +++ djgpp/src/libc/posix/unistd/dup2.c 19 Apr 2016 20:15:41 -0000 @@ -1,5 +1,6 @@ +/* Copyright (C) 2016 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include @@ -13,12 +14,20 @@ int dup2(int fd, int newfd) { __dpmi_regs r; + + if (newfd < 0 || newfd >= getdtablesize() || _get_dev_info(fd) == -1) + { + errno = EBADF; + return -1; + } + if (fd == newfd) return newfd; + /* Reset the text/binary modes, the fsext, and the properties, since DOS function 46h closes newfd. */ __file_handle_set(newfd, __file_handle_modes[fd] ^ (O_BINARY|O_TEXT)); __FSEXT_set_function(newfd, 0); r.h.ah = 0x46; Index: djgpp/src/libc/posix/unistd/dup2.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/dup2.txh,v retrieving revision 1.3 diff -U 5 -r1.3 dup2.txh --- djgpp/src/libc/posix/unistd/dup2.txh 29 Jan 2003 12:51:41 -0000 1.3 +++ djgpp/src/libc/posix/unistd/dup2.txh 19 Apr 2016 20:15:41 -0000 @@ -10,19 +10,21 @@ @subheading Description This call causes @var{new_handle} to refer to the same file and file pointer as @var{existing_handle}. If @var{new_handle} is an open file, -it is closed. +it is closed. If @var{existing_handle} is not a valid open file descriptor +or if @var{new_handle} out of the allowed range for file descriptors the +call will fail and @code{errno} will be set to @code{EBADF}. @subheading Return Value The new handle, or -1 on error. @subheading Portability -@portability !ansi, posix +@portability !ansi, posix-1003.1-2001 @subheading Example @example /* copy new file to stdin stream */ Index: djgpp/tests/libc/posix/unistd/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/posix/unistd/makefile,v retrieving revision 1.6 diff -U 5 -r1.6 makefile --- djgpp/tests/libc/posix/unistd/makefile 26 Mar 2003 19:50:55 -0000 1.6 +++ djgpp/tests/libc/posix/unistd/makefile 19 Apr 2016 20:15:42 -0000 @@ -1,10 +1,11 @@ TOP=../.. SRC += access.c SRC += append.c SRC += chdr.c +SRC += dup2.c SRC += gcwd.c SRC += getpid.c SRC += sleep.c SRC += tread.c SRC += write.c diff -aprNU7 djgpp.orig/src/docs/kb/wc206.txi djgpp/src/docs/kb/wc206.txi --- djgpp.orig/src/docs/kb/wc206.txi 1969-12-31 18:50:25 -0509 +++ djgpp/src/docs/kb/wc206.txi 2016-04-16 17:02:34 -0509 @@ -0,0 +1,12 @@ +@node Changes in 2.06, , Changes in 2.05, What Changed +@section Changes in 2.06 + +Here is a list of changes from DJGPP V2.05 to DJGPP V2.06 + +@findex dup2 AT r{, and POSIX.1-2001 compliance} +The validity of the file descriptors passed to @code{dup2} is now checked. +If @var{existing_handle} is not a valid open file descriptor or +if @var{new_handle} is out of the allowed range for file descriptors +the call of @code{dup2} will fail and @code{errno} will be set to @code{EBADF}. +With this adjustment, the @acronym{Posix} compliance of the @code{dup2} implementation +is increased. diff -aprNU7 djgpp.orig/tests/libc/posix/unistd/dup2.c djgpp/tests/libc/posix/unistd/dup2.c --- djgpp.orig/tests/libc/posix/unistd/dup2.c 1969-12-31 18:50:25 -0509 +++ djgpp/tests/libc/posix/unistd/dup2.c 2016-04-18 19:15:52 -0509 @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + + +int main (void) +{ + int result = 0; + int bad_fd = INT_MAX; + struct rlimit rlim; + + + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX) + bad_fd = rlim.rlim_cur; + + if (dup2(1, 1) != 1) + result |= 1; + + close(0); + if (dup2(0, 0) != -1) + result |= 2; + + if (dup2(2, bad_fd) == -1 && errno != EBADF) + result |= 4; + + if (dup2(2, -1) != -1 && errno != EBADF) + result |= 8; + + if (dup2(2, bad_fd - 1) != bad_fd -1) + result |= 16; + if (dup2(2, bad_fd) != -1) + result |= 32; + + { + int fd = open(".", O_RDONLY); + if (fd == -1) + result |= 64; + else if (dup2(fd, fd + 1) == -1) + result |= 128; + + close(fd); + } + + if (result) + printf("dup2 check failed with result = %d\n", result); + else + printf("dup2 check passed.\n"); + + return result; +} --- djgpp/src/docs/kb/wc205.txi 23 Aug 2015 14:27:40 -0000 1.15 +++ djgpp/src/docs/kb/wc205.txi 19 Apr 2016 20:15:41 -0000 @@ -1,6 +1,6 @@ -@node Changes in 2.05, , Changes in 2.04, What Changed +@node Changes in 2.05, Changes in 2.06, Changes in 2.04, What Changed @section Changes in 2.05 Here is a list of changes from DJGPP V2.04 to DJGPP V2.05 DJGPP v2.04 was actually never released and stayed in beta stage much too Index: djgpp/src/libc/posix/unistd/dup2.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/dup2.c,v retrieving revision 1.6 diff -U 5 -r1.6 dup2.c --- djgpp/src/libc/posix/unistd/dup2.c 19 Aug 2001 16:50:26 -0000 1.6 +++ djgpp/src/libc/posix/unistd/dup2.c 19 Apr 2016 20:15:41 -0000 @@ -1,5 +1,6 @@ +/* Copyright (C) 2016 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include @@ -13,12 +14,20 @@ int dup2(int fd, int newfd) { __dpmi_regs r; + + if (newfd < 0 || newfd >= getdtablesize() || _get_dev_info(fd) == -1) + { + errno = EBADF; + return -1; + } + if (fd == newfd) return newfd; + /* Reset the text/binary modes, the fsext, and the properties, since DOS function 46h closes newfd. */ __file_handle_set(newfd, __file_handle_modes[fd] ^ (O_BINARY|O_TEXT)); __FSEXT_set_function(newfd, 0); r.h.ah = 0x46; Index: djgpp/src/libc/posix/unistd/dup2.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/dup2.txh,v retrieving revision 1.3 diff -U 5 -r1.3 dup2.txh --- djgpp/src/libc/posix/unistd/dup2.txh 29 Jan 2003 12:51:41 -0000 1.3 +++ djgpp/src/libc/posix/unistd/dup2.txh 19 Apr 2016 20:15:41 -0000 @@ -10,19 +10,21 @@ @subheading Description This call causes @var{new_handle} to refer to the same file and file pointer as @var{existing_handle}. If @var{new_handle} is an open file, -it is closed. +it is closed. If @var{existing_handle} is not a valid open file descriptor +or if @var{new_handle} out of the allowed range for file descriptors the +call will fail and @code{errno} will be set to @code{EBADF}. @subheading Return Value The new handle, or -1 on error. @subheading Portability -@portability !ansi, posix +@portability !ansi, posix-1003.1-2001 @subheading Example @example /* copy new file to stdin stream */ Index: djgpp/tests/libc/posix/unistd/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/posix/unistd/makefile,v retrieving revision 1.6 diff -U 5 -r1.6 makefile --- djgpp/tests/libc/posix/unistd/makefile 26 Mar 2003 19:50:55 -0000 1.6 +++ djgpp/tests/libc/posix/unistd/makefile 19 Apr 2016 20:15:42 -0000 @@ -1,10 +1,11 @@ TOP=../.. SRC += access.c SRC += append.c SRC += chdr.c +SRC += dup2.c SRC += gcwd.c SRC += getpid.c SRC += sleep.c SRC += tread.c SRC += write.c diff -aprNU7 djgpp.orig/src/docs/kb/wc206.txi djgpp/src/docs/kb/wc206.txi --- djgpp.orig/src/docs/kb/wc206.txi 1969-12-31 18:50:25 -0509 +++ djgpp/src/docs/kb/wc206.txi 2016-04-16 17:02:34 -0509 @@ -0,0 +1,12 @@ +@node Changes in 2.06, , Changes in 2.05, What Changed +@section Changes in 2.06 + +Here is a list of changes from DJGPP V2.05 to DJGPP V2.06 + +@findex dup2 AT r{, and POSIX.1-2001 compliance} +The validity of the file descriptors passed to @code{dup2} is now checked. +If @var{existing_handle} is not a valid open file descriptor or +if @var{new_handle} is out of the allowed range for file descriptors +the call of @code{dup2} will fail and @code{errno} will be set to @code{EBADF}. +With this adjustment, the @acronym{Posix} compliance of the @code{dup2} implementation +is increased. diff -aprNU7 djgpp.orig/tests/libc/posix/unistd/dup2.c djgpp/tests/libc/posix/unistd/dup2.c --- djgpp.orig/tests/libc/posix/unistd/dup2.c 1969-12-31 18:50:25 -0509 +++ djgpp/tests/libc/posix/unistd/dup2.c 2016-04-18 19:15:52 -0509 @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + + +int main (void) +{ + int result = 0; + int bad_fd = INT_MAX; + struct rlimit rlim; + + + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX) + bad_fd = rlim.rlim_cur; + + if (dup2(1, 1) != 1) + result |= 1; + + close(0); + if (dup2(0, 0) != -1) + result |= 2; + + if (dup2(2, bad_fd) == -1 && errno != EBADF) + result |= 4; + + if (dup2(2, -1) != -1 && errno != EBADF) + result |= 8; + + if (dup2(2, bad_fd - 1) != bad_fd -1) + result |= 16; + if (dup2(2, bad_fd) != -1) + result |= 32; + + { + int fd = open(".", O_RDONLY); + if (fd == -1) + result |= 64; + else if (dup2(fd, fd + 1) == -1) + result |= 128; + + close(fd); + } + + if (result) + printf("dup2 check failed with result = %d\n", result); + else + printf("dup2 check passed.\n"); + + return result; +}