Discussion:
[PATCH v7 08/11] openat_proc_name: port to OS/2 kLIBC
KO Myung-Hun
2016-01-14 02:23:48 UTC
Permalink
OS/2 kLIBC provides a function to retrive a path from a fd. Use it
instead of /proc/self/fd.

* lib/openat-proc.c (openat_proc_name): Port to OS/2 kLIBC with
__libc_Back_ioFHToPath().
---
lib/openat-proc.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)

diff --git a/lib/openat-proc.c b/lib/openat-proc.c
index 15a8c79..db34244 100644
--- a/lib/openat-proc.c
+++ b/lib/openat-proc.c
@@ -30,6 +30,10 @@
#include <string.h>
#include <unistd.h>

+#ifdef __KLIBC__
+# include <InnoTekLIBC/backend.h>
+#endif
+
#include "intprops.h"

#define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/%s"
@@ -56,6 +60,7 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file)
return buf;
}

+#ifndef __KLIBC__
if (! proc_status)
{
/* Set PROC_STATUS to a positive value if /proc/self/fd is
@@ -99,4 +104,28 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file)
sprintf (result, PROC_SELF_FD_FORMAT, fd, file);
return result;
}
+#else
+ /* OS/2 kLIBC provides a function to retrieve a path from a fd. Use it. */
+ {
+ char path[_MAX_PATH];
+ size_t bufsize;
+ char *result = buf;
+
+ /* Get a path from a fd */
+ if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
+ return NULL;
+
+ bufsize = strlen (path) + 1 + strlen (file) + 1; /* 1 for '/', 1 for null */
+ if (OPENAT_BUFFER_SIZE < bufsize)
+ {
+ result = malloc (bufsize);
+ if (! result)
+ return NULL;
+ }
+
+ sprintf (result, "%s/%s", path, file);
+
+ return result;
+ }
+#endif
}
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:51 UTC
Permalink
And warn about it only once.

* gnulib-tool (first_fall_back_to_cp_warn): New. Indicator for only
once warning about falling back to cp -p.
(func_ln_s): New. Fall back into cp -p if ln -s fails. And warn about
this only once.
(func_ln): Replace ln -s with func_ln_s.
---
gnulib-tool | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/gnulib-tool b/gnulib-tool
index 34676f9..2c7d9d3 100755
--- a/gnulib-tool
+++ b/gnulib-tool
@@ -767,23 +767,50 @@ func_relconcat ()
done
}

