pike.git / src / modules / _Stdio / file.c

version» Context lines:

pike.git/src/modules/_Stdio/file.c:55:   #endif /* HAVE_SYS_FILE_H */      #ifdef HAVE_SYS_SOCKET_H   # include <sys/socket.h>   #endif      #ifdef HAVE_SYS_IOCTL_H   #include <sys/ioctl.h>   #endif    + #ifdef HAVE_SYS_STROPTS_H + #include <sys/stropts.h> + #endif +  + #ifdef HAVE_PTY_H + #include <pty.h> + #endif +  + #ifdef HAVE_TERMIOS_H + #include <termios.h> + #elif defined(HAVE_SYS_TERMIOS_H) + /* NB: Deprecated by <termios.h> above. */ + #include <sys/termios.h> + #endif +    #ifdef HAVE_LINUX_IF_H   #include <linux/if.h>   #endif      #ifdef HAVE_SYS_UIO_H   #include <sys/uio.h>   #endif /* HAVE_SYS_UIO_H */      #ifdef HAVE_SYS_XATTR_H   #include <sys/xattr.h>
pike.git/src/modules/_Stdio/file.c:2500:    f->flags&=~FILE_NOT_OPENED;    close_fd();    return 1;       default:    Pike_fatal("Bug in switch implementation!\n");    return 0; /* Make CC happy */    }   }    - /*! @decl string grantpt() -  *! -  *! If this file has been created by calling @[openpt()], return the -  *! filename of the associated pts-file. This function should only be -  *! called once. -  *! -  *! @returns -  *! Returns the filename of the corresponding pts. -  *! -  *! @note -  *! This function is only available on some platforms. -  */ - #if defined(HAVE_GRANTPT) || defined(USE_PT_CHMOD) || defined(USE_CHGPT) - static void file_grantpt( INT32 args ) + #if !defined(HAVE_POSIX_OPENPT) && defined(PTY_MASTER_PATHNAME) + static int my_posix_openpt(int flags)   { -  pop_n_elems(args); +  return open(PTY_MASTER_PATHNAME, flags); + } + #define HAVE_POSIX_OPENPT + #define posix_openpt(FLAGS) my_posix_openpt(FLAGS) + #endif +  + #ifndef HAVE_GRANTPT   #if defined(USE_PT_CHMOD) || defined(USE_CHGPT) -  + static int my_grantpt(int m) + {    push_text("Process.Process");    APPLY_MASTER("resolv", 1);      #ifdef USE_PT_CHMOD    /* pt_chmod wants to get the fd number as the first argument. */    push_text(USE_PT_CHMOD);    push_text("4");    f_aggregate(2);       /* Send the pty as both fd 3 and fd 4. */
pike.git/src/modules/_Stdio/file.c:2546: Inside #if defined(HAVE_GRANTPT) || defined(USE_PT_CHMOD) || defined(USE_CHGPT) and #if defined(USE_PT_CHMOD) || defined(USE_CHGPT)
      /* chgpt wants to get the pty on fd 0. */    push_text("stdin");    ref_push_object(Pike_fp->current_object);    f_aggregate_mapping(2);   #endif /* USE_PT_CHMOD */       apply_svalue(Pike_sp-3, 2);    apply(Pike_sp[-1].u.object, "wait", 0);    if(!UNSAFE_IS_ZERO(Pike_sp-1)) { -  Pike_error( - #ifdef USE_PT_CHMOD -  USE_PT_CHMOD - #else /* USE_CHGPT */ -  USE_CHGPT - #endif /* USE_PT_CHMOD */ -  " returned error %d.\n", Pike_sp[-1].u.integer); +  errno = EINVAL; +  return -1;    } -  pop_n_elems(3); - #else /* HAVE_GRANTPT */ +  return 0; + } + #define HAVE_GRANTPT + #define grantpt(M) my_grantpt(M) + #endif + #endif +  + #ifndef HAVE_UNLOCKPT + #define HAVE_UNLOCKPT + #define unlockpt(m) 0 + #endif +  + #if !defined(HAVE_OPENPTY) && defined(HAVE_PTSNAME) && defined(HAVE_POSIX_OPENPT) + static int my_openpty(int *master, int *slave, void *ignored_name, +  void *ignored_termp, void *ignored_winp) + { +  int m; +  int s; +  char *sname; +  if (!master || !slave) { +  errno = EINVAL; +  return -1; +  } +  m = posix_openpt(O_RDWR | O_NOCTTY); +  if (m < 0) return -1; +  if (!grantpt(m) && !unlockpt(m) && (sname = ptsname(m))) { +  int s = open(sname, O_RDWR | O_NOCTTY); +  if (s >= 0) { +  *master = m; +  *slave = s; + #ifdef I_PUSH +  /* Push required STREAMS modules. +  * cf pts(4D)/pts(7D) on Solaris. +  * +  * Not required on Solaris 11.4 and later. +  */ +  ioctl(s, I_PUSH, "ptem"); /* Pseudo terminal emulation mode */ +  ioctl(s, I_PUSH, "ldterm"); /* Terminal line discipline */ +  ioctl(s, I_PUSH, "ttcompat"); /* BSD terminal compatibility */ + #endif +  return 0; +  } +  } +  close(m); +  return -1; + } + #define HAVE_OPENPTY + #define openpty(M, S, N, T, W) my_openpty(M, S, N, T, W) + #endif +  + /*! @decl string grantpt() +  *! +  *! If this file has been created by calling @[openpt()], return the +  *! filename of the associated pts-file. This function should only be +  *! called once. +  *! +  *! @returns +  *! Returns the filename of the corresponding pts. +  *! +  *! @note +  *! This function is only available on some platforms. +  */ + #if defined(HAVE_GRANTPT) + static void file_grantpt( INT32 args ) + { +  pop_n_elems(args); +     /* Make sure the fd doesn't get closed when it gets sent    * to the subprocess (aka /usr/lib/pt_chmod).    */    set_close_on_exec(FD, 0);    if( grantpt( FD ) )    Pike_error("grantpt failed: %s\n", strerror(errno));    set_close_on_exec(FD, 1); - #endif /* USE_PT_CHMOD || USE_CHGPT */ +     push_text( ptsname( FD ) ); - #ifdef HAVE_UNLOCKPT +     if( unlockpt( FD ) )    Pike_error("unlockpt failed: %s\n", strerror(errno)); - #endif +    } - #endif /* HAVE_GRANTPT || USE_PT_CHMOD || USE_CHGPT */ + #endif /* HAVE_GRANTPT */      /*! @decl int close()    *! @decl int close(string direction)    *!    *! Close a file or stream.    *!    *! If direction is not specified, both the read and the write    *! direction is closed. Otherwise only the directions specified is    *! closed.    *!
