Hi/2.

Bruno Haible wrote:
>> +#ifdef __KLIBC__
>> +  FILE *result = freopen (filename, mode, stream);
>> +
>> +  /* On OS/2 kLIBC, freopen() returns NULL even if it is successful
>> +     if filename is NULL. */
>> +  if (!result && !errno)
>> +    result = stream;
> 
> 1) In the comment you say 'if filename is NULL' but in the code you use
> the (hacky) workaround code also if filename != NULL. Why?
> 

If filename != NULL, it is not possible that result is NULL and errno is
0. Anyway fixed.


> 2) When freopen returns NULL for success, does it set errno = 0, or does
> it leave errno untouched? Can you find out, please, by using a test program
> like
> 
>   errno = 42;
>   FILE *result = freopen (NULL, mode, stream);
>   printf ("errno = %d\n", errno);
> 
> If it's the latter case (it leaves errno untouched), you need to add an
> 'errno = 0;' statement before the freopen call.
> 

I thought testing this. But it was wrong. Thanks for pointing this.

Fixed.

-- 
KO Myung-Hun

Using Mozilla SeaMonkey 2.7.2
Under OS/2 Warp 4 for Korean with FixPak #15
In VirtualBox v4.1.32 on Intel Core i7-3615QM 2.30GHz with 8GB RAM

Korean OS/2 User Community : http://www.ecomstation.co.kr

>From e6db5cbcc2edcc514aef10eaf63d108d1448f5df Mon Sep 17 00:00:00 2001
From: KO Myung-Hun <k...@chollian.net>
Date: Wed, 3 Sep 2014 20:47:02 +0900
Subject: [PATCH] freopen: workaround freopen() on OS/2 kLIBC

On OS/2 kLIBC, freopen() returns NULL even if it is successful if
filename is NULL.

* lib/freopen-safer.c (klibc_freopen): New.
* lib/freopen.c (orig_freopen): Workaround.
---
 lib/freopen-safer.c | 24 ++++++++++++++++++++++++
 lib/freopen.c       | 16 +++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/lib/freopen-safer.c b/lib/freopen-safer.c
index 714dc1d..b889123 100644
--- a/lib/freopen-safer.c
+++ b/lib/freopen-safer.c
@@ -44,6 +44,30 @@ protect_fd (int fd)
   return true;
 }
 
+#ifdef __KLIBC__
+/* Workaround for freopen() on OS/2 kLIBC */
+static FILE *
+klibc_freopen (const char *filename, const char *mode, FILE *stream)
+{
+  FILE *result;
+
+  /* Clear errno to check the success of freopen() with it */
+  errno = 0;
+
+  result = freopen (filename, mode, stream);
+
+  /* On OS/2 kLIBC, freopen() returns NULL even if it is successful
+     if filename is NULL. */
+  if (!filename && !result && !errno)
+    result = stream;
+
+  return result;
+}
+
+# undef freopen
+# define freopen klibc_freopen
+#endif
+
 /* Like freopen, but guarantee that reopening stdin, stdout, or stderr
    preserves the invariant that STDxxx_FILENO==fileno(stdxxx), and
    that no other stream will interfere with the standard streams.
diff --git a/lib/freopen.c b/lib/freopen.c
index 384eba6..4669773 100644
--- a/lib/freopen.c
+++ b/lib/freopen.c
@@ -29,7 +29,21 @@
 static FILE *
 orig_freopen (const char *filename, const char *mode, FILE *stream)
 {
-  return freopen (filename, mode, stream);
+  FILE *result;
+
+  /* Clear errno to check the success of freopen() with it */
+  errno = 0;
+
+  result = freopen (filename, mode, stream);
+
+#ifdef __KLIBC__
+  /* On OS/2 kLIBC, freopen() returns NULL even if it is successful
+     if filename is NULL. */
+  if (!filename && !result && !errno)
+    result = stream;
+#endif
+
+  return result;
 }
 
 /* Specification.  */
-- 
1.8.5.2

Reply via email to