Discussion:
[PATCH v2] OS/2 patches
KO Myung-Hun
2014-12-09 01:40:45 UTC
Permalink
Hi/2.

These are rebased OS/2 patches.

Review, please...

[PATCH 01/14] stdint: check _INTPTR_T_DECLARED before defining
[PATCH 02/14] Fix character encoding aliases for OS/2
[PATCH 03/14] relocatable: support UNIXROOT in relocate() on EMX
[PATCH 04/14] binary-io: don't put fd in binary mode if it is a
[PATCH 05/14] pipe-filter-aux: undefine HAVE_SELECT on KLIBC
[PATCH 06/14] w32spawn: clear SHELL_SPECIAL_CHARS and
[PATCH 07/14] getdtablesize: do not use getrlimit() on OS/2 kLIBC
[PATCH 08/14] wcwidth: fix 'conflicting types' error for `__wcwidth'
[PATCH 09/14] utimes: detect utimes() correctly on OS/2 kLIBC
[PATCH 10/14] gnulib-tool: fall back into copy if symbolic link is
[PATCH 11/14] pipe_filter_ii_execute: port to OS/2 kLIBC
[PATCH 12/14] save_cwd: save/restore all CWDs of each drive on EMX
[PATCH 13/14] dup, dup2, fcntl: support a directory fd on OS/2 kLIBC
[PATCH 14/14] opendir, closedir, dirfd, fdopendir: port to OS/2 kLIBC
KO Myung-Hun
2014-12-09 01:40:46 UTC
Permalink
OS/2 kLIBC's stdint.h defines _INTPTR_T_DECLARED and needs its own
definitions of intptr_t and uintptr_t (which use int and unsigned)
to avoid clashes with declarations of system functions like sbrk.

* lib/stdint.in.h (intptr_t, uintptr_t): Check
_INTPTR_T_DECLARED before defining them.
---
lib/stdint.in.h | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/stdint.in.h b/lib/stdint.in.h
index 98ee423..79f67a6 100644
--- a/lib/stdint.in.h
+++ b/lib/stdint.in.h
@@ -288,12 +288,17 @@ typedef gl_uint_fast32_t gl_uint_fast16_t;

/* 7.18.1.4. Integer types capable of holding object pointers */

-#undef intptr_t
-#undef uintptr_t
+/* kLIBC's stdint.h defines _INTPTR_T_DECLARED and needs its own
+ definitions of intptr_t and uintptr_t (which use int and unsigned)
+ to avoid clashes with declarations of system functions like sbrk. */
+#ifndef _INTPTR_T_DECLARED
+# undef intptr_t
+# undef uintptr_t
typedef long int gl_intptr_t;
typedef unsigned long int gl_uintptr_t;
-#define intptr_t gl_intptr_t
-#define uintptr_t gl_uintptr_t
+# define intptr_t gl_intptr_t
+# define uintptr_t gl_uintptr_t
+#endif

/* 7.18.1.5. Greatest-width integer types */
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:47 UTC
Permalink
* lib/config.charset: Remove os2* from case "$os" in
* lib/localcharset.c (get_charset_aliases): Use embedded encoding
aliases on OS/2.
---
lib/config.charset | 4 +---
lib/localcharset.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/lib/config.charset b/lib/config.charset
index 4e4c7ed..3e6c88f 100644
--- a/lib/config.charset
+++ b/lib/config.charset
@@ -348,12 +348,10 @@ case "$os" in
#echo "sun_eu_greek ?" # what is this?
echo "UTF-8 UTF-8"
;;
- freebsd* | os2*)
+ freebsd*)
# FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore
# localcharset.c falls back to using the full locale name
# from the environment variables.
- # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just
- # reuse FreeBSD's locale data for OS/2.
echo "C ASCII"
echo "US-ASCII ASCII"
for l in la_LN lt_LN; do
diff --git a/lib/localcharset.c b/lib/localcharset.c
index 1c17af0..ba2ac3e 100644
--- a/lib/localcharset.c
+++ b/lib/localcharset.c
@@ -128,7 +128,7 @@ get_charset_aliases (void)
cp = charset_aliases;
if (cp == NULL)
{
-#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__)
+#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__ || defined OS2)
const char *dir;
const char *base = "charset.alias";
char *file_name;
@@ -342,6 +342,64 @@ get_charset_aliases (void)
"CP54936" "\0" "GB18030" "\0"
"CP65001" "\0" "UTF-8" "\0";
# endif
+# if defined OS2
+ /* To avoid the troubles of installing a separate file in the same
+ directory as the DLL and of retrieving the DLL's directory at
+ runtime, simply inline the aliases here. */
+
+ cp = "bg_BG" "\0" "CP1251" "\0"
+ "ca_ES" "\0" "CP850" "\0"
+ "cs_SZ" "\0" "CP852" "\0"
+ "da_DK" "\0" "CP850" "\0"
+ "de_AT" "\0" "CP850" "\0"
+ "de_CH" "\0" "CP850" "\0"
+ "de_DE" "\0" "CP850" "\0"
+ "el_GR" "\0" "CP869" "\0"
+ "en_AU" "\0" "CP850" "\0"
+ "en_CA" "\0" "CP850" "\0"
+ "en_GB" "\0" "CP850" "\0"
+ "en_IE" "\0" "CP850" "\0"
+ "en_NZ" "\0" "CP850" "\0"
+ "en_US" "\0" "CP850" "\0"
+ "en_ZA" "\0" "CP850" "\0"
+ "es_ES" "\0" "CP850" "\0"
+ "es_LA" "\0" "CP850" "\0"
+ "et_EE" "\0" "CP922" "\0"
+ "fi_FI" "\0" "CP850" "\0"
+ "fr_BE" "\0" "CP850" "\0"
+ "fr_CA" "\0" "CP850" "\0"
+ "fr_CH" "\0" "CP850" "\0"
+ "fr_FR" "\0" "CP850" "\0"
+ "hr_HR" "\0" "CP852" "\0"
+ "hu_HU" "\0" "CP852" "\0"
+ "is_IS" "\0" "CP850" "\0"
+ "it_CH" "\0" "CP850" "\0"
+ "it_IT" "\0" "CP850" "\0"
+ "iw_IL" "\0" "CP862" "\0"
+ "ja_JP" "\0" "CP943" "\0"
+ "ko_KR" "\0" "CP949" "\0"
+ "lt_LT" "\0" "ISO-8859-13" "\0"
+ "lv_LV" "\0" "ISO-8859-13" "\0"
+ "mk_MK" "\0" "CP855" "\0"
+ "nl_BE" "\0" "CP850" "\0"
+ "nl_NL" "\0" "CP850" "\0"
+ "no_NO" "\0" "CP850" "\0"
+ "pl_PL" "\0" "CP852" "\0"
+ "pt_BR" "\0" "CP850" "\0"
+ "pt_PT" "\0" "CP850" "\0"
+ "ro_RO" "\0" "CP852" "\0"
+ "ru_RU" "\0" "CP866" "\0"
+ "sh_BA" "\0" "CP852" "\0"
+ "sk_SK" "\0" "CP852" "\0"
+ "sl_SI" "\0" "CP852" "\0"
+ "sq_AL" "\0" "CP850" "\0"
+ "sr_SP" "\0" "CP855" "\0"
+ "sv_SE" "\0" "CP850" "\0"
+ "th_TH" "\0" "CP874" "\0"
+ "tr_TR" "\0" "CP857" "\0"
+ "zh_CN" "\0" "GB2312" "\0"
+ "zh_TW" "\0" "CP950" "\0";
+# endif
#endif

charset_aliases = cp;
--
1.8.5.2
Daiki Ueno
2014-12-19 03:26:36 UTC
Permalink
Hello,
Post by KO Myung-Hun
+# if defined OS2
+ /* To avoid the troubles of installing a separate file in the same
+ directory as the DLL and of retrieving the DLL's directory at
+ runtime, simply inline the aliases here. */
+
+ cp = "bg_BG" "\0" "CP1251" "\0"
You are adding locale-to-charset mappings here, while all other mappings
defined are charset-to-charset. Perhaps such a mappings could be
resolved in intl/localealias.c through the locale.alias file instead?

Your change might be necessary for other consumers than gettext. If so,
could you explain the actual use-case in the ChangeLog and/or the above
comment?

Also if it changes anything in the OS/2 port of gettext, consider
updating this file:
http://git.savannah.gnu.org/cgit/gettext.git/tree/os2/README.OS2

Thanks,
--
Daiki Ueno
KO Myung-Hun
2014-12-19 04:35:50 UTC
Permalink
Hi/2.
Post by Daiki Ueno
Hello,
Post by KO Myung-Hun
+# if defined OS2
+ /* To avoid the troubles of installing a separate file in the same
+ directory as the DLL and of retrieving the DLL's directory at
+ runtime, simply inline the aliases here. */
+
+ cp = "bg_BG" "\0" "CP1251" "\0"
You are adding locale-to-charset mappings here, while all other mappings
defined are charset-to-charset. Perhaps such a mappings could be
resolved in intl/localealias.c through the locale.alias file instead?
Your change might be necessary for other consumers than gettext. If so,
could you explain the actual use-case in the ChangeLog and/or the above
comment?
I'm using this in libiconv. On OS/2, a charset is not specified
generally. Just only a locale is specified. And all LC_xxx are not
specified. Just only LANG is specified. For examples, set LANG=ko_KR for
Korean. And the case that charset aliases are used is that '.' to
specify a charset is not found or a buffer is overflowed, which is
impossible if a charset is correct. So charset-to-charset mapping is not
useful on OS/2.
Post by Daiki Ueno
Also if it changes anything in the OS/2 port of gettext, consider
http://git.savannah.gnu.org/cgit/gettext.git/tree/os2/README.OS2
Ok. If I work on gettext later, I'll consider.
--
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
KO Myung-Hun
2014-12-19 05:44:30 UTC
Permalink
Post by KO Myung-Hun
Hi/2.
Post by Daiki Ueno
Hello,
Post by KO Myung-Hun
+# if defined OS2
+ /* To avoid the troubles of installing a separate file in the same
+ directory as the DLL and of retrieving the DLL's directory at
+ runtime, simply inline the aliases here. */
+
+ cp = "bg_BG" "\0" "CP1251" "\0"
You are adding locale-to-charset mappings here, while all other mappings
defined are charset-to-charset. Perhaps such a mappings could be
resolved in intl/localealias.c through the locale.alias file instead?
Your change might be necessary for other consumers than gettext. If so,
could you explain the actual use-case in the ChangeLog and/or the above
comment?
I'm using this in libiconv. On OS/2, a charset is not specified
generally. Just only a locale is specified. And all LC_xxx are not
specified. Just only LANG is specified. For examples, set LANG=ko_KR for
Korean. And the case that charset aliases are used is that '.' to
specify a charset is not found or a buffer is overflowed, which is
impossible if a charset is correct. So charset-to-charset mapping is not
useful on OS/2.
Post by Daiki Ueno
Also if it changes anything in the OS/2 port of gettext, consider
http://git.savannah.gnu.org/cgit/gettext.git/tree/os2/README.OS2
Ok. If I work on gettext later, I'll consider.
I missed a patch.
--
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
Daiki Ueno
2014-12-19 06:02:48 UTC
Permalink
Post by KO Myung-Hun
I'm using this in libiconv. On OS/2, a charset is not specified
generally. Just only a locale is specified. And all LC_xxx are not
specified. Just only LANG is specified. For examples, set LANG=ko_KR for
Korean. And the case that charset aliases are used is that '.' to
specify a charset is not found or a buffer is overflowed, which is
impossible if a charset is correct. So charset-to-charset mapping is not
useful on OS/2.
Thanks for the update.
Post by KO Myung-Hun
Post by Daiki Ueno
Also if it changes anything in the OS/2 port of gettext, consider
http://git.savannah.gnu.org/cgit/gettext.git/tree/os2/README.OS2
Ok. If I work on gettext later, I'll consider.
I meant to ask if the patch could potentially change the behavior
described in that documentation. Would you mind double-checking that?

For example, it says:

If the output character set is ommited from the LANG variable, the
default codepage is ALWAYS taken from the operating system (e.g. the
codepage setting from locale.alias is always ignored, so "russian"
stays just for "ru_RU" and not for "ru_RU.ISO-8859-5"); you may want
to set it just if you want to override the active OS/2 codepage.

Regards,
--
Daiki Ueno
KO Myung-Hun
2014-12-19 09:21:11 UTC
Permalink
Post by Daiki Ueno
Post by KO Myung-Hun
I'm using this in libiconv. On OS/2, a charset is not specified
generally. Just only a locale is specified. And all LC_xxx are not
specified. Just only LANG is specified. For examples, set LANG=ko_KR for
Korean. And the case that charset aliases are used is that '.' to
specify a charset is not found or a buffer is overflowed, which is
impossible if a charset is correct. So charset-to-charset mapping is not
useful on OS/2.
Thanks for the update.
Post by KO Myung-Hun
Post by Daiki Ueno
Also if it changes anything in the OS/2 port of gettext, consider
http://git.savannah.gnu.org/cgit/gettext.git/tree/os2/README.OS2
Ok. If I work on gettext later, I'll consider.
I meant to ask if the patch could potentially change the behavior
described in that documentation. Would you mind double-checking that?
If the output character set is ommited from the LANG variable, the
default codepage is ALWAYS taken from the operating system (e.g. the
codepage setting from locale.alias is always ignored, so "russian"
stays just for "ru_RU" and not for "ru_RU.ISO-8859-5"); you may want
to set it just if you want to override the active OS/2 codepage.
This patch does not change any behaviors of OS/2 port of gettext.
Because this patch embeds charset aliases into localcharset.c instead of
using charset.alias file, and fixes the problem a locale instead of a
charset if a charset is not specified is returned. In addition,
localcharset.c module itself does not use locale.alias. It is used in
localealias.c. Frankly, I don't know that how localcharset.c and
localealias.c have a relation to each other.
--
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
Daiki Ueno
2014-12-24 09:40:19 UTC
Permalink
Post by KO Myung-Hun
Post by Daiki Ueno
If the output character set is ommited from the LANG variable, the
default codepage is ALWAYS taken from the operating system (e.g. the
codepage setting from locale.alias is always ignored, so "russian"
stays just for "ru_RU" and not for "ru_RU.ISO-8859-5"); you may want
to set it just if you want to override the active OS/2 codepage.
This patch does not change any behaviors of OS/2 port of gettext.
Because this patch embeds charset aliases into localcharset.c instead of
using charset.alias file, and fixes the problem a locale instead of a
charset if a charset is not specified is returned.
Thanks for checking, looks safe then. One question is: where did you
take the mapping data? I found this chart:
http://www.borgendale.com/locale.htm

I'm not sure how authoritative it is, but there are some differences
from yours: ar_AA, bg_BG, lt_LT, lv_LV, and zh_CN.

Regards,
--
Daiki Ueno
KO Myung-Hun
2014-12-25 03:59:18 UTC
Permalink
Post by Daiki Ueno
Post by KO Myung-Hun
Post by Daiki Ueno
If the output character set is ommited from the LANG variable, the
default codepage is ALWAYS taken from the operating system (e.g. the
codepage setting from locale.alias is always ignored, so "russian"
stays just for "ru_RU" and not for "ru_RU.ISO-8859-5"); you may want
to set it just if you want to override the active OS/2 codepage.
This patch does not change any behaviors of OS/2 port of gettext.
Because this patch embeds charset aliases into localcharset.c instead of
using charset.alias file, and fixes the problem a locale instead of a
charset if a charset is not specified is returned.
Thanks for checking, looks safe then. One question is: where did you
http://www.borgendale.com/locale.htm
I used CODEPAGE and COUNTRY parts of OS/2 command references.
Post by Daiki Ueno
I'm not sure how authoritative it is, but there are some differences
from yours: ar_AA, bg_BG, lt_LT, lv_LV, and zh_CN.
Owing to you, I've found that I omitted ar_AA and comments for code page
lists. Thanks.

And the differences of others is because cp915, cp921 and cp1381 are not
supported by libiconv. In these cases, I picked up code pages from
config.charset.

Finally, I changed a code page for bg_BG from cp1251 to cp855 which is
etc code page.
--
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
Daiki Ueno
2014-12-25 07:54:52 UTC
Permalink
Thanks for the update. I'm attaching a slightly modified version of the
patch, with typo and style fixes (e.g. adding two spaces after a period,
according to GCS, etc).
Post by KO Myung-Hun
I used CODEPAGE and COUNTRY parts of OS/2 command references.
Could you provide the title and the corresponding section number of the
manual? For example, for VMS, we have the following comment:

/* The list of encodings is taken from the OpenVMS 7.3-1 documentation
"Compaq C Run-Time Library Reference Manual for OpenVMS systems"
section 10.7 "Handling Different Character Sets". */
Post by KO Myung-Hun
And the differences of others is because cp915, cp921 and cp1381 are not
supported by libiconv. In these cases, I picked up code pages from
config.charset.
I see.
Post by KO Myung-Hun
Finally, I changed a code page for bg_BG from cp1251 to cp855 which is
etc code page.
Is this a desired change? It seems those codepages are largely
incompatible. I changed this to ISO-8859-5.

By the way, it's tempting to call DosQueryCp if a charset is omitted
from the locale name, to avoid maintaining the default mapping
ourselves. I'd rather not do that for now, but is it feasible?

Regards,
--
Daiki Ueno
KO Myung-Hun
2014-12-26 03:15:30 UTC
Permalink
Post by Daiki Ueno
Thanks for the update. I'm attaching a slightly modified version of the
patch, with typo and style fixes (e.g. adding two spaces after a period,
according to GCS, etc).
Thanks. ^^ And fixed typo, cp1361 to cp1381.
Post by Daiki Ueno
Post by KO Myung-Hun
I used CODEPAGE and COUNTRY parts of OS/2 command references.
Could you provide the title and the corresponding section number of the
/* The list of encodings is taken from the OpenVMS 7.3-1 documentation
"Compaq C Run-Time Library Reference Manual for OpenVMS systems"
section 10.7 "Handling Different Character Sets". */
I added a document file name and entries.
Post by Daiki Ueno
Post by KO Myung-Hun
And the differences of others is because cp915, cp921 and cp1381 are not
supported by libiconv. In these cases, I picked up code pages from
config.charset.
I see.
Post by KO Myung-Hun
Finally, I changed a code page for bg_BG from cp1251 to cp855 which is
etc code page.
Is this a desired change? It seems those codepages are largely
incompatible. I changed this to ISO-8859-5.
But cp855 is used on OS/2. So I decided it. But ISO-8859-5 is equivalent
to cp915, no problem.
Post by Daiki Ueno
By the way, it's tempting to call DosQueryCp if a charset is omitted
from the locale name, to avoid maintaining the default mapping
ourselves. I'd rather not do that for now, but is it feasible?
This was my first idea. But Bruno rejected. See

http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-03/msg00000.html
http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-06/msg00000.html
http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-06/msg00001.html
http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-06/msg00002.html
http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-06/msg00003.html
--
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
Daiki Ueno
2014-12-26 08:21:52 UTC
Permalink
Post by KO Myung-Hun
Thanks. ^^ And fixed typo, cp1361 to cp1381.
Oops, thanks for fixing.
Post by KO Myung-Hun
Post by Daiki Ueno
By the way, it's tempting to call DosQueryCp if a charset is omitted
from the locale name, to avoid maintaining the default mapping
ourselves. I'd rather not do that for now, but is it feasible?
This was my first idea. But Bruno rejected. See
http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-03/msg00000.html
Thanks for the link. If I understand correctly, the main point seems
that the patch affects the codeset of the POSIX locale ("C" or "POSIX").

For other locale values, POSIX says:

If the locale value has the form:

language[_territory][.codeset]

it refers to an implementation-provided locale, where settings of
language, territory, and codeset are implementation-defined.

So, I don't see any problem using system's codepage as a default codeset
of a language_territory locale (though it might conflict with the
libiconv design). FWIW, kLIBC's nl_langinfo/setlocale implementation
does this:

- if codeset is specified as part of the locale name, use it
- if the locale name is "C" or "POSIX", use "US-ASCII"
- otherwise, fallback to DosQueryCp

I'm attaching two patches: the first one is an update of the patch we
are currently working on (I added mappings from the "unusable" codepages
to their equivalents), and the second one is an alternative
implementation following the kLIBC implementation.

Regards,
--
Daiki Ueno
KO Myung-Hun
2014-12-26 15:49:46 UTC
Permalink
Post by Daiki Ueno
Post by KO Myung-Hun
Thanks. ^^ And fixed typo, cp1361 to cp1381.
Oops, thanks for fixing.
Post by KO Myung-Hun
Post by Daiki Ueno
By the way, it's tempting to call DosQueryCp if a charset is omitted
from the locale name, to avoid maintaining the default mapping
ourselves. I'd rather not do that for now, but is it feasible?
This was my first idea. But Bruno rejected. See
http://lists.gnu.org/archive/html/bug-gnu-libiconv/2011-03/msg00000.html
Thanks for the link. If I understand correctly, the main point seems
that the patch affects the codeset of the POSIX locale ("C" or "POSIX").
language[_territory][.codeset]
it refers to an implementation-provided locale, where settings of
language, territory, and codeset are implementation-defined.
So, I don't see any problem using system's codepage as a default codeset
of a language_territory locale (though it might conflict with the
libiconv design). FWIW, kLIBC's nl_langinfo/setlocale implementation
- if codeset is specified as part of the locale name, use it
- if the locale name is "C" or "POSIX", use "US-ASCII"
- otherwise, fallback to DosQueryCp
I'm attaching two patches: the first one is an update of the patch we
are currently working on (I added mappings from the "unusable" codepages
to their equivalents), and the second one is an alternative
implementation following the kLIBC implementation.
I prefer second one. It was my first idea and more simple. ^^

Thanks a lot for your works.
--
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
Daiki Ueno
2015-01-05 06:06:59 UTC
Permalink
Sorry for the delay.
Post by KO Myung-Hun
Post by Daiki Ueno
I'm attaching two patches: the first one is an update of the patch we
are currently working on (I added mappings from the "unusable" codepages
to their equivalents), and the second one is an alternative
implementation following the kLIBC implementation.
I prefer second one. It was my first idea and more simple. ^^
Okay, if nobody objects, I'll push the attached (I did a bit more
research on OS/2 codepages and added mappings from them to the GNU
canonical charset names as possible).

Regards,
--
Daiki Ueno
KO Myung-Hun
2015-01-06 00:46:10 UTC
Permalink
Post by Daiki Ueno
Sorry for the delay.
Post by KO Myung-Hun
Post by Daiki Ueno
I'm attaching two patches: the first one is an update of the patch we
are currently working on (I added mappings from the "unusable" codepages
to their equivalents), and the second one is an alternative
implementation following the kLIBC implementation.
I prefer second one. It was my first idea and more simple. ^^
Okay, if nobody objects, I'll push the attached (I did a bit more
research on OS/2 codepages and added mappings from them to the GNU
canonical charset names as possible).
Thanks a lot. ^^
--
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
KO Myung-Hun
2014-12-09 01:40:48 UTC
Permalink
UNIXROOT is used to specify a drive of a root of FHS. So if a path is
started with '/', then it should be translated to "$UNIXROOT/".

* lib/relocatable.c (relocate): Prepend $UNIXROOT to pathname if it is
started with '/' on EMX.
---
lib/relocatable.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/lib/relocatable.c b/lib/relocatable.c
index 6c6ea1c..1d6fdd5 100644
--- a/lib/relocatable.c
+++ b/lib/relocatable.c
@@ -537,6 +537,27 @@ relocate (const char *pathname)
}
}
}
+
+#ifdef __EMX__
+ if (pathname && ISSLASH (pathname[0]))
+ {
+ const char *unixroot = getenv ("UNIXROOT");
+
+ if (unixroot && HAS_DEVICE (unixroot) && !unixroot[2])
+ {
+ char *result = (char *) xmalloc (2 + strlen (pathname) + 1);
+#ifdef NO_XMALLOC
+ if (result != NULL)
+#endif
+ {
+ strcpy (result, unixroot);
+ strcpy (result + 2, pathname);
+ return result;
+ }
+ }
+ }
+#endif
+
/* Nothing to relocate. */
return pathname;
}
--
1.8.5.2
Ben Pfaff
2014-12-09 04:38:50 UTC
Permalink
Post by KO Myung-Hun
UNIXROOT is used to specify a drive of a root of FHS. So if a path is
started with '/', then it should be translated to "$UNIXROOT/".
* lib/relocatable.c (relocate): Prepend $UNIXROOT to pathname if it is
started with '/' on EMX.
As one of the maintainers of the relocatable modules, the code in this
patch seems reasonable to me. I don't know enough about OS/2 or EMX to
know whether $UNIXROOT is a customary variable or whether this is a
correct context for using it. Can you assure me that you've thought
about those?
KO Myung-Hun
2014-12-09 05:51:51 UTC
Permalink
Post by Ben Pfaff
Post by KO Myung-Hun
UNIXROOT is used to specify a drive of a root of FHS. So if a path is
started with '/', then it should be translated to "$UNIXROOT/".
* lib/relocatable.c (relocate): Prepend $UNIXROOT to pathname if it is
started with '/' on EMX.
As one of the maintainers of the relocatable modules, the code in this
patch seems reasonable to me. I don't know enough about OS/2 or EMX to
know whether $UNIXROOT is a customary variable or whether this is a
correct context for using it. Can you assure me that you've thought
about those?
OS/2 file system is based on drives[A-Z]. '/' means a root of a current
drive. There are maximum 26 kinds of '/'.

For examples, consider that xxx is installed into f:/usr/bin. If
executing xxx on drive e:, '/' of xxx is e:/ not f:/. In this case, xxx
fails to find its root.

$UNIXROOT is used to overcome this problem. On OS/2, $UNIXROOT is used
to specify a drive of '/'. And all programs following FHS are installed
on a drive specified by $UNIXROOT. In the above, if UNIXROOT is set to
'f:'. Then '/' is translated to 'f:/' as xxx expects.

And see <http://trac.netlabs.org/libc/wiki/UnixPenthouseApartement>.

Still not assured ?
--
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
Ben Pfaff
2014-12-09 05:58:02 UTC
Permalink
Post by KO Myung-Hun
Post by Ben Pfaff
Post by KO Myung-Hun
UNIXROOT is used to specify a drive of a root of FHS. So if a path is
started with '/', then it should be translated to "$UNIXROOT/".
* lib/relocatable.c (relocate): Prepend $UNIXROOT to pathname if it is
started with '/' on EMX.
As one of the maintainers of the relocatable modules, the code in this
patch seems reasonable to me. I don't know enough about OS/2 or EMX to
know whether $UNIXROOT is a customary variable or whether this is a
correct context for using it. Can you assure me that you've thought
about those?
OS/2 file system is based on drives[A-Z]. '/' means a root of a current
drive. There are maximum 26 kinds of '/'.
For examples, consider that xxx is installed into f:/usr/bin. If
executing xxx on drive e:, '/' of xxx is e:/ not f:/. In this case, xxx
fails to find its root.
$UNIXROOT is used to overcome this problem. On OS/2, $UNIXROOT is used
to specify a drive of '/'. And all programs following FHS are installed
on a drive specified by $UNIXROOT. In the above, if UNIXROOT is set to
'f:'. Then '/' is translated to 'f:/' as xxx expects.
And see <http://trac.netlabs.org/libc/wiki/UnixPenthouseApartement>.
Still not assured ?
Thank you for explaining.

I applied this to the gnulib repository.

Thanks,

Ben.
KO Myung-Hun
2014-12-09 06:05:43 UTC
Permalink
Post by Ben Pfaff
Post by KO Myung-Hun
Post by Ben Pfaff
Post by KO Myung-Hun
UNIXROOT is used to specify a drive of a root of FHS. So if a path is
started with '/', then it should be translated to "$UNIXROOT/".
* lib/relocatable.c (relocate): Prepend $UNIXROOT to pathname if it is
started with '/' on EMX.
As one of the maintainers of the relocatable modules, the code in this
patch seems reasonable to me. I don't know enough about OS/2 or EMX to
know whether $UNIXROOT is a customary variable or whether this is a
correct context for using it. Can you assure me that you've thought
about those?
OS/2 file system is based on drives[A-Z]. '/' means a root of a current
drive. There are maximum 26 kinds of '/'.
For examples, consider that xxx is installed into f:/usr/bin. If
executing xxx on drive e:, '/' of xxx is e:/ not f:/. In this case, xxx
fails to find its root.
$UNIXROOT is used to overcome this problem. On OS/2, $UNIXROOT is used
to specify a drive of '/'. And all programs following FHS are installed
on a drive specified by $UNIXROOT. In the above, if UNIXROOT is set to
'f:'. Then '/' is translated to 'f:/' as xxx expects.
And see <http://trac.netlabs.org/libc/wiki/UnixPenthouseApartement>.
Still not assured ?
Thank you for explaining.
I applied this to the gnulib repository.
Thanks a lot for applying promptly.
--
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
Bruno Haible
2017-05-16 18:06:57 UTC
Permalink
Followup to this patch from 2014-12-09: A bit more consistent coding style:
- The argument 'pathname' must be non-NULL. No need to test it against NULL.
- Make use of ISSLASH macro consistently.
- For characters, I find a comparison with '\0' clearer than a boolean negation.
Limit boolean expressions to booleans.
- Better use the memcpy-before-strcpy idiom than strcpy-before-strcpy. The
former makes it clear that the programmer has thought about the length of the
strings.


2017-05-16 Bruno Haible <***@clisp.org>

relocate: Simplify EMX specific code.
* lib/relocatable.c (relocate): Assume pathname is non-NULL. Use
ISSLASH macro consistently. Avoid dangerous string concatenation idiom.

diff --git a/lib/relocatable.c b/lib/relocatable.c
index c42398e..189aee4 100644
--- a/lib/relocatable.c
+++ b/lib/relocatable.c
@@ -542,27 +542,26 @@ relocate (const char *pathname)
# ifdef __KLIBC__
# undef strncmp

- if (pathname && strncmp (pathname, "/@unixroot", 10) == 0
- && (pathname[10] == '\0' || pathname[10] == '/' || pathname[10] == '\\'))
+ if (strncmp (pathname, "/@unixroot", 10) == 0
+ && (pathname[10] == '\0' || ISSLASH (pathname[10])))
{
/* kLIBC itself processes /@unixroot prefix */
-
return pathname;
}
else
# endif
- if (pathname && ISSLASH (pathname[0]))
+ if (ISSLASH (pathname[0]))
{
const char *unixroot = getenv ("UNIXROOT");

- if (unixroot && HAS_DEVICE (unixroot) && !unixroot[2])
+ if (unixroot && HAS_DEVICE (unixroot) && unixroot[2] == '\0')
{
char *result = (char *) xmalloc (2 + strlen (pathname) + 1);
#ifdef NO_XMALLOC
if (result != NULL)
#endif
{
- strcpy (result, unixroot);
+ memcpy (result, unixroot, 2);
strcpy (result + 2, pathname);
return result;
}

KO Myung-Hun
2014-12-09 01:40:49 UTC
Permalink
* lib/binary-io.h (SET_BINARY): Don't put fd in binary mode if it is
a console on EMX.
---
lib/binary-io.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/binary-io.h b/lib/binary-io.h
index 7928f8c..696cdf9 100644
--- a/lib/binary-io.h
+++ b/lib/binary-io.h
@@ -60,7 +60,7 @@ set_binary_mode (int fd, int mode)

/* SET_BINARY (fd);
changes the file descriptor fd to perform binary I/O. */
-#ifdef __DJGPP__
+#if defined __DJGPP__ || defined __EMX__
# include <unistd.h> /* declares isatty() */
/* Avoid putting stdin/stdout in binary mode if it is connected to
the console, because that would make it impossible for the user
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:50 UTC
Permalink
On OS/2 kLIBC, select() works only on sockets.

* lib/pipe-filter-aux.h (HAVE_SELECT): Undefine on OS/2 kLIBC.
---
lib/pipe-filter-aux.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/pipe-filter-aux.h b/lib/pipe-filter-aux.h
index 8f2a707..ee63ac8 100644
--- a/lib/pipe-filter-aux.h
+++ b/lib/pipe-filter-aux.h
@@ -35,8 +35,9 @@ _GL_INLINE_HEADER_BEGIN
looping while waiting for the child. Not good. But hardly any platform
lacks select() nowadays.) */

-/* On BeOS select() works only on sockets, not on normal file descriptors. */
-#ifdef __BEOS__
+/* On BeOS and OS/2 kLIBC select() works only on sockets, not on normal file
+ descriptors. */
+#if defined __BEOS__ || defined __KLIBC__
# undef HAVE_SELECT
#endif
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:51 UTC
Permalink
spawn() on OS/2 kLIBC is not silly like one on Windows

* libc/w32spawn.h (SHELL_SPECIAL_CHARS, SHELL_SPACE_CHAR): Set both to
empty string on OS/2 kLIBC.
---
lib/w32spawn.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/w32spawn.h b/lib/w32spawn.h
index 0cad232..16f1251 100644
--- a/lib/w32spawn.h
+++ b/lib/w32spawn.h
@@ -123,8 +123,13 @@ undup_safer_noinherit (int tempfd, int origfd)
- mingw programs that have a global variable 'int _CRT_glob = 0;',
- Cygwin programs, when invoked from a Cygwin program.
*/
-#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?"
-#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#ifndef __KLIBC__
+# define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?"
+# define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#else
+# define SHELL_SPECIAL_CHARS ""
+# define SHELL_SPACE_CHARS ""
+#endif
static char **
prepare_spawn (char **argv)
{
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:52 UTC
Permalink
getrlimit() implementation of kLIBC is buggy. For examples, it crashes
due to 'stack overflow' or 'SIGSEGV' when used in GNU M4. So just use
getdtablesize() on kLIBC.

* lib/getdtablesize.c (rpl_getdtablesize): Do not use getrlimit() on
OS/2 kLIBC.
---
lib/getdtablesize.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/lib/getdtablesize.c b/lib/getdtablesize.c
index f0c6271..07e9d57 100644
--- a/lib/getdtablesize.c
+++ b/lib/getdtablesize.c
@@ -92,6 +92,10 @@ getdtablesize (void)
int
rpl_getdtablesize(void)
{
+/* getrlimit() implementation of kLIBC is buggy. For examples, it crashes
+ due to 'stack overflow' or 'SIGSEGV' when used in GNU M4. So just use
+ getdtablesize() on kLIBC. */
+# ifndef __KLIBC__
/* To date, this replacement is only compiled for Cygwin 1.7.25,
which auto-increased the RLIMIT_NOFILE soft limit until it
hits the compile-time constant hard limit of 3200. Although
@@ -101,6 +105,7 @@ rpl_getdtablesize(void)
struct rlimit lim;
if (!getrlimit (RLIMIT_NOFILE, &lim) && lim.rlim_max != RLIM_INFINITY)
return lim.rlim_max;
+# endif
return getdtablesize ();
}
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:53 UTC
Permalink
wchar_t(unsigned short) is defined differently from wint_t(int) on
OS/2 kLIBC.

* lib/wcwidth.c (wcwidth): Undefine on OS/2 kLIBC.
---
lib/wcwidth.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/lib/wcwidth.c b/lib/wcwidth.c
index d7837bb..2f8dc26 100644
--- a/lib/wcwidth.c
+++ b/lib/wcwidth.c
@@ -26,6 +26,13 @@
#include "streq.h"
#include "uniwidth.h"

+#ifdef __KLIBC__
+/* To avoid 'conflicting types' error for `__wcwidth' on OS/2 kLIBC.
+ wchar_t(unsigned short) is defined differently from wint_t(int) on
+ OS/2 kLIBC. */
+# undef wcwidth
+#endif
+
int
wcwidth (wchar_t wc)
#undef wcwidth
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:54 UTC
Permalink
utimes() of OS/2 kLIBC has some limitations.

