bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

port 'openpty' to all Unix platforms


From: Bruno Haible
Subject: port 'openpty' to all Unix platforms
Date: Mon, 22 Mar 2010 00:10:23 +0100
User-agent: KMail/1.9.9

Hi,

Here's an attempted implementation of openpty for all Unix platforms. It's
tested to work fine on Solaris 10 and Solaris 8. The logic should also be
in place for AIX, HP-UX, IRIX, but I can't test that. If it does not work
on these platforms - there is a unit test -, please report it.


2010-03-21  Bruno Haible  <address@hidden>

        openpty: Provide replacement on AIX, HP-UX, IRIX, Solaris.
        * lib/openpty.c (openpty): New replacement function.
        * lib/pty.in.h: Include <termios.h>.
        (openpty): Update declaration. Add comments.
        * m4/pty.m4 (gl_OPENPTY): Require AC_USE_SYSTEM_EXTENSIONS. If openpty
        is not declared, arrange to provide the replacement. Check for _getpty
        and posix_openpt.
        * modules/openpty (Depends-on): Add extensions, fcntl-h, ioctl.
        * m4/pty_h.m4 (gl_PTY_H_DEFAULTS): Initialize HAVE_OPENPTY.
        * modules/pty (Makefile.am): Substitute HAVE_OPENPTY.
        * modules/pty-tests (test_pty_c___LDADD): New variable.
        * doc/glibc-functions/openpty.texi: More supported platforms.

--- doc/glibc-functions/openpty.texi.orig       Sun Mar 21 23:57:55 2010
+++ doc/glibc-functions/openpty.texi    Sun Mar 21 23:47:05 2010
@@ -7,6 +7,9 @@
 Portability problems fixed by Gnulib:
 @itemize
 @item
+This function is missing on some platforms:
+AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, mingw.
address@hidden
 One some systems (at least including Cygwin, Interix, OSF/1 4 and 5,
 and Mac OS X) linking with @code{-lutil} is not required.
 @item
@@ -24,7 +27,4 @@
 
 Portability problems not fixed by Gnulib:
 @itemize
address@hidden
-On some systems (at least including Solaris and HP-UX) the function is
-missing.
 @end itemize
--- lib/openpty.c.orig  Sun Mar 21 23:57:55 2010
+++ lib/openpty.c       Sun Mar 21 23:47:05 2010
@@ -1,4 +1,4 @@
-/* Open a pseudo-terminal descriptor.
+/* Open a pseudo-terminal.
    Copyright (C) 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -19,17 +19,135 @@
 /* Specification.  */
 #include <pty.h>
 
-#if HAVE_DECL_OPENPTY
+#if HAVE_OPENPTY
+
+/* Provider a wrapper with the precise POSIX prototype.  */
 # undef openpty
 int
-rpl_openpty (int *amaster, int *aslave, char *name, struct termios const 
*termp,
-         struct winsize const *winp)
+rpl_openpty (int *amaster, int *aslave, char *name,
+             struct termios const *termp, struct winsize const *winp)
 {
   /* Cast away const, for implementations with weaker prototypes.  */
   return openpty (amaster, aslave, name, (struct termios *) termp,
                   (struct winsize *) winp);
 }
