The next brick for building a portable openpty and forkpty is 'grantpt'. I'm adding a port of the glibc implementation (based on the pt_chown program).
2010-03-21 Bruno Haible <br...@clisp.org> New module 'grantpt'. * lib/grantpt.c: New file, from glibc with modifications. * m4/grantpt.m4: New file. * modules/grantpt: New file. * lib/stdlib.in.h (grantpt): New declaration. * m4/stdlib_h.m4 (gl_STDLIB_H): Check whether grantpt is declared. (gl_STDLIB_H_DEFAULTS): Initialize GNULIB_GRANTPT, HAVE_GRANTPT. * modules/stdlib (Makefile.am): Substitute GNULIB_GRANTPT, HAVE_GRANTPT. * doc/posix-functions/grantpt.texi: Mention the new module. * tests/test-stdlib-c++.cc: Check GNULIB_NAMESPACE::grantpt. * config/srclist.txt: Add grantpt.c (commented). ================================ lib/grantpt.c ================================ /* Acquire ownership of the slave side of a pseudo-terminal. Copyright (C) 1998-2002, 2009-2010 Free Software Foundation, Inc. Contributed by Zack Weinberg <z...@rabi.phys.columbia.edu>, 1998. 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> #include <stdlib.h> #include <assert.h> #include <errno.h> #include <string.h> #include <sys/wait.h> #include <unistd.h> #if HAVE_SETRLIMIT # include <sys/types.h> # include <sys/time.h> # include <sys/resource.h> #endif #include "configmake.h" #include "pty-private.h" #ifndef _LIBC # define __builtin_expect(expr,val) (expr) # define __set_errno(e) errno = (e) # define __dup2 dup2 # define __fork fork # define __setrlimit setrlimit # define __waitpid waitpid #endif int grantpt (int fd) { /* This function is most often called from a process without 'root' credentials. Use the helper program. */ int retval = -1; pid_t pid = __fork (); if (pid == -1) goto cleanup; else if (pid == 0) { /* This is executed in the child process. */ #if HAVE_SETRLIMIT && defined RLIMIT_CORE /* Disable core dumps. */ struct rlimit rl = { 0, 0 }; __setrlimit (RLIMIT_CORE, &rl); #endif /* We pass the master pseudo terminal as file descriptor PTY_FILENO. */ if (fd != PTY_FILENO) if (__dup2 (fd, PTY_FILENO) < 0) _exit (FAIL_EBADF); #ifdef CLOSE_ALL_FDS CLOSE_ALL_FDS (); #endif execle (_PATH_PT_CHOWN, strrchr (_PATH_PT_CHOWN, '/') + 1, NULL, NULL); _exit (FAIL_EXEC); } else { int w; if (__waitpid (pid, &w, 0) == -1) goto cleanup; if (!WIFEXITED (w)) __set_errno (ENOEXEC); else switch (WEXITSTATUS (w)) { case 0: retval = 0; break; case FAIL_EBADF: __set_errno (EBADF); break; case FAIL_EINVAL: __set_errno (EINVAL); break; case FAIL_EACCES: __set_errno (EACCES); break; case FAIL_EXEC: __set_errno (ENOEXEC); break; case FAIL_ENOMEM: __set_errno (ENOMEM); break; default: assert(! "getpt: internal error: invalid exit code from pt_chown"); } } cleanup: return retval; } ================================ m4/grantpt.m4 ================================ # grantpt.m4 serial 1 dnl Copyright (C) 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, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_GRANTPT], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl Persuade glibc <stdlib.h> to declare grantpt(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS([grantpt]) if test $ac_cv_func_grantpt = no; then HAVE_GRANTPT=0 AC_LIBOBJ([grantpt]) gl_PREREQ_GRANTPT fi ]) # Prerequisites of lib/grantpt.c. AC_DEFUN([gl_PREREQ_GRANTPT], [ AC_CHECK_FUNCS([setrlimit]) ]) =============================== modules/grantpt =============================== Description: grantpt() function: Acquire ownership of the slave side of a pseudo-terminal. Files: lib/grantpt.c m4/grantpt.m4 Depends-on: stdlib extensions pt_chown configmake configure.ac: gl_FUNC_GRANTPT gl_STDLIB_MODULE_INDICATOR([grantpt]) Makefile.am: Include: <stdlib.h> License: LGPL Maintainer: Bruno Haible =============================================================================== --- lib/stdlib.in.h.orig Sun Mar 21 20:06:55 2010 +++ lib/stdlib.in.h Sun Mar 21 19:25:36 2010 @@ -201,6 +201,22 @@ # endif #endif +#if @GNULIB_GRANTPT@ +/* Change the ownership and access permission of the slave side of the + pseudo-terminal whose master side is specified by FD. */ +# if !...@have_grantpt@ +_GL_FUNCDECL_SYS (grantpt, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (grantpt, int, (int fd)); +_GL_CXXALIASWARN (grantpt); +#elif defined GNULIB_POSIXCHECK +# undef grantpt +# if HAVE_RAW_DECL_GRANTPT +_GL_WARN_ON_USE (ptsname, "grantpt is not portable - " + "use gnulib module grantpt for portability"); +# endif +#endif + #if @GNULIB_MALLOC_POSIX@ # if !...@have_malloc_posix@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) --- m4/stdlib_h.m4.orig Sun Mar 21 20:06:55 2010 +++ m4/stdlib_h.m4 Sun Mar 21 19:26:58 2010 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 24 +# stdlib_h.m4 serial 25 dnl Copyright (C) 2007-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, @@ -33,7 +33,7 @@ #if HAVE_RANDOM_H # include <random.h> #endif - ]], [atoll canonicalize_file_name getloadavg getsubopt mkdtemp + ]], [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 unsetenv]) ]) @@ -54,6 +54,7 @@ GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME]) GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG]) GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) + GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT]) GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX]) GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP]) @@ -77,6 +78,7 @@ HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME]) HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) + HAVE_GRANTPT=1; AC_SUBST([HAVE_GRANTPT]) HAVE_MALLOC_POSIX=1; AC_SUBST([HAVE_MALLOC_POSIX]) HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP]) HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP]) --- modules/stdlib.orig Sun Mar 21 20:06:55 2010 +++ modules/stdlib Sun Mar 21 19:26:16 2010 @@ -33,6 +33,7 @@ -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \ -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ + -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \ -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \ @@ -55,6 +56,7 @@ -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ + -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ -e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \ -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ --- doc/posix-functions/grantpt.texi.orig Sun Mar 21 20:06:55 2010 +++ doc/posix-functions/grantpt.texi Sun Mar 21 19:18:58 2010 @@ -4,15 +4,15 @@ POSIX specification: @url{http://www.opengroup.org/onlinepubs/9699919799/functions/grantpt.html} -Gnulib module: --- +Gnulib module: grantpt Portability problems fixed by Gnulib: @itemize +...@item +This function is missing on some platforms: +MacOS X 10.3, OpenBSD 3.8, mingw, BeOS. @end itemize Portability problems not fixed by Gnulib: @itemize -...@item -This function is missing on some platforms: -MacOS X 10.3, OpenBSD 3.8, mingw, BeOS. @end itemize --- tests/test-stdlib-c++.cc.orig Sun Mar 21 20:06:55 2010 +++ tests/test-stdlib-c++.cc Sun Mar 21 19:53:14 2010 @@ -48,6 +48,10 @@ (char **, char *const *, char **)); #endif +#if GNULIB_GRANTPT +SIGNATURE_CHECK (GNULIB_NAMESPACE::grantpt, int, (int)); +#endif + #if GNULIB_MALLOC_POSIX SIGNATURE_CHECK (GNULIB_NAMESPACE::malloc, void *, (size_t)); #endif --- config/srclist.txt.orig Sun Mar 21 20:06:55 2010 +++ config/srclist.txt Sun Mar 21 19:54:32 2010 @@ -218,6 +218,7 @@ #$LIBCSRC/sysdeps/unix/bsd/poll.c lib gpl #$LIBCSRC/sysdeps/unix/bsd/ptsname.c lib gpl #$LIBCSRC/sysdeps/unix/dirfd.c lib gpl +#$LIBCSRC/sysdeps/unix/grantpt.c lib gpl #$LIBCSRC/sysdeps/unix/rmdir.c lib gpl #$LIBCSRC/time/strftime.c lib gpl # These are close, but we are using the gettext versions.