1. OS/2 itself supports a file date since 1980 year.
2. OS/2 itself supports even seconds for a file time.
3. utimes() of OS/2 kLIBC does not work on an opened file.

* m4/utimes.m4: Detect utimes() correctly on OS/2 kLIBC.
---
m4/utimes.m4 | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/m4/utimes.m4 b/m4/utimes.m4
index c361357..ce6435c 100644
--- a/m4/utimes.m4
+++ b/m4/utimes.m4
@@ -1,5 +1,5 @@
# Detect some bugs in glibc's implementation of utimes.
-# serial 3
+# serial 4

dnl Copyright (C) 2003-2005, 2009-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
@@ -45,7 +45,9 @@ main ()
{
int result = 0;
char const *file = "conftest.utimes";
- static struct timeval timeval[2] = {{9, 10}, {999999, 999999}};
+ /* On OS/2, a file date should be since 1980 year and even seconds */
+ static struct timeval timeval[2] = {{315500400 + 10, 10},
+ {315500400 + 1000000, 999998}};

/* Test whether utimes() essentially works. */
{
@@ -82,11 +84,16 @@ main ()
result |= 1;
else if (fstat (fd, &st0) != 0)
result |= 1;
+ /* utimes() of OS/2 kLIBC does not work on an opened file */
+ else if (close (fd) != 0)
+ result |= 1;
else if (utimes (file, timeval) != 0)
result |= 2;
else if (utimes (file, NULL) != 0)
result |= 8;
- else if (fstat (fd, &st1) != 0)
+ else if (lstat (file, &st1) != 0)
+ result |= 1;
+ else if ((fd = open (file, O_WRONLY)) < 0)
result |= 1;
else if (write (fd, "\n", 1) != 1)
result |= 1;
--
1.8.5.2
KO Myung-Hun
2015-01-01 02:05:10 UTC
Permalink
Post by KO Myung-Hun
utimes() of OS/2 kLIBC has some limitations.
1. OS/2 itself supports a file date since 1980 year.
2. OS/2 itself supports even seconds for a file time.
3. utimes() of OS/2 kLIBC does not work on an opened file.
* m4/utimes.m4: Detect utimes() correctly on OS/2 kLIBC.
---
m4/utimes.m4 | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
Updated to consider local time correctly.
--
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
KO Myung-Hun
2014-12-09 01:40:55 UTC
Permalink
And warn about it.

* gnulib-tool (have_symlink_support): New.
(symbolic, lsymbolic): Clear on systems not supporting symbolic link.
---
gnulib-tool | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/gnulib-tool b/gnulib-tool
index 2641378..c5a4c87 100755
--- a/gnulib-tool
+++ b/gnulib-tool
@@ -898,6 +898,16 @@ if test "X$1" = "X--no-reexec"; then
shift
fi

+# Check if symbolic link is supported
+have_symlink_support=false
+rm -f symlink$$.file symlink$$
+if (echo >symlink$$.file) 2>/dev/null; then
+ if ln -s symlink$$.file symlink$$ 2>/dev/null; then
+ have_symlink_support=true
+ fi
+fi
+rm -f symlink$$.file symlink$$
+
# Unset CDPATH. Otherwise, output from 'cd dir' can surprise callers.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

@@ -1355,6 +1365,16 @@ fi
echo "gnulib-tool: option --conditional-dependencies is not supported with --with-tests" 1>&2
func_exit 1
fi
+ # Warn if symbolic link is requested on a system not supporting it.
+ # And fall back into copy.
+ if { test -n "$symbolic" || test -n "$lsymbolic" ; } \
+ && ! $have_symlink_support ; then
+ echo "gnulib-tool: symbolic link is not supported on this system." 1>&2
+ echo "Copy will be performed instead." 1>&2
+
+ symbolic=
+ lsymbolic=
+ fi

# Determine the minimum supported autoconf version from the project's
# configure.ac.
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:56 UTC
Permalink
Pipes on kLIBC does not support O_NONBLOCK like Win32.

* lib/pipe-filter-ii.c (start_wrapper, _beginthreadex, CloseHandle,
WaiForSingleObject, WaitForMultipleObjects): New on OS/2 kLIBC.
Reuse Win32 codes on OS/2 kLIBC.
* lib/spawn-pipe.c: Reuse Win32 codes on OS/2 kLIBC.
* lib/w32spawn.h: Do not include windows.h on OS/2 kLIBC.
---
lib/pipe-filter-ii.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++--
lib/spawn-pipe.c | 6 ++-
lib/w32spawn.h | 6 ++-
3 files changed, 137 insertions(+), 8 deletions(-)

diff --git a/lib/pipe-filter-ii.c b/lib/pipe-filter-ii.c
index db398d2..27037e5 100644
--- a/lib/pipe-filter-ii.c
+++ b/lib/pipe-filter-ii.c
@@ -27,6 +27,127 @@
#include <unistd.h>
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# include <windows.h>
+#elif defined __KLIBC__
+# define INCL_DOS
+# include <os2.h>
+
+/* Simple implementation of Win32 APIs */
+
+# define WINAPI
+
+typedef struct _HANDLE
+{
+ TID tid;
+ HEV hevDone;
+ unsigned int WINAPI (*start) (void *);
+ void *arg;
+} *HANDLE;
+
+typedef ULONG DWORD;
+
+static void
+start_wrapper (void *arg)
+{
+ HANDLE h = (HANDLE) arg;
+
+ h->start (h->arg);
+
+ DosPostEventSem (h->hevDone);
+ _endthread ();
+}
+
+static HANDLE
+_beginthreadex (void *s, unsigned n, unsigned int WINAPI (*start) (void *),
+ void *arg, unsigned fl, unsigned *th)
+{
+ HANDLE h;
+
+ h = malloc (sizeof (*h));
+ if (!h)
+ return NULL;
+
+ if (DosCreateEventSem (NULL, &h->hevDone, 0, FALSE ))
+ goto exit_free;
+
+ h->start = start;
+ h->arg = arg;
+
+ h->tid = _beginthread (start_wrapper, NULL, n, (void *) h);
+ if (h->tid == -1)
+ goto exit_close_event_sem;
+
+ return h;
+
+exit_close_event_sem:
+ DosCloseEventSem (h->hevDone);
+
+exit_free:
+ free (h);
+
+ return NULL;
+}
+
+static BOOL
+CloseHandle (HANDLE h)
+{
+ DosCloseEventSem (h->hevDone);
+ free (h);
+}
+
+# define _endthreadex(x) return (x)
+# define TerminateThread(h, e) DosKillThread (h->tid)
+
+# define GetLastError() -1
+
+# ifndef ERROR_NO_DATA
+# define ERROR_NO_DATA 232
+# endif
+
+# define INFINITE SEM_INDEFINITE_WAIT
+# define WAIT_OBJECT_0 0
+
+static DWORD
+WaitForSingleObject (HANDLE h, DWORD ms)
+{
+ return DosWaitEventSem (h->hevDone, ms) == 0 ? WAIT_OBJECT_0 : (DWORD) -1;
+}
+
+static DWORD
+WaitForMultipleObjects (DWORD nCount, const HANDLE *pHandles, BOOL bWaitAll,
+ DWORD ms)
+{
+ HMUX hmux;
+ PSEMRECORD psr;
+ ULONG ulUser;
+ ULONG rc = (ULONG) -1;
+ DWORD i;
+
+ psr = malloc (sizeof (*psr) * nCount);
+ if (!psr)
+ goto exit_return;
+
+ for (i = 0; i < nCount; ++i)
+ {
+ psr[i].hsemCur = (HSEM) pHandles[i]->hevDone;
+ psr[i].ulUser = WAIT_OBJECT_0 + i;
+ }
+
+ if (DosCreateMuxWaitSem (NULL, &hmux, nCount, psr,
+ bWaitAll ? DCMW_WAIT_ALL : DCMW_WAIT_ANY))
+ goto exit_free;
+
+ rc = DosWaitMuxWaitSem (hmux, ms, &ulUser);
+ DosCloseMuxWaitSem (hmux);
+
+exit_free:
+ free (psr);
+
+exit_return:
+ if (rc)
+ return (DWORD) -1;
+
+ return ulUser;
+}
#else
# include <signal.h>
# include <sys/select.h>
@@ -41,7 +162,8 @@

#include "pipe-filter-aux.h"

-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ \
+ || defined __KLIBC__

struct locals
{
@@ -143,7 +265,8 @@ pipe_filter_ii_execute (const char *progname,
{
pid_t child;
int fd[2];
-#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ \
+ || defined __KLIBC__)
struct sigaction orig_sigpipe_action;
#endif

@@ -154,7 +277,8 @@ pipe_filter_ii_execute (const char *progname,
if (child == -1)
return -1;

-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ \
+ || defined __KLIBC__
/* Native Windows API. */
/* Pipes have a non-blocking mode, see function SetNamedPipeHandleState and
the article "Named Pipe Type, Read, and Wait Modes", but Microsoft's
@@ -462,7 +586,8 @@ pipe_filter_ii_execute (const char *progname,
{
int saved_errno = errno;
close (fd[1]);
-#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ \
+ || defined __KLIBC__)
if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
abort ();
#endif
diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c
index 656980d..ab7cc18 100644
--- a/lib/spawn-pipe.c
+++ b/lib/spawn-pipe.c
@@ -35,7 +35,8 @@

#define _(str) gettext (str)

-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ \
+ || defined __KLIBC__

/* Native Windows API. */
# include <process.h>
@@ -109,7 +110,8 @@ create_pipe (const char *progname,
bool slave_process, bool exit_on_error,
int fd[2])
{
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ \
+ || defined __KLIBC__

/* Native Windows API.
This uses _pipe(), dup2(), and spawnv(). It could also be implemented
diff --git a/lib/w32spawn.h b/lib/w32spawn.h
index 16f1251..1346773 100644
--- a/lib/w32spawn.h
+++ b/lib/w32spawn.h
@@ -15,9 +15,11 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */

+#ifndef __KLIBC__
/* Get declarations of the native Windows API functions. */
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif

/* Get _open_osfhandle(). */
#include <io.h>
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:57 UTC
Permalink
On OS/2, there are maximum 26 CWDs, one CWD per drive[A to Z]. So
it is needed to save and restore all of them as well as a CWD of a
current drive.

For examples,

1. CWD is C:\CWD
2. Call save_cwd()
3. Change drive to drive D: whose CWD was D:\
4. Change directory to D:\CWD
5. Now, CWD is D:\CWD
6. Call restore_cwd()
7. Now CWD is C:\CWD. But CWD of drive D: is still D:\CWD not D:\.

* lib/save-cwd.c (save_cwd): Save all CWDs of each drive.
(restore_cwd): Restore all CWDs of each drive.
(free_cwd): Free allocated name_with_drvie.
* lib/save-cwd.h (struct save_cwd): Add current_drive and
name_with_drive member.
---
lib/save-cwd.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/save-cwd.h | 4 ++++
2 files changed, 54 insertions(+)

diff --git a/lib/save-cwd.c b/lib/save-cwd.c
index 7aafacd..5eca000 100644
--- a/lib/save-cwd.c
+++ b/lib/save-cwd.c
@@ -62,6 +62,36 @@
int
save_cwd (struct saved_cwd *cwd)
{
+#ifdef __EMX__
+ /* On OS/2, there are maximum 26 CWDs, one CWD per drive[A to Z]. Here save
+ all the CWDs of each drive. */
+
+ char drive;
+
+ /* Save a current drive. */
+ cwd->current_drive = _getdrive ();
+
+ /* Save CWD with a drive name of each drive. */
+ for (drive = 0; drive <= 'Z' - 'A'; drive++)
+ {
+ /* _chdrive() always returns 0. */
+ _chdrive (drive + 'A');
+
+ /* Ignore ENOENT due to empty removable drives such as CD-ROM. */
+ if (!(cwd->name_with_drive[drive] = _getcwd2 (NULL, 0))
+ && errno == ENOMEM)
+ {
+ while (drive-- > 0)
+ free (cwd->name_with_drive[drive]);
+
+ return -1;
+ }
+ }
+
+ /* Restore a current drive. */
+ _chdrive (cwd->current_drive);
+#endif
+
cwd->name = NULL;

cwd->desc = open (".", O_SEARCH);
@@ -84,6 +114,19 @@ save_cwd (struct saved_cwd *cwd)
int
restore_cwd (const struct saved_cwd *cwd)
{
+#ifdef __EMX__
+ char drive;
+
+ /* Restore CWD of each drive. */
+ for (drive = 0; drive <= 'Z' - 'A'; drive++)
+ if (cwd->name_with_drive[drive])
+ if (chdir_long (cwd->name_with_drive[drive]))
+ return -1;
+
+ /* Restore a current drive. */
+ _chdrive (cwd->current_drive);
+#endif
+
if (0 <= cwd->desc)
return fchdir (cwd->desc);
else
@@ -93,6 +136,13 @@ restore_cwd (const struct saved_cwd *cwd)
void
free_cwd (struct saved_cwd *cwd)
{
+#ifdef __EMX__
+ char drive;
+
+ for (drive = 0; drive <= 'Z' - 'A'; drive++)
+ free (cwd->name_with_drive[drive]);
+#endif
+
if (cwd->desc >= 0)
close (cwd->desc);
free (cwd->name);
diff --git a/lib/save-cwd.h b/lib/save-cwd.h
index 6b84e46..492772f 100644
--- a/lib/save-cwd.h
+++ b/lib/save-cwd.h
@@ -25,6 +25,10 @@ struct saved_cwd
{
int desc;
char *name;
+# ifdef __EMX__
+ char current_drive;
+ char *name_with_drive['Z' - 'A' + 1]; /* for drive A to Z */
+# endif
};

int save_cwd (struct saved_cwd *cwd);
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:58 UTC
Permalink
On OS/2 kLIBC, dup(), dup2() and fcntl() do not work on a directory
fd.

* lib/dup.c (dup_nothrow): New.
* lib/dup2.c (klibc_dup2dirfd): New. dup2() for a directory fd.
(klibc_dup2): New.
* lib/fcntl.c (klibc_fcntl): New.
* m4/dup.m4 (gl_FUNC_DUP): Check if dup() works on a directory fd.
* m4/dup2.m4 (gl_FUNC_DUP2): Check if dup2() works on a directory fd.
* m4/fcntl.m4 (gl_FUNC_FCNTL): Check if F_DUPFD works on a directory
fd.
---
lib/dup.c | 25 ++++++++++++++++++
lib/dup2.c | 51 ++++++++++++++++++++++++++++++++++++
lib/fcntl.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
m4/dup.m4 | 30 ++++++++++++++++++++-
m4/dup2.m4 | 15 ++++++++++-
m4/fcntl.m4 | 14 +++++++++-
6 files changed, 219 insertions(+), 3 deletions(-)

diff --git a/lib/dup.c b/lib/dup.c
index c813df6..a2e43ec 100644
--- a/lib/dup.c
+++ b/lib/dup.c
@@ -45,6 +45,31 @@ dup_nothrow (int fd)

return result;
}
+#elif defined __KLIBC__
+# include <fcntl.h>
+# include <sys/stat.h>
+
+# include <InnoTekLIBC/backend.h>
+
+static int
+dup_nothrow (int fd)
+{
+ int dupfd;
+ struct stat sbuf;
+
+ dupfd = dup (fd);
+ if (dupfd == -1 && errno == ENOTSUP \
+ && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode))
+ {
+ char path[_MAX_PATH];
+
+ /* Get a path from fd */
+ if (!__libc_Back_ioFHToPath (fd, path, sizeof (path)))
+ dupfd = open (path, O_RDONLY);
+ }
+
+ return dupfd;
+}
#else
# define dup_nothrow dup
#endif
diff --git a/lib/dup2.c b/lib/dup2.c
index 7de6805..a1fff0a 100644
--- a/lib/dup2.c
+++ b/lib/dup2.c
@@ -85,6 +85,57 @@ ms_windows_dup2 (int fd, int desired_fd)

# define dup2 ms_windows_dup2

+# elif defined __KLIBC__
+
+# include <InnoTekLIBC/backend.h>
+
+static int
+klibc_dup2dirfd (int fd, int desired_fd)
+{
+ int tempfd;
+ int dupfd;
+
+ tempfd = open ("NUL", O_RDONLY);
+ if (tempfd == -1)
+ return -1;
+
+ if (tempfd == desired_fd)
+ {
+ close (tempfd);
+
+ char path[_MAX_PATH];
+ if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
+ return -1;
+
+ return open(path, O_RDONLY);
+ }
+
+ dupfd = klibc_dup2dirfd (fd, desired_fd);
+
+ close (tempfd);
+
+ return dupfd;
+}
+
+static int
+klibc_dup2 (int fd, int desired_fd)
+{
+ int dupfd;
+ struct stat sbuf;
+
+ dupfd = dup2 (fd, desired_fd);
+ if (dupfd == -1 && errno == ENOTSUP \
+ && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode))
+ {
+ close (desired_fd);
+
+ return klibc_dup2dirfd (fd, desired_fd);
+ }
+
+ return dupfd;
+}
+
+# define dup2 klibc_dup2
# endif

int
diff --git a/lib/fcntl.c b/lib/fcntl.c
index 1e35dd1..1f88b95 100644
--- a/lib/fcntl.c
+++ b/lib/fcntl.c
@@ -162,6 +162,93 @@ dupfd (int oldfd, int newfd, int flags)
}
#endif /* W32 */

+#ifdef __KLIBC__
+
+# define INCL_DOS
+# include <os2.h>
+
+static int
+klibc_fcntl (int fd, int action, /* arg */...)
+{
+ va_list arg_ptr;
+ int arg;
+ struct stat sbuf;
+ int result = -1;
+
+ va_start (arg_ptr, action);
+ arg = va_arg (arg_ptr, int);
+ result = fcntl (fd, action, arg);
+ /* EPERM for F_DUPFD, ENOTSUP for others */
+ if (result == -1 && (errno == EPERM || errno == ENOTSUP) \
+ && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode))
+ {
+ ULONG ulMode;
+
+ switch (action)
+ {
+ case F_DUPFD:
+ /* Find available fd */
+ while (fcntl (arg, F_GETFL) != -1 || errno != EBADF)
+ arg++;
+
+ result = dup2 (fd, arg);
+ break;
+
+ /* Using underlying APIs is right ? */
+ case F_GETFD:
+ if (DosQueryFHState (fd, &ulMode))
+ break;
+
+ result = (ulMode & OPEN_FLAGS_NOINHERIT) ? FD_CLOEXEC : 0;
+ break;
+
+ case F_SETFD:
+ if (arg & ~FD_CLOEXEC)
+ break;
+
+ if (DosQueryFHState (fd, &ulMode))
+ break;
+
+ if (arg & FD_CLOEXEC)
+ ulMode |= OPEN_FLAGS_NOINHERIT;
+ else
+ ulMode &= ~OPEN_FLAGS_NOINHERIT;
+
+ /* Filter supported flags. */
+ ulMode &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR \
+ | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT;
+
+ if (DosSetFHState (fd, ulMode))
+ break;
+
+ result = 0;
+ break;
+
+ case F_GETFL:
+ result = 0;
+ break;
+
+ case F_SETFL:
+ if (arg != 0)
+ break;
+
+ result = 0;
+ break;
+
+ default :
+ errno = EINVAL;
+ break;
+ }
+ }
+
+ va_end (arg_ptr);
+
+ return result;
+}
+
+# define fcntl klibc_fcntl
+#endif
+
/* Perform the specified ACTION on the file descriptor FD, possibly
using the argument ARG further described below. This replacement
handles the following actions, and forwards all others on to the
diff --git a/m4/dup.m4 b/m4/dup.m4
index 9393bc5..03ee089 100644
--- a/m4/dup.m4
+++ b/m4/dup.m4
@@ -1,4 +1,4 @@
-# dup.m4 serial 3
+# dup.m4 serial 4
dnl Copyright (C) 2011-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,34 @@ AC_DEFUN([gl_FUNC_DUP],
REPLACE_DUP=1
fi
])
+ AC_CACHE_CHECK([whether dup works], [gl_cv_func_dup_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>]],
+ [int result = 0;
+ int fd;
+
+ /* On OS/2 kLIBC, dup() does not work on a directory fd. */
+ fd = open (".", O_RDONLY);
+ if (fd == -1)
+ result |= 1;
+ else if (dup (fd) == -1 )
+ result |= 2;
+
+ close (fd);
+
+ return result;
+ ])
+ ],
+ [gl_cv_func_dup_works=yes], [gl_cv_func_dup_works=no])
+ ])
+ case "$gl_cv_func_dup_works" in
+ *yes) ;;
+ *)
+ REPLACE_DUP=1
+ ;;
+ esac
])

