changeset 15961:27cc5b08d442

posix_openpt: new module * modules/posix_openpt: New module. * m4/posix_openpt.m4: New file. * lib/posix_openpt.c: Likewise. * m4/stdlib_h.m4 (gl_STDLIB_H): Check for decl. (gl_STDLIB_H_DEFAULTS): Set defaults. * modules/stdlib (Makefile.am): Substitute macros. * lib/stdlib.in.h (posix_openpt): Declare. * MODULES.html.sh (systems lacking POSIX:2008): Document it. * doc/posix-functions/posix_openpt.texi (posix_openpt): Likewise. * modules/posix_openpt-tests: New test module. * tests/test-posix_openpt.c: New test.
author Eric Blake <eblake@redhat.com>
date Mon, 17 Oct 2011 17:19:41 -0600
parents 85f5b7651b9a
children cfa1d5dbe78c
files ChangeLog MODULES.html.sh doc/posix-functions/posix_openpt.texi lib/posix_openpt.c lib/stdlib.in.h m4/posix_openpt.m4 m4/stdlib_h.m4 modules/posix_openpt modules/posix_openpt-tests modules/stdlib tests/test-posix_openpt.c
diffstat 11 files changed, 236 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2011-10-18  Eric Blake  <eblake@redhat.com>
+
+	posix_openpt: new module
+	* modules/posix_openpt: New module.
+	* m4/posix_openpt.m4: New file.
+	* lib/posix_openpt.c: Likewise.
+	* m4/stdlib_h.m4 (gl_STDLIB_H): Check for decl.
+	(gl_STDLIB_H_DEFAULTS): Set defaults.
+	* modules/stdlib (Makefile.am): Substitute macros.
+	* lib/stdlib.in.h (posix_openpt): Declare.
+	* MODULES.html.sh (systems lacking POSIX:2008): Document it.
+	* doc/posix-functions/posix_openpt.texi (posix_openpt): Likewise.
+	* modules/posix_openpt-tests: New test module.
+	* tests/test-posix_openpt.c: New test.
+
 2011-10-15  Bruno Haible  <bruno@clisp.org>
 
 	xstrtoll: Fix compilation failure.
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -2411,6 +2411,7 @@
   func_module perror
   func_module poll
   func_module popen
+  func_module posix_openpt
   func_module posix_spawn
   func_module posix_spawnattr_destroy
   func_module posix_spawnattr_getflags
--- a/doc/posix-functions/posix_openpt.texi
+++ b/doc/posix-functions/posix_openpt.texi
@@ -4,16 +4,17 @@
 
 POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html}
 
-Gnulib module: ---
+Gnulib module: posix_openpt
 
 Portability problems fixed by Gnulib:
 @itemize
-@end itemize
-
-Portability problems not fixed by Gnulib:
-@itemize
 @item
 This function is missing on some platforms:
 MacOS X 10.3, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11.23, IRIX 6.5, OSF/1 5.1,
 Solaris 9, Cygwin 1.5.x, mingw, MSVC 9, Interix 3.5, BeOS.
+However, the replacement may fail with ENOSYS on some platforms.
 @end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end itemize
new file mode 100644
--- /dev/null
+++ b/lib/posix_openpt.c
@@ -0,0 +1,50 @@
+/* Open the master side of a pseudo-terminal.
+   Copyright (C) 2010-2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdlib.h>
+
+#include <fcntl.h>
+#include <errno.h>
+
+int
+posix_openpty (int flags)
+{
+  int master;
+
+#ifdef _AIX /* AIX */
+
+  master = open ("/dev/ptc", flags);
+
+#elif (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ /* mingw */
+
+  /* Mingw lacks pseudo-terminals altogether.  */
+  master = -1;
+  errno = ENOSYS;
+
+#else /* MacOS, OpenBSD, HP-UX, IRIX, Solaris 9, Cygwin 1.5 */
+
+  /* Most systems that lack posix_openpt() have /dev/ptmx.  */
+  master = open ("/dev/ptmx", flags);
+
+#endif
+
+  return master;
+}
+
+#endif
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -423,6 +423,22 @@
 # endif
 #endif
 
+#if @GNULIB_POSIX_OPENPT@
+/* Return an FD open to the master side of a pseudo-terminal.  Flags should
+   include O_RDWR, and may also include O_NOCTTY.  */
+# if !@HAVE_POSIX_OPENPT@
+_GL_FUNCDECL_SYS (posix_openpt, int, (int flags));
+# endif
+_GL_CXXALIAS_SYS (posix_openpt, int, (int flags));
+_GL_CXXALIASWARN (posix_openpt);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_openpt
+# if HAVE_RAW_DECL_POSIX_OPENPT
+_GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - "
+                 "use gnulib module posix_openpt for portability");
+# endif
+#endif
+
 #if @GNULIB_PTSNAME@
 /* Return the pathname of the pseudo-terminal slave associated with
    the master FD is open on, or NULL on errors.  */
new file mode 100644
--- /dev/null
+++ b/m4/posix_openpt.m4
@@ -0,0 +1,21 @@
+# posix_openpt.m4 serial 1
+dnl Copyright (C) 2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_POSIX_OPENPT],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+
+  dnl Persuade Solaris <stdlib.h> to declare posix_openpt().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_FUNCS_ONCE([posix_openpt])
+  if test $ac_cv_have_posix_openpt != yes; then
+    dnl The system does not have posix_openpt.
+    HAVE_POSIX_OPENPT=0
+    dnl Prerequisites of lib/posix_openpt.c in this case.
+    AC_CHECK_FUNCS([_getpty])
+  fi
+])
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -19,10 +19,10 @@
 #if HAVE_RANDOM_H
 # include <random.h>
 #endif
