Here's a patch for PTS support in proc_open, instead of having PHP_CAN_DO_PTS 
always
disabled this patch introduces --enable-pty option.
Added support for BSD4 PTS types.
Please review it.

-- 
Best regards,

Michael
Index: ext/standard/config.m4
===================================================================
RCS file: /repository/php-src/ext/standard/config.m4,v
retrieving revision 1.78
diff -u -u -r1.78 config.m4
--- ext/standard/config.m4      30 Dec 2004 07:08:37 -0000      1.78
+++ ext/standard/config.m4      6 Apr 2005 13:18:44 -0000
@@ -479,6 +479,15 @@
 
 PHP_CHECK_I18N_FUNCS
 
+dnl pty support
+PHP_ARG_ENABLE(pty, [Wherher to enable pseudo terminals support],
+[  --enable-pty            Enable pseudo terminals support], no, no)
+
+if test $PHP_PTY != "no"; then
+       AC_DEFINE(PHP_ENABLE_PTY, 1, [ ])
+       PHP_CHECK_FUNC(openpty, util)
+fi
+
 PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c 
crc32.c crypt.c \
                             cyr_convert.c datetime.c dir.c dl.c dns.c exec.c 
file.c filestat.c \
                             flock_compat.c formatted_print.c fsock.c head.c 
html.c image.c \
Index: ext/standard/proc_open.c
===================================================================
RCS file: /repository/php-src/ext/standard/proc_open.c,v
retrieving revision 1.32
diff -u -u -r1.32 proc_open.c
--- ext/standard/proc_open.c    7 Mar 2005 16:17:12 -0000       1.32
+++ ext/standard/proc_open.c    6 Apr 2005 13:18:44 -0000
@@ -61,16 +61,114 @@
  * */
 #ifdef PHP_CAN_SUPPORT_PROC_OPEN
 
-#if 0 && HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && 
HAVE_TERMIOS_H
-# include <sys/ioctl.h>
-# include <termios.h>
-# define PHP_CAN_DO_PTS        1
-#endif
-
 #include "proc_open.h"
 
 static int le_proc_open;
 
