Provide the correct POSIX return value for POSIX::dup2() on Win32.
authorNicholas Clark <nick@ccl4.org>
Fri, 9 Dec 2011 12:09:07 +0000 (13:09 +0100)
committerNicholas Clark <nick@ccl4.org>
Fri, 30 Dec 2011 10:55:07 +0000 (11:55 +0100)
Microsoft, in their wisdom, chose to ignore the POSIX spec when implementing
their dup2(), and have theirs return 0 on success, instead of the file
descriptor. It seems that no other vendor is this, um, "special", so code
the exception directly, as we don't run Configure on Win32, so there's little
point probing for this.

This resolves RT #98912.

ext/POSIX/POSIX.xs
ext/POSIX/t/posix.t

index ab30a1c..f9a91ca 100644 (file)
@@ -1468,6 +1468,17 @@ SysRet
 dup2(fd1, fd2)
        int             fd1
        int             fd2
+    CODE:
+#ifdef WIN32
+       /* RT #98912 - More Microsoft muppetry - failing to actually implemented
+          the well known documented POSIX behaviour for a POSIX API.
+          http://msdn.microsoft.com/en-us/library/8syseb29.aspx   */
+       RETVAL = dup2(fd1, fd2) == -1 ? -1 : fd2;
+#else
+       RETVAL = dup2(fd1, fd2);
+#endif
+    OUTPUT:
+       RETVAL
 
 SV *
 lseek(fd, offset, whence)
index a5585e0..442b540 100644 (file)
@@ -346,9 +346,6 @@ is($buffer, "# Ex", 'read');
 # The descriptor $testfd was using is now free, and is lower than that which
 # $fd1 was using. Hence if dup2() behaves as dup(), we'll know :-)
 {
-    local $TODO;
-    $TODO = "dup2's return value is not correct on $^O"
-       if $Is_W32;
     $testfd = dup2($fd2, $fd1);
     is($testfd, $fd1, 'dup2');
     undef $buffer;