# Prerequisites of lib/dup.c.
diff --git a/m4/dup2.m4 b/m4/dup2.m4
index 6498fc2..a9b1873 100644
--- a/m4/dup2.m4
+++ b/m4/dup2.m4
@@ -1,4 +1,4 @@
-#serial 20
+#serial 21
dnl Copyright (C) 2002, 2005, 2007, 2009-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -50,6 +50,17 @@ AC_DEFUN([gl_FUNC_DUP2],
result |= 32;
dup2 (2, 255);
dup2 (2, 256);
+ /* On OS/2 kLIBC, dup2() does not work on a directory fd. */
+ {
+ int fd = open (".", O_RDONLY);
+ if (fd == -1)
+ result |= 64;
+ else if (dup2 (fd, fd + 1) == -1 )
+ result |= 128;
+
+ close (fd);
+ }
+
return result;
])
],
@@ -68,6 +79,8 @@ AC_DEFUN([gl_FUNC_DUP2],
gl_cv_func_dup2_works="guessing no" ;;
haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC.
gl_cv_func_dup2_works="guessing no" ;;
+ os2*) # on OS/2 kLIBC, dup2() does not work on a directory fd.
+ gl_cv_func_dup2_works="guessing no" ;;
*) gl_cv_func_dup2_works="guessing yes" ;;
esac])
])
diff --git a/m4/fcntl.m4 b/m4/fcntl.m4
index f824beb..009c520 100644
--- a/m4/fcntl.m4
+++ b/m4/fcntl.m4
@@ -1,4 +1,4 @@
-# fcntl.m4 serial 5
+# fcntl.m4 serial 6
dnl Copyright (C) 2009-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -43,6 +43,18 @@ AC_DEFUN([gl_FUNC_FCNTL],
if (errno != EINVAL) result |= 2;
if (fcntl (0, F_DUPFD, bad_fd) != -1) result |= 4;
if (errno != EINVAL) result |= 8;
+ /* On OS/2 kLIBC, F_DUPFD does not work on a directory fd */
+ {
+ int fd;
+ fd = open (".", O_RDONLY);
+ if (fd == -1)
+ result |= 16;
+ else if (fcntl (fd, F_DUPFD, STDERR_FILENO + 1) == -1)
+ result |= 32;
+
+ close (fd);
+ }
+
return result;
]])],
[gl_cv_func_fcntl_f_dupfd_works=yes],
--
1.8.5.2
KO Myung-Hun
2014-12-09 01:40:59 UTC
Permalink
* lib/closedir.c (closedir): Unregister fd if closedir() succeeds.
* lib/dirent.in.h (_gl_register_dirp_fd, _gl_unregister_dirp_fd):
Declare on kLIBC.
* lib/dirfd.c (struct dirp_fd_list): New. Structures to keep track of
fd associated with dirp.
(_gl_register_dirp_fd): New. Register fd associated with dirp to
dirp_fd_list.
(_gl_unregister_dirp_fd): New. Unregister fd with closing it.
(dirfd): Implemented for kLIBC.
* lib/fdopendir.c (fdopendir): Implemented for kLIBC.
* lib/opendir.c (opendir): New. Register fd and dirp pair if open()
succeeds.
* m4/closedir.m4 (gl_FUNC_CLOSEDIR): Replace if OS/2.
* m4/dirfd.m4 (gl_FUNC_DIRFD): Likewise.
* m4/opendir.m4 (gl_FUNC_OPENDIR): Likewise.
* modules/closedir (Depends-on): Add dirfd.
* modules/dirfd (Depends-on): Add 'test $REPLACE_DIRFD = 1' to errno
condition.
(configure.ac): Add dirfd to LIBOBJS if $REPLACE_DIRFD = 1 as well.
* modules/fdopendir (Depends-on): Add dirfd.
* modules/opendir (Depends-on): Add dirfd.
---
lib/closedir.c | 6 ++++-
lib/dirent.in.h | 7 ++++++
lib/dirfd.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/fdopendir.c | 36 +++++++++++++++++++++++++++++
lib/opendir.c | 21 +++++++++++++++++
m4/closedir.m4 | 9 +++++++-
m4/dirfd.m4 | 8 ++++---
m4/opendir.m4 | 9 +++++++-
modules/closedir | 1 +
modules/dirfd | 5 ++--
modules/fdopendir | 1 +
modules/opendir | 1 +
12 files changed, 164 insertions(+), 8 deletions(-)