+first_fall_back_to_cp_warn=true
+
+# func_ln_s SRC DEST
+# Like ln -s, except that cp -p is used if ln -s fails.
+func_ln_s ()
+{
+ if ln -s "$1" "$2" 2>/dev/null; then
+ :
+ else
+ if $first_fall_back_to_cp_warn; then
+ echo "gnulib-tool: symbolic link is not supported on this system." 1>&2
+ echo "Copy will be performed instead." 1>&2
+
+ first_fall_back_to_cp_warn=false
+ fi
+
+ case "$1" in
+ /* | ?:*) # SRC is absolute.
+ cp_src="$1" ;;
+ *) # SRC is relative to the directory of DEST.
+ cp_src="`echo "$2" | sed -e 's,\(^.*\)/[^/]*$,\1,'`/$1" ;;
+ esac
+
+ cp -p "$cp_src" "$2"
+ fi
+}
+
# func_ln SRC DEST
-# Like ln -s, except that SRC is given relative to the current directory (or
+# Like func_ln_s, except that SRC is given relative to the current directory (or
# absolute), not given relative to the directory of DEST.
func_ln ()
{
case "$1" in
/* | ?:*)
- ln -s "$1" "$2" ;;
+ func_ln_s "$1" "$2" ;;
*) # SRC is relative.
case "$2" in
/* | ?:*)
- ln -s "`pwd`/$1" "$2" ;;
+ func_ln_s "`pwd`/$1" "$2" ;;
*) # DEST is relative too.
ln_destdir=`echo "$2" | sed -e 's,[^/]*$,,'`
test -n "$ln_destdir" || ln_destdir="."
func_relativize "$ln_destdir" "$1"
- ln -s "$reldir" "$2"
+ func_ln_s "$reldir" "$2"
;;
esac
;;
--
2.7.0
Paul Eggert
2016-01-15 00:34:56 UTC
Permalink
Post by KO Myung-Hun
+ *) # SRC is relative to the directory of DEST.
+ cp_src="`echo "$2" | sed -e 's,\(^.*\)/[^/]*$,\1,'`/$1" ;;
Can we use parameter expansion instead? Something like this, say:

cp_src=${2%/*}/$1
KO Myung-Hun
2016-01-15 04:19:08 UTC
Permalink
Post by Paul Eggert
Post by KO Myung-Hun
+ *) # SRC is relative to the directory of DEST.
+ cp_src="`echo "$2" | sed -e 's,\(^.*\)/[^/]*$,\1,'`/$1" ;;
cp_src=${2%/*}/$1
Updated.
--
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
Paul Eggert
2016-01-15 18:14:36 UTC
Permalink
Thanks, I installed the attached somewhat-different patch instead.
Please give it a try. Also, I installed the other two gnulib patches
pretty much as-is.
KO Myung-Hun
2016-01-16 04:10:24 UTC
Permalink
Hi/2.
Post by Paul Eggert
Thanks, I installed the attached somewhat-different patch instead.
Please give it a try.
Works here. But it is different from my patch. My patch calls 'ln -s'
every time. And if it fails, fallback to 'cp -p'. However, the installed
patch seems to call 'ln -s'. If it fails only once, always fallback to
'cp -p'.

Some time ago, you reviewed my patch, and advised to do so because 'ln
-s' may succeed on some file systems, or may fail on another file systems.

Any idea ?
Post by Paul Eggert
Also, I installed the other two gnulib patches
pretty much as-is.
At last, all my OS/2 patches have been applied in almost two years.

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
Paul Eggert
2016-01-24 22:26:02 UTC
Permalink
Post by KO Myung-Hun
Some time ago, you reviewed my patch, and advised to do so because 'ln
-s' may succeed on some file systems, or may fail on another file systems.
Thanks for reminding me; I had forgotten about that consideration. I installed
the attached patch to fix this.
KO Myung-Hun
2016-01-25 02:48:51 UTC
Permalink
Post by Paul Eggert
Post by KO Myung-Hun
Some time ago, you reviewed my patch, and advised to do so because 'ln
-s' may succeed on some file systems, or may fail on another file systems.
Thanks for reminding me; I had forgotten about that consideration. I
installed the attached patch to fix this.
Thanks.

But, you said that it was enough to warn only once.
--
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
Paul Eggert
2016-01-25 03:21:59 UTC
Permalink
Post by KO Myung-Hun
But, you said that it was enough to warn only once.
True, and the current implementation doesn't have that nicety. However, it's not
essential to support it, and not all that important as gnulib-tool will be run
only rarely on file systems lacking symlinks.
KO Myung-Hun
2016-01-25 04:07:57 UTC
Permalink
Post by Paul Eggert
Post by KO Myung-Hun
But, you said that it was enough to warn only once.
True, and the current implementation doesn't have that nicety. However,
it's not essential to support it, and not all that important as
gnulib-tool will be run only rarely on file systems lacking symlinks.
OK.

Thanks a lot for your efforts.
--
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-06-08 12:46:43 UTC
Permalink
Post by Paul Eggert
Thanks, I installed the attached somewhat-different patch instead.
Please give it a try.
This func_ln_s has a bug: when both arguments are relative and the second one
is in the current directory, the copy source will be wrong. I.e.

func_ln_s a/b y

will essentially do

ln -s a/b y || cp -p y/a/b y

where the correct expansion is

ln -s a/b y || cp -p a/b y

Bruno


2017-06-08 Bruno Haible <***@clisp.org>

gnulib-tool: Fix bug in func_ln_s, from 2016-01-15.
* gnulib-tool (func_ln_s): Determine cp_src correctly.

diff --git a/gnulib-tool b/gnulib-tool
index a0dc037..e336466 100755
--- a/gnulib-tool
+++ b/gnulib-tool
@@ -784,9 +784,13 @@ func_ln_s ()

case "$1" in
/* | ?:*) # SRC is absolute.
- cp_src=$1 ;;
+ cp_src="$1" ;;
*) # SRC is relative to the directory of DEST.
- cp_src=${2%/*}/$1 ;;
+ case "$2" in
+ */*) cp_src="${2%/*}/$1" ;;
+ *) cp_src="$1" ;;
+ esac
+ ;;
esac