-#else
-# error openpty has not been ported to your system; \
-  report this to address@hidden for help
+
+#else /* AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, mingw */
+
+# include <fcntl.h>
+# include <string.h>
+# include <sys/ioctl.h>
+# include <termios.h>
+# include <unistd.h>
+# if defined __sun || defined __hpux /* Solaris, HP-UX */
+#  include <stropts.h>
+# endif
+
+int
+openpty (int *amaster, int *aslave, char *name,
+         struct termios const *termp, struct winsize const *winp)
+{
+  int master;
+  char *slave_name;
+  int slave;
+
+# if HAVE__GETPTY /* IRIX */
+
+  slave_name = _getpty (&master, O_RDWR, 0622, 0);
+  if (slave_name == NULL)
+    return -1;
+
+# else /* AIX 5.1, HP-UX 11, Solaris 10, mingw */
+
+#  if HAVE_POSIX_OPENPT /* Solaris 10 */
+
+  master = posix_openpt (O_RDWR | O_NOCTTY);
+  if (master < 0)
+    return -1;
+
+#  else /* AIX 5.1, HP-UX 11, Solaris 9, mingw */
+
+#   ifdef _AIX /* AIX */
+
+  master = open ("/dev/ptc", O_RDWR | O_NOCTTY);
+  if (master < 0)
+    return -1;
+
+#   else /* HP-UX 11, Solaris 9, mingw */
+
+  /* HP-UX, Solaris have /dev/ptmx.
+     HP-UX also has /dev/ptym/clone, but this should not be needed.
+     Linux also has /dev/ptmx, but Linux already has openpty().
+     MacOS X also has /dev/ptmx, but MacOS X already has openpty().
+     OSF/1 also has /dev/ptmx and /dev/ptmx_bsd, but OSF/1 already has
+     openpty().  */
+  master = open ("/dev/ptmx", O_RDWR | O_NOCTTY);
+  if (master < 0)
+    return -1;
+
+#   endif
+
+#  endif
+
+  /* If all this does not work, we could try to open, one by one:
+     - On MacOS X: /dev/pty[p-w][0-9a-f]
+     - On *BSD:    /dev/pty[p-sP-S][0-9a-v]
+     - On AIX:     /dev/ptyp[0-9a-f]
+     - On HP-UX:   /dev/pty[p-r][0-9a-f]
+     - On OSF/1:   /dev/pty[p-q][0-9a-f]
+     - On Solaris: /dev/pty[p-r][0-9a-f]
+   */
+# endif
+
+  /* This call does not require a dependency to the 'grantpt' module,
+     because AIX, HP-UX, IRIX, Solaris all have the grantpt() function.  */
+  if (grantpt (master))
+    goto fail;
+
+  /* This call does not require a dependency to the 'unlockpt' module,
+     because AIX, HP-UX, IRIX, Solaris all have the unlockpt() function.  */
+  if (unlockpt (master))
+    goto fail;
+
+# if !HAVE__GETPTY /* !IRIX */
+  slave_name = ptsname (master);
+  if (slave_name == NULL)
+    goto fail;
+# endif
+
+  slave = open (slave_name, O_RDWR | O_NOCTTY);
+  if (slave == -1)
+    goto fail;
+
+# if defined __sun || defined __hpux /* Solaris, HP-UX */
+  if (ioctl (slave, I_PUSH, "ptem") < 0
+      || ioctl (slave, I_PUSH, "ldterm") < 0
+#  if defined __sun
+      || ioctl (slave, I_PUSH, "ttcompat") < 0
+#  endif
+     )
+    {
+      close (slave);
+      goto fail;
+    }
+# endif
+
+  /* XXX Should we ignore errors here?  */
+  if (termp)
+    tcsetattr (slave, TCSAFLUSH, termp);
+  if (winp)
+    ioctl (slave, TIOCSWINSZ, winp);
+
+  *amaster = master;
+  *aslave = slave;
+  if (name != NULL)
+    strcpy (name, slave_name);
+
+  return 0;
+
+ fail:
+  close (master);
+  return -1;
+}
+
 #endif
--- lib/pty.in.h.orig   Sun Mar 21 23:57:55 2010
+++ lib/pty.in.h        Sun Mar 21 23:47:05 2010
@@ -37,6 +37,9 @@
 # include <libutil.h>
 #endif
 
+/* Get 'struct termios' and 'struct winsize'.  */
+#include <termios.h>
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_WARN_ON_USE is copied here.  */
@@ -71,21 +74,29 @@
 #endif
 
 #if @GNULIB_OPENPTY@
+/* Create pseudo tty master slave pair and set terminal attributes
+   according to TERMP and WINP.  Return handles for both ends in
+   *AMASTER and *ASLAVE, and return the name of the slave end in NAME.  */
 # if @REPLACE_OPENPTY@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef openpty
 #   define openpty rpl_openpty
 #  endif
 _GL_FUNCDECL_RPL (openpty, int,
-                  (int *, int *, char *, struct termios const *,
-                   struct winsize const *));
+                  (int *amaster, int *aslave, char *name,
+                   struct termios const *termp, struct winsize const *winp));
 _GL_CXXALIAS_RPL (openpty, int,
-                  (int *, int *, char *, struct termios const *,
-                   struct winsize const *));
+                  (int *amaster, int *aslave, char *name,
+                   struct termios const *termp, struct winsize const *winp));
 # else
+#  if address@hidden@
+_GL_FUNCDECL_SYS (openpty, int,
+                  (int *amaster, int *aslave, char *name,
+                   struct termios const *termp, struct winsize const *winp));
+#  endif
 _GL_CXXALIAS_SYS (openpty, int,
-                  (int *, int *, char *, struct termios const *,
-                   struct winsize const *));
+                  (int *amaster, int *aslave, char *name,
+                   struct termios const *termp, struct winsize const *winp));
 # endif
 _GL_CXXALIASWARN (openpty);
 #elif defined GNULIB_POSIXCHECK
--- m4/pty.m4.orig      Sun Mar 21 23:57:55 2010
+++ m4/pty.m4   Sun Mar 21 23:47:05 2010
@@ -70,6 +70,11 @@
   AC_REQUIRE([gl_PTY_LIB])
   AC_REQUIRE([gl_PTY])
 
