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