cp -p "$cp_src" "$2"
Myung-Hun KO
2017-06-08 13:42:28 UTC
Permalink
Thanks!
Post by Paul Eggert
Thanks, I installed the attached somewhat-different patch instead.
Please give it a try.
This func_ln_s has a bug: when both arguments are relative and the second
one
is in the current directory, the copy source will be wrong. I.e.

func_ln_s a/b y

will essentially do

ln -s a/b y || cp -p y/a/b y

where the correct expansion is

ln -s a/b y || cp -p a/b y

Bruno


2017-06-08 Bruno Haible <***@clisp.org>

gnulib-tool: Fix bug in func_ln_s, from 2016-01-15.
* gnulib-tool (func_ln_s): Determine cp_src correctly.

diff --git a/gnulib-tool b/gnulib-tool
index a0dc037..e336466 100755
--- a/gnulib-tool
+++ b/gnulib-tool
@@ -784,9 +784,13 @@ func_ln_s ()

case "$1" in
/* | ?:*) # SRC is absolute.
- cp_src=$1 ;;
+ cp_src="$1" ;;
*) # SRC is relative to the directory of DEST.
- cp_src=${2%/*}/$1 ;;
+ case "$2" in
+ */*) cp_src="${2%/*}/$1" ;;
+ *) cp_src="$1" ;;
+ esac
+ ;;
esac

cp -p "$cp_src" "$2"

KO Myung-Hun
2016-01-14 02:23:49 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.
(REPLACE_DIRFD): Define to 1 if replaced.
* 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/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 | 10 ++++++---
m4/opendir.m4 | 9 +++++++-
modules/closedir | 1 +
modules/dirfd | 5 +++--
modules/opendir | 1 +
11 files changed, 165 insertions(+), 8 deletions(-)