+  dnl Persuade Solaris <stdlib.h> to declare posix_openpt().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  dnl We assume that openpty exists (possibly in libc, possibly in libutil)
+  dnl if and only if it is declared.
   AC_CHECK_DECLS([openpty],,, [[
 #if HAVE_PTY_H
 # include <pty.h>
@@ -81,15 +86,13 @@
 # include <libutil.h>
 #endif
 ]])
-  if test $ac_cv_have_decl_openpty = no; then
-    AC_MSG_WARN([[Cannot find openpty, build will likely fail]])
-  fi
-
-  dnl Prefer glibc's const-safe prototype, if available.
-  AC_CACHE_CHECK([for const-safe openpty signature],
-    [gl_cv_func_openpty_const],
-    [AC_COMPILE_IFELSE(
-      [AC_LANG_PROGRAM([[
+  if test $ac_cv_have_decl_openpty = yes; then
+    dnl The system has openpty.
+    dnl Prefer glibc's const-safe prototype, if available.
+    AC_CACHE_CHECK([for const-safe openpty signature],
+      [gl_cv_func_openpty_const],
+      [AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM([[
 #if HAVE_PTY_H
 # include <pty.h>
 #endif
@@ -99,13 +102,21 @@
 #if HAVE_LIBUTIL_H
 # include <libutil.h>
 #endif
-      ]], [[
-        int openpty (int *, int *, char *, struct termios const *,
-                     struct winsize const *);
-      ]])],
-      [gl_cv_func_openpty_const=yes], [gl_cv_func_openpty_const=no])])
-  if test $gl_cv_func_openpty_const != yes; then
-    REPLACE_OPENPTY=1
+          ]], [[
+            int openpty (int *, int *, char *, struct termios const *,
+                       struct winsize const *);
+          ]])
+        ],
+        [gl_cv_func_openpty_const=yes], [gl_cv_func_openpty_const=no])
+      ])
+    if test $gl_cv_func_openpty_const != yes; then
+      REPLACE_OPENPTY=1
+      AC_LIBOBJ([openpty])
+    fi
+  else
+    dnl The system does not have openpty.
+    HAVE_OPENPTY=0
     AC_LIBOBJ([openpty])
+    AC_CHECK_FUNCS([_getpty posix_openpt])
   fi
 ])
--- m4/pty_h.m4.orig    Sun Mar 21 23:57:55 2010
+++ m4/pty_h.m4 Sun Mar 21 23:47:05 2010
@@ -1,4 +1,4 @@
-# pty_h.m4 serial 5
+# pty_h.m4 serial 6
 dnl Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -60,6 +60,7 @@
   dnl Assume proper GNU behavior unless another module says otherwise.
   HAVE_UTIL_H=0;        AC_SUBST([HAVE_UTIL_H])
   HAVE_LIBUTIL_H=0;     AC_SUBST([HAVE_LIBUTIL_H])
+  HAVE_OPENPTY=1;       AC_SUBST([HAVE_OPENPTY])
   REPLACE_FORKPTY=0;    AC_SUBST([REPLACE_FORKPTY])
   REPLACE_OPENPTY=0;    AC_SUBST([REPLACE_OPENPTY])
 ])
--- modules/openpty.orig        Sun Mar 21 23:57:55 2010
+++ modules/openpty     Sun Mar 21 23:53:10 2010
@@ -1,5 +1,5 @@
 Description:
-Provide the openpty() function.
+openpty() function: Open a pseudo-terminal.
 
 Files:
 lib/openpty.c
@@ -7,6 +7,9 @@
 
 Depends-on:
 pty
+extensions
+fcntl-h
+ioctl
 
 configure.ac:
 gl_OPENPTY
--- modules/pty.orig    Sun Mar 21 23:57:55 2010
+++ modules/pty Sun Mar 21 23:47:05 2010
@@ -29,6 +29,7 @@
              -e 's|@''GNULIB_OPENPTY''@|$(GNULIB_OPENPTY)|g' \
              -e 's|@''HAVE_UTIL_H''@|$(HAVE_UTIL_H)|g' \
              -e 's|@''HAVE_LIBUTIL_H''@|$(HAVE_LIBUTIL_H)|g' \
+             -e 's|@''HAVE_OPENPTY''@|$(HAVE_OPENPTY)|g' \
              -e 's|@''REPLACE_FORKPTY''@|$(REPLACE_FORKPTY)|g' \
              -e 's|@''REPLACE_OPENPTY''@|$(REPLACE_OPENPTY)|g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
--- modules/pty-tests.orig      Sun Mar 21 23:57:55 2010
+++ modules/pty-tests   Sun Mar 21 23:47:05 2010
@@ -12,4 +12,5 @@
 TESTS += test-pty-c++
 check_PROGRAMS += test-pty-c++
 test_pty_c___SOURCES = test-pty-c++.cc
+test_pty_c___LDADD = $(LDADD) $(PTY_LIB)
 endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]