pike.git/src/modules/_Stdio/file.c:2971: Inside #if defined(HAVE_OPENAT)
   }    else    {    push_new_fd_object(fd_fd_factory_fun_num, fd, flags, FILE_CAPABILITIES);    set_close_on_exec(fd, 1);    stack_pop_n_elems_keep_top(args);    }   }   #endif /* HAVE_OPENAT */    - #if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME)) + #if !defined(__NT__) && defined(HAVE_POSIX_OPENPT)   /*! @decl int openpt(string mode)    *!    *! Open the master end of a pseudo-terminal pair.    *!    *! @returns    *! This function returns @expr{1@} for success, @expr{0@} otherwise.    *!    *! @seealso    *! @[grantpt()]    */   static void file_openpt(INT32 args)   {    int flags,fd; - #ifdef HAVE_POSIX_OPENPT +     struct pike_string *flag_str; - #endif +     close_fd();       if(args < 1)    SIMPLE_TOO_FEW_ARGS_ERROR("openpt", 2);       if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING)    SIMPLE_BAD_ARG_ERROR("openpt", 1, "string");    - #ifdef HAVE_POSIX_OPENPT +     flags = parse((flag_str = Pike_sp[-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))
pike.git/src/modules/_Stdio/file.c:3028: Inside #if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME)) and #if defined(HAVE_POSIX_OPENPT)
   {    ERRNO=errno;    }    else    {    init_fd(fd, flags | fd_query_properties(fd, FILE_CAPABILITIES), 0);    set_close_on_exec(fd,1);    }    pop_n_elems(args);    push_int(fd>=0); - #else -  if(args > 1) -  pop_n_elems(args - 1); -  push_text(PTY_MASTER_PATHNAME); -  stack_swap(); -  file_open(2); - #endif +    }   #endif      #ifdef HAVE_FSYNC   /*! @decl int(0..1) sync()    *!    *! Flush buffers to disk.    *!    *! @returns    *!
