delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2016/04/19/16:36:01

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]" <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>
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 <libc/stubs.h>
  #include <unistd.h>
@@ -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 <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+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 <libc/stubs.h>
  #include <unistd.h>
@@ -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 <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+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;
+}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019