diff --git a/lib/closedir.c b/lib/closedir.c
index c0298bc..30d1290 100644
--- a/lib/closedir.c
+++ b/lib/closedir.c
@@ -39,7 +39,7 @@
int
closedir (DIR *dirp)
{
-# if REPLACE_FCHDIR
+# if REPLACE_FCHDIR || REPLACE_DIRFD
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 4c62737..65482d7 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -158,6 +158,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 1ea2a63..2b659f4 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 f30ab24..c1f4dcb 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 1b0e8f7..a135fd8 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 dab6673..4be0ebd 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-2016 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 e9532e6..8195b78 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,11 +35,15 @@ 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
+ AC_DEFINE([REPLACE_DIRFD], [1],
+ [Define to 1 if gnulib's dirfd() replacement is used.])
fi
fi
])
diff --git a/m4/opendir.m4 b/m4/opendir.m4
index 1181dde..2124f98 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-2016 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/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
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:50 UTC
Permalink
utimes() of OS/2 kLIBC has some limitations.

1. OS/2 itself supports a file date since 1980 year in local time.
2. OS/2 itself supports only 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.
* doc/posix-functions/utime.texi: Document the above limitations of
utimes() on OS/2 kLIBC.
---
doc/posix-functions/utime.texi | 7 +++++++
m4/utimes.m4 | 24 ++++++++++++++++--------
2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/doc/posix-functions/utime.texi b/doc/posix-functions/utime.texi
index 9cfe373..a0fb67d 100644
--- a/doc/posix-functions/utime.texi
+++ b/doc/posix-functions/utime.texi
@@ -27,4 +27,11 @@ On some platforms, the prototype for @code{utime} omits @code{const}
for the second argument. Fortunately, the argument is not modified,
so it is safe to cast away const:
mingw, MSVC 9.
+@item
+On OS/2, this funciton cannot set timestamp earlier than 1980 year in local
+time.
+@item
+On OS/2, this function cannot set timestamp in odd seconds.
+@item
+On OS/2, this function does not work on an opened file.
@end itemize
diff --git a/m4/utimes.m4 b/m4/utimes.m4
index a016723..9392203 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-2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
@@ -33,6 +33,7 @@ AC_DEFUN([gl_FUNC_UTIMES],
#include <stdlib.h>
#include <stdio.h>
#include <utime.h>
+#include <errno.h>

static int
inorder (time_t a, time_t b, time_t c)
@@ -45,7 +46,10 @@ 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 in local time
+ and even seconds. */
+ static struct timeval timeval[2] = {{315620000 + 10, 10},
+ {315620000 + 1000000, 999998}};

/* Test whether utimes() essentially works. */
{
@@ -82,15 +86,18 @@ main ()
result |= 1;
else if (fstat (fd, &st0) != 0)
result |= 1;
+ else if (write (fd, "\n", 1) != 1)
+ result |= 1;
+ else if (fstat (fd, &st1) != 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)
- result |= 1;
- else if (write (fd, "\n", 1) != 1)
- result |= 1;
- else if (fstat (fd, &st2) != 0)
+ else if (lstat (file, &st2) != 0)
result |= 1;
else if (time (&t2) == (time_t) -1)
result |= 1;
@@ -103,7 +110,8 @@ main ()
if (! (m_ok_POSIX || m_ok_NFS))
result |= 32;
}
- if (close (fd) != 0)
+ /* Ensure to close fd, but ignore an error if already closed. */
+ if (close (fd) != 0 && errno != EBADF)
result |= 1;
}
if (unlink (file) != 0)
--
2.7.0
Paul Eggert
2016-01-15 00:19:33 UTC
Permalink
Post by KO Myung-Hun
+On OS/2, this funciton cannot set timestamp earlier than 1980 year in local
+time.
+On OS/2, this function cannot set timestamp in odd seconds.
Misspelled "function", and some grammar issues. Please change to
something like this:

On OS/2, this function cannot set the timestamp to earlier than the
year 1980 in local time.
@item
On OS/2, this function cannot set the timestamp to an odd number of
seconds.
Post by KO Myung-Hun
+ /* On OS/2, a file date should be since 1980 year in local time
+ and even seconds. */
Reword to "On OS/2, file timestamps must be on or after 1980 in local
time, with an even number of seconds."
Post by KO Myung-Hun
+ static struct timeval timeval[2] = {{315620000 + 10, 10},
+ {315620000 + 1000000, 999998}};
/* Test whether utimes() essentially works. */
{
@@ -82,15 +86,18 @@ main ()
result |= 1;
else if (fstat (fd, &st0) != 0)
result |= 1;
+ else if (write (fd, "\n", 1) != 1)
+ result |= 1;
+ else if (fstat (fd, &st1) != 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)
- result |= 1;
- else if (write (fd, "\n", 1) != 1)
- result |= 1;
- else if (fstat (fd, &st2) != 0)
+ else if (lstat (file, &st2) != 0)
result |= 1;
else if (time (&t2) == (time_t) -1)
result |= 1;
@@ -103,7 +110,8 @@ main ()
if (! (m_ok_POSIX || m_ok_NFS))
result |= 32;
}
- if (close (fd) != 0)
+ /* Ensure to close fd, but ignore an error if already closed. */
+ if (close (fd) != 0 && errno != EBADF)
result |= 1;
}
if (unlink (file) != 0)
This doesn't look right, as the original order of updating the file's
time stamps is needed to tickle the NFS bug. Instead, please change the
code to attempt utimes() on the opened file, and if this fails the way
that kLIBC fails, then close the file, invoke utimes on the file, and
reopen the file. That way, the order will be preserved and there should
be no need for any EBADF check.
KO Myung-Hun
2016-01-15 04:18:18 UTC
Permalink
Post by Paul Eggert
Post by KO Myung-Hun
+On OS/2, this funciton cannot set timestamp earlier than 1980 year in local
+time.
+On OS/2, this function cannot set timestamp in odd seconds.
Misspelled "function", and some grammar issues. Please change to
On OS/2, this function cannot set the timestamp to earlier than the
year 1980 in local time.
@item
On OS/2, this function cannot set the timestamp to an odd number of
seconds.
Post by KO Myung-Hun
+ /* On OS/2, a file date should be since 1980 year in local time
+ and even seconds. */
Reword to "On OS/2, file timestamps must be on or after 1980 in local
time, with an even number of seconds."
Post by KO Myung-Hun
+ static struct timeval timeval[2] = {{315620000 + 10, 10},
+ {315620000 + 1000000, 999998}};
/* Test whether utimes() essentially works. */
{
@@ -82,15 +86,18 @@ main ()
result |= 1;
else if (fstat (fd, &st0) != 0)
result |= 1;
+ else if (write (fd, "\n", 1) != 1)
+ result |= 1;
+ else if (fstat (fd, &st1) != 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)
- result |= 1;
- else if (write (fd, "\n", 1) != 1)
- result |= 1;
- else if (fstat (fd, &st2) != 0)
+ else if (lstat (file, &st2) != 0)
result |= 1;
else if (time (&t2) == (time_t) -1)
result |= 1;
@@ -103,7 +110,8 @@ main ()
if (! (m_ok_POSIX || m_ok_NFS))
result |= 32;
}
- if (close (fd) != 0)
+ /* Ensure to close fd, but ignore an error if already closed. */
+ if (close (fd) != 0 && errno != EBADF)
result |= 1;
}
if (unlink (file) != 0)
This doesn't look right, as the original order of updating the file's
time stamps is needed to tickle the NFS bug. Instead, please change the
code to attempt utimes() on the opened file, and if this fails the way
that kLIBC fails, then close the file, invoke utimes on the file, and
reopen the file. That way, the order will be preserved and there should
be no need for any EBADF check.
Updated.
--
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
2016-01-14 02:23:47 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 | 14 +++++++++-
m4/fcntl.m4 | 13 ++++++++-
6 files changed, 217 insertions(+), 3 deletions(-)