-    ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt mkdtemp
-    mkostemp mkostemps mkstemp mkstemps ptsname random_r initstat_r srandom_r
-    setstate_r realpath rpmatch setenv strtod strtoll strtoull unlockpt
-    unsetenv])
+    ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
+    initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps posix_openpt
+    ptsname random_r realpath rpmatch setenv setstate_r srandom_r strtod
+    strtoll strtoull unlockpt unsetenv])
 ])
 
 AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
@@ -50,6 +50,7 @@
   GNULIB_MKOSTEMPS=0;     AC_SUBST([GNULIB_MKOSTEMPS])
   GNULIB_MKSTEMP=0;       AC_SUBST([GNULIB_MKSTEMP])
   GNULIB_MKSTEMPS=0;      AC_SUBST([GNULIB_MKSTEMPS])
+  GNULIB_POSIX_OPENPT=0;  AC_SUBST([GNULIB_POSIX_OPENPT])
   GNULIB_PTSNAME=0;       AC_SUBST([GNULIB_PTSNAME])
   GNULIB_PUTENV=0;        AC_SUBST([GNULIB_PUTENV])
   GNULIB_RANDOM_R=0;      AC_SUBST([GNULIB_RANDOM_R])
@@ -76,6 +77,7 @@
   HAVE_MKOSTEMPS=1;          AC_SUBST([HAVE_MKOSTEMPS])
   HAVE_MKSTEMP=1;            AC_SUBST([HAVE_MKSTEMP])
   HAVE_MKSTEMPS=1;           AC_SUBST([HAVE_MKSTEMPS])
+  HAVE_POSIX_OPENPT=1;       AC_SUBST([HAVE_POSIX_OPENPT])
   HAVE_PTSNAME=1;            AC_SUBST([HAVE_PTSNAME])
   HAVE_RANDOM_H=1;           AC_SUBST([HAVE_RANDOM_H])
   HAVE_RANDOM_R=1;           AC_SUBST([HAVE_RANDOM_R])
new file mode 100644
--- /dev/null
+++ b/modules/posix_openpt
@@ -0,0 +1,28 @@
+Description:
+posix_openpt() function: Open the master side of a pseudo-terminal.
+
+Files:
+lib/posix_openpt.c
+m4/posix_openpt.m4
+
+Depends-on:
+extensions
+stdlib
+
+configure.ac:
+gl_FUNC_POSIX_OPENPT
+if test $HAVE_POSIX_OPENPT = 0; then
+  AC_LIBOBJ([posix_openpt])
+fi
+gl_STDLIB_MODULE_INDICATOR([posix_openpt])
+
+Makefile.am:
+
+Include:
+<stdlib.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Eric Blake
new file mode 100644
--- /dev/null
+++ b/modules/posix_openpt-tests
@@ -0,0 +1,15 @@
+Files:
+tests/test-posix_openpt.c
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+grantpt
+ptsname
+unlockpt
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-posix_openpt
+check_PROGRAMS += test-posix_openpt
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -45,6 +45,7 @@
 	      -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \
 	      -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \
 	      -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \
+	      -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \
 	      -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
 	      -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \
 	      -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
@@ -71,6 +72,7 @@
 	      -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \
 	      -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \
 	      -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \
+	      -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
 	      -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
 	      -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
 	      -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
new file mode 100644
--- /dev/null
+++ b/tests/test-posix_openpt.c
@@ -0,0 +1,76 @@
+/* Test of posix_openpt function.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Eric Blake <eblake@redhat.com>, 2011.  */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (posix_openpt, int, (int));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#if defined __sun || defined __hpux /* Solaris, HP-UX */
+# include <stropts.h>
+#endif
+
+#include "macros.h"
+
+int
+main (void)
+{
+  int master;
+  int slave;
+  char *name;
+
+  /* Open the master of a pseudo-terminal pair.  */
+  master = posix_openpt(O_RDWR | O_NOCTTY);
+  if (master < 0 && errno == ENOSYS)
+    {
+      fputs ("skipping: platform lacks pty support\n", stderr);
+      return 77;
+    }
+
+  ASSERT (0 <= master);
+  name = ptsname (master);
+  ASSERT (name);
+  ASSERT (grantpt (master) == 0);
+  ASSERT (unlockpt (master) == 0);
+  slave = open (name, O_RDWR);
+  ASSERT (0 <= slave);
+
+#if defined __sun || defined __hpux /* Solaris, HP-UX */
+  ASSERT (ioctl (slave, I_PUSH, "ptem") == 0);
+  ASSERT (ioctl (slave, I_PUSH, "ldterm")  == 0);
+# if defined __sun
+  ASSERT (ioctl (slave, I_PUSH, "ttcompat") == 0);
+# endif
+#endif
+
+  ASSERT (isatty (slave));
+
+  /* Close the master side before the slave side gets closed.
+     This is necessary on MacOS X 10.4.11.  */
+  ASSERT (close (master) == 0);
+  ASSERT (close (slave) == 0);
+
+  return 0;
+}