diff --git a/lib/closedir.c b/lib/closedir.c
index 940c6f9..b40181c 100644
--- a/lib/closedir.c
+++ b/lib/closedir.c
@@ -39,7 +39,7 @@
int
closedir (DIR *dirp)
{
-# if REPLACE_FCHDIR
+# if REPLACE_FCHDIR || defined __KLIBC__
int fd = dirfd (dirp);
# endif
int retval;
@@ -49,6 +49,10 @@ closedir (DIR *dirp)

retval = closedir (dirp);

+# ifdef __KLIBC__
+ if (!retval)
+ _gl_unregister_dirp_fd (fd);
+# endif
#else

if (dirp->current != INVALID_HANDLE_VALUE)
diff --git a/lib/dirent.in.h b/lib/dirent.in.h
index 4822d6b..cce86d9 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -156,6 +156,13 @@ _GL_WARN_ON_USE (closedir, "closedir is not portable - "
# endif
_GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_RPL (dirfd, int, (DIR *));
+
+# ifdef __KLIBC__
+/* Gnulib internal hooks needed to maintain the dirfd metadata. */
+_GL_EXTERN_C int _gl_register_dirp_fd (int fd, DIR *dirp)
+ _GL_ARG_NONNULL ((2));
+_GL_EXTERN_C void _gl_unregister_dirp_fd (int fd);
+# endif
# else
# if defined __cplusplus && defined GNULIB_NAMESPACE && defined dirfd
/* dirfd is defined as a macro and not as a function.
diff --git a/lib/dirfd.c b/lib/dirfd.c
index 4d37928..aa6514f 100644
--- a/lib/dirfd.c
+++ b/lib/dirfd.c
@@ -22,11 +22,79 @@
#include <dirent.h>
#include <errno.h>

+#ifdef __KLIBC__
+# include <stdlib.h>
+# include <io.h>
+
+static struct dirp_fd_list
+{
+ DIR *dirp;
+ int fd;
+ struct dirp_fd_list *next;
+} *dirp_fd_start = NULL;
+
+/* Register fd associated with dirp to dirp_fd_list. */
+int
+_gl_register_dirp_fd (int fd, DIR *dirp)
+{
+ struct dirp_fd_list *new_dirp_fd;
+
+ new_dirp_fd = malloc (sizeof (*new_dirp_fd));
+ if (!new_dirp_fd)
+ return -1;
+
+ new_dirp_fd->dirp = dirp;
+ new_dirp_fd->fd = fd;
+ new_dirp_fd->next = dirp_fd_start;
+
+ dirp_fd_start = new_dirp_fd;
+
+ return 0;
+}
+
+/* Unregister fd from dirp_fd_list with closing it */
+void
+_gl_unregister_dirp_fd (int fd)
+{
+ struct dirp_fd_list *dirp_fd;
+ struct dirp_fd_list *dirp_fd_prev;
+
+ for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd;
+ dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next)
+ {
+ if (dirp_fd->fd == fd)
+ {
+ if (dirp_fd_prev)
+ dirp_fd_prev->next = dirp_fd->next;
+ else /* dirp_fd == dirp_fd_start */
+ dirp_fd_start = dirp_fd_start->next;
+
+ close (fd);
+ free (dirp_fd);
+ break;
+ }
+ }
+}
+#endif
+
int
dirfd (DIR *dir_p)
{
int fd = DIR_TO_FD (dir_p);
if (fd == -1)
+#ifndef __KLIBC__
errno = ENOTSUP;
+#else
+ {
+ struct dirp_fd_list *dirp_fd;
+
+ for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next)
+ if (dirp_fd->dirp == dir_p)
+ return dirp_fd->fd;
+
+ errno = EINVAL;
+ }
+#endif
+
return fd;
}
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index b6c94a0..80ec4cf 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -62,6 +62,41 @@ static DIR *fd_clone_opendir (int, struct saved_cwd const *);
If this function returns successfully, FD is under control of the
dirent.h system, and the caller should not close or modify the state of
FD other than by the dirent.h functions. */
+# ifdef __KLIBC__
+# include <InnoTekLIBC/backend.h>
+
+DIR *
+fdopendir (int fd)
+{
+ char path[_MAX_PATH];
+ DIR *dirp;
+
+ /* Get a path from fd */
+ if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
+ return NULL;
+
+ dirp = opendir (path);
+ if (!dirp)
+ return NULL;
+
+ /* Unregister fd registered by opendir() */
+ _gl_unregister_dirp_fd (dirfd (dirp));
+
+ /* Register our fd */
+ if (_gl_register_dirp_fd (fd, dirp))
+ {
+ int saved_errno = errno;
+
+ closedir (dirp);
+
+ errno = saved_errno;
+
+ dirp = NULL;
+ }
+
+ return dirp;
+}
+# else
DIR *
fdopendir (int fd)
{
@@ -84,6 +119,7 @@ fdopendir (int fd)

return dir;
}
+# endif

/* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known
to be a dup of FD which is less than FD - 1 and which will be
diff --git a/lib/opendir.c b/lib/opendir.c
index c67f2e5..064e699 100644
--- a/lib/opendir.c
+++ b/lib/opendir.c
@@ -40,6 +40,11 @@
# include <unistd.h>
#endif

+#ifdef __KLIBC__
+# include <io.h>
+# include <fcntl.h>
+#endif
+
DIR *
opendir (const char *dir_name)
{
@@ -51,6 +56,22 @@ opendir (const char *dir_name)
if (dirp == NULL)
return NULL;

+# ifdef __KLIBC__
+ {
+ int fd = open (dir_name, O_RDONLY);
+ if (fd == -1 || _gl_register_dirp_fd (fd, dirp))
+ {
+ int saved_errno = errno;
+
+ close (fd);
+ closedir (dirp);
+
+ errno = saved_errno;
+
+ return NULL;
+ }
+ }
+# endif
#else

char dir_name_mask[MAX_PATH + 1 + 1 + 1];
diff --git a/m4/closedir.m4 b/m4/closedir.m4
index d234a52..206f5f8 100644
--- a/m4/closedir.m4
+++ b/m4/closedir.m4
@@ -1,4 +1,4 @@
-# closedir.m4 serial 2
+# closedir.m4 serial 3
dnl Copyright (C) 2011-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -22,4 +22,11 @@ AC_DEFUN([gl_FUNC_CLOSEDIR],
fi
fi
])
+ dnl Replace closedir() on OS/2 kLIBC for support dirfd() function replaced
+ dnl by gnulib.
+ if test -z "${host_os##os2*}"; then
+ if test $HAVE_OPENDIR = 1; then
+ REPLACE_OPENDIR=1
+ fi
+ fi
])
diff --git a/m4/dirfd.m4 b/m4/dirfd.m4
index b422769..1de121a 100644
--- a/m4/dirfd.m4
+++ b/m4/dirfd.m4
@@ -1,4 +1,4 @@
-# serial 22 -*- Autoconf -*-
+# serial 23 -*- Autoconf -*-

dnl Find out how to get the file descriptor associated with an open DIR*.

@@ -35,8 +35,10 @@ AC_DEFUN([gl_FUNC_DIRFD],
gl_cv_func_dirfd_macro=yes,
gl_cv_func_dirfd_macro=no)])

- # Use the replacement only if we have no function or macro with that name.
- if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
+ # Use the replacement if we have no function or macro with that name,
+ # or if OS/2 kLIBC whose dirfd() does not work.
+ if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no \
+ || test -z "${host_os##os2*}" ; then
if test $ac_cv_have_decl_dirfd = yes; then
# If the system declares dirfd already, let's declare rpl_dirfd instead.
REPLACE_DIRFD=1
diff --git a/m4/opendir.m4 b/m4/opendir.m4
index fa29c64..4dcba85 100644
--- a/m4/opendir.m4
+++ b/m4/opendir.m4
@@ -1,4 +1,4 @@
-# opendir.m4 serial 2
+# opendir.m4 serial 3
dnl Copyright (C) 2011-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -22,4 +22,11 @@ AC_DEFUN([gl_FUNC_OPENDIR],
fi
fi
])
+ dnl Replace opendir() on OS/2 kLIBC to support dirfd() function replaced
+ dnl by gnulib.
+ if test -z "${host_os##os2*}"; then
+ if test $HAVE_OPENDIR = 1; then
+ REPLACE_OPENDIR=1
+ fi
+ fi
])
diff --git a/modules/closedir b/modules/closedir
index 8fb9645..0763878 100644
--- a/modules/closedir
+++ b/modules/closedir
@@ -8,6 +8,7 @@ m4/closedir.m4

Depends-on:
dirent
+dirfd [test $HAVE_CLOSEDIR = 0 || test $REPLACE_CLOSEDIR = 1]

configure.ac:
gl_FUNC_CLOSEDIR
diff --git a/modules/dirfd b/modules/dirfd
index 1c6d26f..0ad0bf4 100644
--- a/modules/dirfd
+++ b/modules/dirfd
@@ -8,11 +8,12 @@ m4/dirfd.m4
Depends-on:
dirent
extensions
-errno [test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no]
+errno [test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no || test $REPLACE_DIRFD = 1]

configure.ac:
gl_FUNC_DIRFD
-if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
+if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no \
+ || test $REPLACE_DIRFD = 1; then
AC_LIBOBJ([dirfd])
gl_PREREQ_DIRFD
fi
diff --git a/modules/fdopendir b/modules/fdopendir
index ee9a875..0606e5d 100644
--- a/modules/fdopendir
+++ b/modules/fdopendir
@@ -16,6 +16,7 @@ fstat [test $HAVE_FDOPENDIR = 0]
openat-die [test $HAVE_FDOPENDIR = 0]
opendir [test $HAVE_FDOPENDIR = 0]
save-cwd [test $HAVE_FDOPENDIR = 0]
+dirfd [test $HAVE_FDOPENDIR = 0]

configure.ac:
gl_FUNC_FDOPENDIR
diff --git a/modules/opendir b/modules/opendir
index cfb9e1a..8192853 100644
--- a/modules/opendir
+++ b/modules/opendir
@@ -12,6 +12,7 @@ largefile
filename [test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1]
unistd [test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1]
closedir [test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1]
+dirfd [test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1]

configure.ac:
gl_FUNC_OPENDIR
--
1.8.5.2
Loading...