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