+#if PHP_ENABLE_PTY
+/* {{{ php_openpty */
+static int php_openpty (int *amaster, int *aslave, char *name)
+{
+#if HAVE_OPENPTY
+       return openpty (amaster, aslave, name, NULL, NULL);
+
+#else
+       int master, slave;
+
+#if defined(__linux__) || defined(__sun__) || defined(_AIX) || defined(__osf__)
+       char *pts_name;
+
+       if ((master = open ("/dev/ptmx", O_RDWR)) < 0) { /* open master */
+               goto failure;
+       }
+       if (grantpt (master) < 0) { /* grant access to slave */
+               goto failure_clean_master;
+       }
+       if (unlockpt (master) < 0) { /* clear slave's lock flag */
+               goto failure_clean_master;
+       }
+       if ((pts_name = (char *)ptsname (master)) == NULL) { /* find slave's 
name */
+               goto failure_clean_master;
+       }
+       if ((slave = open (pts_name, O_RDWR)) < 0) { /* open slave */
+               goto failure_clean_master;
+       }
+
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || 
defined(__MACH__)
+       char pty_name[] = "/dev/ptyXX";
+       const char *cp1, *cp2;
+       int ttygid;
+       struct group *grptr;
+
+       if ((grptr = getgrnam ("tty")) != NULL) { /
+               ttygid = grptr->gr_gid;
+       } else {
+               ttygid = -1; /* group tty is not in the group file */
+       }
+
+       for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
+               pty_name[8] = *cp1;
+
+               for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
+                       pty_name[5] = 'p';
+                       pty_name[9] = *cp2;
+
+                       if ((master = open (pty_name, O_RDWR, 0)) < 0) {
+                               if (errno == ENOENT) {
+                                       break; /* try the next pty group */
+                               }
+                               goto failure;
+                       } else {
+                               pty_name[5] = 't'; /* change pty -> tty */
+
+                               /* following two functions don't work unless 
we're root */
+                               chown (pty_name, getuid(), ttygid);
+                               chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP);
+
+                               if ((slave = open (pty_name, O_RDWR)) < 0) {
+                                       goto failure_clean_master;
+                               }
+                               goto success;
+                       }
+               }
+       }
+       errno = ENOENT; /* out of ptys */
+       goto failure;
+
+#else
+       goto failure; /* PTY wasn't checked on other systems */
+
+#endif /* systems */
+
+success:
+       if (name) {
+               strcpy(name, pts_name); /* return name of slave */
+       }
+       if(amaster) {
+               *amaster = master; /* return master's fd */
+       }
+       if (aslave) {
+               *aslave = slave; /* return slave's fd */
+       }
+       return 0;
+
+failure_clean_master:
+       close (master);
+       return (-1);
+
+failure_clean_master_slave:
+       close (master);
+       close (slave);
+       return (-1);
+
+#endif /* HAVE_OPENPTY */
+
+failure:
+       return (-1);
+}
+/* }}} */
+#endif /* PHP_ENABLE_PTY */
+
 /* {{{ _php_array_to_envp */
 static php_process_env_t _php_array_to_envp(zval *environment, int 
is_persistent TSRMLS_DC)
 {
@@ -501,8 +599,8 @@
        struct php_process_handle *proc;
        int is_persistent = 0; /* TODO: ensure that persistent procs will work 
*/
        int suppress_errors = 0;
-#if PHP_CAN_DO_PTS
-       php_file_descriptor_t dev_ptmx = -1;    /* master */
+#if PHP_ENABLE_PTY
+       php_file_descriptor_t master_pty = -1;  /* master */
        php_file_descriptor_t slave_pty = -1;
 #endif
 
@@ -674,26 +772,16 @@
                                descriptors[ndesc].childend = fd;
 #endif
                        } else if (strcmp(Z_STRVAL_PP(ztype), "pty") == 0) {
-#if PHP_CAN_DO_PTS
-                               if (dev_ptmx == -1) {
-                                       /* open things up */
-                                       dev_ptmx = open("/dev/ptmx", O_RDWR);
-                                       if (dev_ptmx == -1) {
-                                               php_error_docref(NULL 
TSRMLS_CC, E_WARNING, "failed to open /dev/ptmx, errno %d", errno);
-                                               goto exit_fail;
-                                       }
-                                       grantpt(dev_ptmx);
-                                       unlockpt(dev_ptmx);
-                                       slave_pty = open(ptsname(dev_ptmx), 
O_RDWR);
-
-                                       if (slave_pty == -1) {
-                                               php_error_docref(NULL 
TSRMLS_CC, E_WARNING, "failed to open slave pty, errno %d", errno);
+#if PHP_ENABLE_PTY
+                               if (master_pty == -1) {
+                                       if (php_openpty (&master_pty, 
&slave_pty, NULL) == -1) {
+                                               php_error_docref(NULL 
TSRMLS_CC, E_WARNING, "cannot open pty pseudo terminal");
                                                goto exit_fail;
                                        }
                                }
                                descriptors[ndesc].mode = DESC_PIPE;
-                               descriptors[ndesc].childend = dup(slave_pty);
-                               descriptors[ndesc].parentend = dup(dev_ptmx);
+                               descriptors[ndesc].childend = slave_pty;
+                               descriptors[ndesc].parentend = master_pty;
                                descriptors[ndesc].mode_flags = O_RDWR;
 #else
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"pty pseudo terminal is not support on this system");
@@ -767,21 +855,19 @@
        if (child == 0) {
                /* this is the child process */
 
-#if PHP_CAN_DO_PTS
-               if (dev_ptmx >= 0) {
-                       int my_pid = getpid();
-
-#ifdef TIOCNOTTY
-                       /* detach from original tty. Might only need this if 
isatty(0) is true */
-                       ioctl(0,TIOCNOTTY,NULL);
-#else
+#if PHP_ENABLE_PTY
+               if (master_pty >= 0) {
                        setsid();
+
+#if defined(TIOCSCTTY) && !defined(CIBAUD)
+                       /* 44BSD way to acquire controlling terminal */
+                       /* !CIBAUD to avoid doing this under SunOS */
+                       if (ioctl (slave_pty, TIOCSCTTY, (char *)NULL) < 0) {
+                               goto failure;
+                       }
 #endif
-                       /* become process group leader */
-                       setpgid(my_pid, my_pid);
-                       tcsetpgrp(0, my_pid);
                }
-#endif
+#endif /* PHP_ENABLE_PTY */
                
                /* close those descriptors that we just opened for the parent 
stuff,
                 * dup new descriptors into required descriptors and close the 
original
@@ -794,17 +880,22 @@
                        }
                        if (dup2(descriptors[i].childend, descriptors[i].index) 
< 0)
                                perror("dup2");
-                       if (descriptors[i].childend != descriptors[i].index)
-                               close(descriptors[i].childend);
+                       
+#if PHP_ENABLE_PTY
+                       if (descriptors[i].childend != slave_pty) {
+#endif
+                               if (descriptors[i].childend != 
descriptors[i].index) {
+                                       close(descriptors[i].childend);
+                               }
+#if PHP_ENABLE_PTY
+                       }
+#endif
                }
-
-#if PHP_CAN_DO_PTS
-               if (dev_ptmx >= 0) {
-                       close(dev_ptmx);
-                       close(slave_pty);
+#if PHP_ENABLE_PTY
+               if (slave_pty > 2) {
+                       close (slave_pty);
                }
 #endif
-               
                if (cwd) {
                        chdir(cwd);
                }
@@ -887,13 +978,6 @@
        }
        array_init(pipes);
 
-#if PHP_CAN_DO_PTS
-       if (dev_ptmx >= 0) {
-               close(dev_ptmx);
-               close(slave_pty);
-       }
-#endif
-
        /* clean up all the child ends and then open streams on the parent
         * ends, where appropriate */
        for (i = 0; i < ndesc; i++) {
@@ -953,9 +1037,9 @@
 exit_fail:
        _php_free_envp(env, is_persistent);
        pefree(command, is_persistent);
-#if PHP_CAN_DO_PTS
-       if (dev_ptmx >= 0) {
-               close(dev_ptmx);
+#if PHP_ENABLE_PTY
+       if (master_pty >= 0) {
+               close(master_pty);
        }
        if (slave_pty >= 0) {
                close(slave_pty);

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to