diff --git a/lib/dup.c b/lib/dup.c
index f1fa5f9..1f488f2 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 c913f47..5d026f2 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 1ccc5ac..b7b4313 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 4fb0d30..490d921 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-2016 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 63d6d8e..5b68312 100644
--- a/m4/dup2.m4
+++ b/m4/dup2.m4
@@ -1,4 +1,4 @@
-#serial 24
+#serial 25
dnl Copyright (C) 2002, 2005, 2007, 2009-2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -62,6 +62,16 @@ 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;]])
],
[gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no],
@@ -78,6 +88,8 @@ AC_DEFUN([gl_FUNC_DUP2],
gl_cv_func_dup2_works="guessing no" ;;
*-android*) # implemented using dup3(), which fails if oldfd == newfd
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 0037e5f..bb61470 100644
--- a/m4/fcntl.m4
+++ b/m4/fcntl.m4
@@ -1,4 +1,4 @@
-# fcntl.m4 serial 8
+# fcntl.m4 serial 9
dnl Copyright (C) 2009-2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -54,6 +54,17 @@ 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],
[gl_cv_func_fcntl_f_dupfd_works=no],
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:45 UTC
Permalink
On OS/2 kLIBC, wcwidth is a macro to static inline function.
Implementation of wcwidth in wcwidth.c causes 'conflicting types'
error.

* lib/wchar.in.h: Undefine wcwidth on OS/2 kLIBC.
---
lib/wchar.in.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 3ff9b6c..9b90e6e 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -31,7 +31,7 @@
@PRAGMA_COLUMNS@

