diff --git a/lib/modules/Stdio.pmod/module.pmod b/lib/modules/Stdio.pmod/module.pmod index 444487a0f003ec576f30a05e39faa90ec841b83c..58867ec39695ea54fecae2efc1ef82a628475eda 100644 --- a/lib/modules/Stdio.pmod/module.pmod +++ b/lib/modules/Stdio.pmod/module.pmod @@ -1,4 +1,4 @@ -// $Id: module.pmod,v 1.172 2003/04/26 15:24:18 marcus Exp $ +// $Id: module.pmod,v 1.173 2003/05/15 15:23:53 marcus Exp $ #pike __REAL_VERSION__ inherit files; @@ -211,6 +211,37 @@ class File return ::open(file,mode,bits); } +#if constant(files.__HAVE_OPENPT__) + //! @decl int openpt(string mode) + //! + //! Open the master end of a pseudo-terminal pair. The parameter + //! @[mode] should contain one or more of the following letters: + //! @string + //! @value "r" + //! Open terminal for reading. + //! @value "w" + //! Open terminal for writing. + //! @endstring + //! + //! @[mode] should always contain at least one of the letters + //! @expr{"r"@} or @expr{"w"@}. + //! + //! @seealso + //! @[grantpt()] + //! + int openpt(string mode) + { + _fd=Fd(); + register_open_file ("pty master", open_file_id, backtrace()); + is_file = 0; +#ifdef __STDIO_DEBUG + __closed_backtrace=0; +#endif + debug_file = "pty master"; debug_mode = mode; debug_bits=0; + return ::openpt(mode); + } +#endif + //! This makes this file into a socket ready for connections. The reason //! for this function is so that you can set the socket to nonblocking //! or blocking (default is blocking) before you call @[connect()]. diff --git a/src/modules/files/acconfig.h b/src/modules/files/acconfig.h index 203b4a741d72344a8e69a289ba6760059735a3b3..e2758d11c0aaa8c9e4ebf6dfe051f7d1dac413b4 100644 --- a/src/modules/files/acconfig.h +++ b/src/modules/files/acconfig.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: acconfig.h,v 1.20 2003/05/14 20:21:15 marcus Exp $ +|| $Id: acconfig.h,v 1.21 2003/05/15 15:24:06 marcus Exp $ */ #ifndef FILE_MACHINE_H @@ -80,8 +80,11 @@ /* Filesystem notifications */ #undef HAVE_NOTIFICATIONS -/* Defined to path of pt_chmod to use pt_chmod directly rather than - calling grantpt (needed on Solaris) */ +/* Define to path of pseudo terminal master device if available */ +#undef PTY_MASTER_PATHNAME + +/* Define to path of pt_chmod/chgpt to use pt_chmod directly rather than + calling grantpt (needed on SysV) */ #undef USE_PT_CHMOD #endif diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in index 7bd414836b926a5f63782a01f0438f79f728e34f..5aa595cc26ec9762afeb969a65f6b1e67be56d0d 100644 --- a/src/modules/files/configure.in +++ b/src/modules/files/configure.in @@ -1,4 +1,4 @@ -# $Id: configure.in,v 1.87 2003/05/15 13:25:41 marcus Exp $ +# $Id: configure.in,v 1.88 2003/05/15 15:24:06 marcus Exp $ AC_INIT(file.c) AC_CONFIG_HEADER(file_machine.h) @@ -18,8 +18,9 @@ AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(nsl, gethostbyname) AC_HAVE_FUNCS(getwd perror readdir_r statvfs statfs ustat lseek64 lstat fsync \ - grantpt unlockpt ptsname socketpair writev sendfile munmap madvise poll \ - setsockopt getprotobyname truncate64 ftruncate64 inet_ntoa inet_ntop) + grantpt unlockpt ptsname posix_openpt socketpair writev sendfile munmap \ + madvise poll setsockopt getprotobyname truncate64 ftruncate64 inet_ntoa \ + inet_ntop) AC_FUNC_MMAP @@ -1125,6 +1126,25 @@ else AC_MSG_RESULT(no) fi +AC_MSG_CHECKING(for pty master device) +AC_CACHE_VAL(pike_cv_pty_master_pathname, [ + pike_cv_pty_master_pathname=no + for i in ptmx ptc; do + if test -c /dev/$i; then + pike_cv_pty_master_pathname="/dev/$i" + break + else + : + fi + done +]) +AC_MSG_RESULT($pike_cv_pty_master_pathname) +if test no = "$pike_cv_pty_master_pathname"; then + : +else + AC_DEFINE_UNQUOTED(PTY_MASTER_PATHNAME, "$pike_cv_pty_master_pathname") +fi + if test yes = "$ac_cv_func_grantpt"; then pt_chmod_dirs="" case "$pike_cv_sys_os" in diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 719b5c6c63ac15ffa935cc53d9952900e78894f5..ea4dc9dc58d5d7ba8b98203bf1246accf55de40a 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -2,12 +2,12 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: file.c,v 1.277 2003/05/15 13:25:59 marcus Exp $ +|| $Id: file.c,v 1.278 2003/05/15 15:24:06 marcus Exp $ */ #define NO_PIKE_SHORTHAND #include "global.h" -RCSID("$Id: file.c,v 1.277 2003/05/15 13:25:59 marcus Exp $"); +RCSID("$Id: file.c,v 1.278 2003/05/15 15:24:06 marcus Exp $"); #include "fdlib.h" #include "pike_netlib.h" #include "interpret.h" @@ -1470,7 +1470,7 @@ static int do_close(int flags) /*! @decl string grantpt() *! - *! If this file has been created by opening /dev/ptmx, return the + *! If this file has been created by calling @[openpt()], return the *! filename of the associated pts-file. This function should only be *! called once. */ @@ -1706,6 +1706,68 @@ static void file_open(INT32 args) push_int(fd>=0); } +#if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME)) +/*! @decl int openpt(string mode) + *! + *! Open the master end of a pseudo-terminal pair. + *! + *! @seealso + *! @[grantpt()] + */ +static void file_openpt(INT32 args) +{ + int flags,fd; + struct pike_string *flag_str; + close_fd(); + + if(args < 1) + SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->openpt", 2); + + if(Pike_sp[-args].type != PIKE_T_STRING) + SIMPLE_BAD_ARG_ERROR("Stdio.File->openpt", 1, "string"); + +#ifdef HAVE_POSIX_OPENPT + flags = parse((flag_str = Pike_sp[1-args].u.string)->str); + + if(!( flags & (FILE_READ | FILE_WRITE))) + Pike_error("Must open file for at least one of read and write.\n"); + + do { + THREADS_ALLOW_UID(); + fd=posix_openpt(map(flags)); + THREADS_DISALLOW_UID(); + if ((fd < 0) && (errno == EINTR)) + check_threads_etc(); + } while(fd < 0 && errno == EINTR); + + if(!Pike_fp->current_object->prog) + { + if (fd >= 0) + fd_close(fd); + Pike_error("Object destructed in Stdio.File->open()\n"); + } + + if(fd < 0) + { + ERRNO=errno; + } + else + { + init_fd(fd,flags | fd_query_properties(fd, FILE_CAPABILITIES)); + set_close_on_exec(fd,1); + } + pop_n_elems(args); + push_int(fd>=0); +#else + if(args > 1) + pop_n_elems(args - 1); + push_constant_text(PTY_MASTER_PATHNAME); + stack_swap(); + file_open(2); +#endif +} +#endif + #ifdef HAVE_FSYNC /*! @decl int(0..1) sync() *! @@ -3808,6 +3870,10 @@ PIKE_MODULE_INIT add_integer_constant("__HAVE_CONNECT_UNIX__",1,0); #endif +#if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME)) + add_integer_constant("__HAVE_OPENPT__",1,0); +#endif + /* function(:array(int)) */ ADD_FUNCTION("get_all_active_fd", f_get_all_active_fd, tFunc(tNone,tArr(tInt)), OPT_EXTERNAL_DEPEND); diff --git a/src/modules/files/file_functions.h b/src/modules/files/file_functions.h index c591a32d7a0382db783a5120ce689d07fb519abb..b32dedc781d43be2c944696dcd25e88036cfe463 100644 --- a/src/modules/files/file_functions.h +++ b/src/modules/files/file_functions.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: file_functions.h,v 1.26 2003/04/22 15:15:50 marcus Exp $ +|| $Id: file_functions.h,v 1.27 2003/05/15 15:24:06 marcus Exp $ */ FILE_FUNC("open",file_open,"function(string,string,void|int:int)") @@ -71,7 +71,11 @@ FILE_FUNC("open",file_open,"function(string,string,void|int:int)") FILE_FUNC("trylock",file_trylock,"function(void|int:object)") #endif -#if defined(HAVE_GRANTPT) +#if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME)) + FILE_FUNC("openpt",file_openpt,"function(string:int)") +#endif + +#if defined(HAVE_GRANTPT) || defined(USE_PT_CHMOD) FILE_FUNC("grantpt",file_grantpt,"function(void:string)") #endif diff --git a/src/modules/files/testsuite.in b/src/modules/files/testsuite.in index 7a5d5898bbde5322292a9d2c4b255884bc0f902c..a4220d5e2715e5314d424f40db84983e0a12aabb 100644 --- a/src/modules/files/testsuite.in +++ b/src/modules/files/testsuite.in @@ -241,9 +241,18 @@ cond([[Stdio.File()->lock]], ]]) dnl pty handling -cond([[ Stdio.File()->grantpt ]], + +cond([[ Stdio.File()->openpt ]], +[[ + test_true(Stdio.File()->openpt("rw")); +]]) + +cond([[ Stdio.File()->openpt && Stdio.File()->grantpt ]], [[ - test_true(stringp(Stdio.File(file_stat("/dev/ptmx")?"/dev/ptmx":"/dev/ptc")->grantpt())) + test_any([[ + Stdio.File p = Stdio.File(); + return p->openpt("rw") && stringp(p->grantpt()); + ]], 1) ]]) test_do(rm("conftest"))