pike.git/src/modules/_Stdio/file.c:4553: Inside #if undefined(UNIX_SOCKETS_WORKS_WITH_SHUTDOWN)
   if(!(type & ~(SOCKET_CAPABILITIES)))    {    i=socketpair_ultra(AF_UNIX, SOCK_STREAM, 0, inout);    if (i >= 0) {    type=SOCKET_CAPABILITIES;    break;    }    }   #endif    + #ifdef HAVE_OPENPTY +  if (!(type & ~(TTY_CAPABILITIES))) +  { +  i = openpty(inout, inout + 1, NULL, NULL, NULL); +  if (i >= 0) { +  type = TTY_CAPABILITIES; +  break; +  } +  } + #endif +     if (!i) {    Pike_error("Cannot create a pipe matching those parameters.\n");    }    }while(0);       if ((i<0) || (inout[0] < 0) || (inout[1] < 0))    {    ERRNO=errno;    if (inout[0] >= 0) {    while (fd_close(inout[0]) && errno == EINTR) {}
pike.git/src/modules/_Stdio/file.c:5913:      /*! @decl constant NOTE_REVOKE = 64    *    * Used with @[Stdio.File()->set_fs_event_callback()] to monitor for access revokation (unmount, etc).    *    * @note    * Available on systems that use kqueue.    */       + /*! @decl constant PROP_TTY = 128 +  *! +  *! The @[Stdio.File] object supports tty operations. +  *! +  *! @seealso +  *! @[Stdio.File()->pipe()] +  */ +    /*! @decl constant PROP_SEND_FD = 64    *!    *! The @[Stdio.File] object might support the @[Stdio.File()->send_fd()]    *! operation.    *!    *! @seealso    *! @[Stdio.File()->pipe()], @[Stdio.File()->send_fd()],    *! @[Stdio.File()->receive_fd()]    */   
pike.git/src/modules/_Stdio/file.c:6214: Inside #if defined(HAVE_LINUX_IF_H) && defined(HAVE_SYS_IOCTL_H)
   up++;    }       fd_close(fd);    }   #endif /* defined(HAVE_LINUX_IF_H) && defined(HAVE_SYS_IOCTL_H) */       push_mapping(m);   }    - #ifdef HAVE_OPENPTY - #include <pty.h> - #endif -  +    int fd_write_identifier_offset;      PIKE_MODULE_INIT   {    struct object *o;    int write_fun_num;       Pike_compiler->new_program->id = PROG_MODULE_STDIO_ID;       init_stdio_efuns();
pike.git/src/modules/_Stdio/file.c:6336: Inside #if defined(HAVE_FSETXATTR)
   */    add_integer_constant("XATTR_REPLACE", XATTR_REPLACE, 0 );   #endif    add_integer_constant("PROP_IPC",fd_INTERPROCESSABLE,0);    add_integer_constant("PROP_NONBLOCK",fd_CAN_NONBLOCK,0);    add_integer_constant("PROP_SEND_FD",fd_SEND_FD,0);    add_integer_constant("PROP_SHUTDOWN",fd_CAN_SHUTDOWN,0);    add_integer_constant("PROP_BUFFERED",fd_BUFFERED,0);    add_integer_constant("PROP_BIDIRECTIONAL",fd_BIDIRECTIONAL,0);    add_integer_constant("PROP_REVERSE",fd_REVERSE,0); + #ifdef HAVE_OPENPTY +  add_integer_constant("PROP_TTY",fd_TTY,0); + #endif       add_integer_constant("PROP_IS_NONBLOCKING", FILE_NONBLOCKING, 0);       /* seek modes. These are strings to keep compatibility in seek(). */    {    static char seek_how[] = {    SEEK_CUR,0,    SEEK_SET,0,    SEEK_END,0   #ifdef SEEK_DATA