#if (((defined __need_mbstate_t || defined __need_wint_t) \
- && !defined __MINGW32__) \
+ && !defined __MINGW32__ && !defined __KLIBC__) \
|| (defined __hpux \
&& ((defined _INTTYPES_INCLUDED && !defined strtoimax) \
|| defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) \
@@ -445,6 +445,10 @@ _GL_CXXALIAS_RPL (wcwidth, int, (wchar_t));
# if !@HAVE_DECL_WCWIDTH@
/* wcwidth exists but is not declared. */
_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE);
+# elif defined __KLIBC__
+/* On OS/2 kLIBC, wcwidth is a macro to static inline function. Implementation
+ of wcwidth in wcwidth.c causes 'conflicting types' error. */
+# undef wcwidth
# endif
_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t));
# endif
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:46 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 d05d201..d44a6e8 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 0f47fe6..97a6f0f 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 e0608fb..389054a 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>
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:43 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 f4249f4..50ad62c 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
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:44 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 7487950..e0608fb 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)
{
--
2.7.0
KO Myung-Hun
2016-01-14 02:23:41 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 d20d1c7..03a6087 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 */
--
2.7.0
Paul Eggert
2016-01-14 21:11:55 UTC
Permalink
Wouldn't something like the attached be simpler?
KO Myung-Hun
2016-01-15 01:27:53 UTC
Permalink
Post by Paul Eggert
Wouldn't something like the attached be simpler?
stdint.diff
diff --git a/lib/stdint.in.h b/lib/stdint.in.h
index d20d1c7..22c2d70 100644
--- a/lib/stdint.in.h
+++ b/lib/stdint.in.h
@@ -288,12 +288,14 @@ typedef gl_uint_fast32_t gl_uint_fast16_t;
/* 7.18.1.4. Integer types capable of holding object pointers */
+#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
+#endif
/* 7.18.1.5. Greatest-width integer types */
Updated.
--
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
2016-01-14 02:23:42 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 d5c8233..9f17c0d 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
--
2.7.0
Paul Eggert
2016-01-14 21:55:19 UTC
Permalink
Post by KO Myung-Hun
+ if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
Don't parenthesize the argument of sizeof here.
Post by KO Myung-Hun
+ sprintf (result, "%s/%s", path, file);
This won't work if PATH or FILE is longer than INT_MAX bytes. Please
just use memcpy or strcpy instead.
KO Myung-Hun
2016-01-15 02:11:29 UTC
Permalink
Hi/2.
Post by Paul Eggert
Post by KO Myung-Hun
+ if (__libc_Back_ioFHToPath (fd, path, sizeof (path)))
Don't parenthesize the argument of sizeof here.
Post by KO Myung-Hun
+ sprintf (result, "%s/%s", path, file);
This won't work if PATH or FILE is longer than INT_MAX bytes. Please
just use memcpy or strcpy instead.
Updated.
--
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
Paul Eggert
2016-01-15 18:10:33 UTC
Permalink
Thanks, I installed the attached somewhat-different patch. It also
incorporates the ChangeLog fixes from your earlier patches that I forgot
to install earlier. Please give it a try.
KO Myung-Hun
2016-01-16 03:56:31 UTC
Permalink
Hi/2.

Not work here. I attach the fix.
Post by Paul Eggert
Thanks, I installed the attached somewhat-different patch. It also
incorporates the ChangeLog fixes from your earlier patches that I forgot
to install earlier. Please give it a try.
--
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
2016-01-20 02:22:39 UTC
Permalink
Ping ?
--
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
Paul Eggert
2016-01-15 00:46:42 UTC
Permalink
Thanks, I've installed patches 02, 03, 04, 05, 06, 07, and 09 in that
series, and have responded with comments for the other patches.
KO Myung-Hun
2016-01-15 04:20:02 UTC
Permalink
Post by Paul Eggert
Thanks, I've installed patches 02, 03, 04, 05, 06, 07, and 09 in that
series, and have responded with comments for the other patches.
Thanks a lot. I've replied updated patches to those comments.
--
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
Loading...