[PHP-DEV] [PATCH] for proc_close() Bug #17538
Do a cvs diff -u and post the patch to the list with [PATCH] in the subject; CC me directly. I'll try and apply it over the weekend, unless someone else here applies it for you in the meantime. That would be great :) Thanks for your extensive testing of proc_open/proc_close :-) No problems. Something gives me the impression that I'm the first person to use the functions to any great extent, but it's been fun learning and playing with the PHP source. The patch is somewhat more developed than what I posted before, I commented what's actually happening (once I figured out what was actually happening), and it checks that the process exited normally now (it didn't before, which would have returned spurious exit codes in some cases). I am moderately confident that it should be fairy reliable, as opposed to what I posted before, which was more of a one-off this works for me, someone please make it work for everyone. Thanks, KimS ? proc_close_patch Index: ext/standard/exec.c === RCS file: /repository/php4/ext/standard/exec.c,v retrieving revision 1.76 diff -u -r1.76 exec.c --- ext/standard/exec.c 23 May 2002 10:17:07 - 1.76 +++ ext/standard/exec.c 13 Jun 2002 00:03:21 - -559,23 +559,33 GetExitCodeProcess(child, wstatus); FG(pclose_ret) = wstatus; #else -# if HAVE_SYS_WAIT +#if HAVE_SYS_WAIT_H int wstatus; pid_t child, wait_pid; child = (pid_t)rsrc-ptr; do { + /* fetch status of child process */ wait_pid = waitpid(child, wstatus, 0); - } while (wait_pid == -1 errno = EINTR); + + /* if wait_pid == 1 and errno == EINTR, then waitpid() is just +* alerting of a signal that's been caught - so keep looping +* until wait_pid != -1 (the child process has exited) or +* errno != EINTR (there was a real error, not just a caught +* signal) +*/ + } while (wait_pid == -1 errno == EINTR); - if (wait_pid == -1) - FG(pclose_ret) = -1; - else - FG(pclose_ret) = wstatus; -# else + /* if the child process exited normally, set pclose_ret to the exit +* status of the child process, otherwise set it to -1 (this might +* happen if there's no child process, or it didn't exit normally) +*/ + FG(pclose_ret) = wait_pid 0 WIFEXITED(wstatus) ? + WEXITSTATUS(wstatus) : -1; +#else FG(pclose_ret) = -1; -# endif +#endif #endif } -- PHP Development Mailing List http://www.php.net/ To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Bug #17538 proc_close() doesn't return exit value of process
Hi, I logged Bug #17538 proc_close() doesn't return exit value of process a little while a ago, full details are at http://bugs.php.net/bug.php?id=17538 obviously, but the short summary is that proc_close() doesn't return the exit value of the process, like it's meant to. The bug I logged has an example script and stuff. Anyway, I needed a fix soon, so I've had a poke around in the PHP source myself, and I have basically got pretty close to a fix. I deliberated for a little bit about whether I should try and make a patch, or log more info on the bug, but I decided that posting to the list was best, because I don't have a magic wand fix, rather some *very* relevant info that a PHP developer will be able to use to create a proper fix. Ok, so, all the problems I found are in ext/standard/exec.c (CVS version of course). This is the offending code: # if HAVE_SYS_WAIT int wstatus; pid_t child, wait_pid; child = (pid_t)rsrc-ptr; do { wait_pid = waitpid(child, wstatus, 0); } while (wait_pid == -1 errno = EINTR); if (wait_pid == -1) FG(pclose_ret) = -1; else FG(pclose_ret) = wstatus; # else FG(pclose_ret) = -1; # endif Firstly, the gdb was showing me that code inside here wasn't getting executed (waitpid() wasn't getting run). It turns out that there is no HAVE_SYS_WAIT in php_config.h, but there is a HAVE_SYS_WAIT_H. I imagine that perhaps it should be HAVE_SYS_WAIT_H? Anyway, that was what was causing the code not to be run. So, for the purposes of my experimentation, I just deleted the # if # else and # endif lines (and the FG() line between else and endif) so that the code could run, since clearly this is the code that sets pclose_ret, which is in turn the number returned by proc_close(). That was the first problem. I'm sure someone more knowledgeable about the PHP source will know if it's actually meant to be HAVE_SYS_WAIT_H, or something else. So, with that removed, I tried to compile, and the } while (wait_pid == -1 errno = EINTR); line gave me an invalid lvalue in assignment compiler error. Changing to errno == EINTR fixed that, but I'm not sure if it's meant to be == or not, or what's meant to be happening. But, I took a punt at ==, and it compiled. Then, I tried running some programs through proc_open() and proc_close(), but php was mangling the return values. The line: FG(pclose_ret) = wstatus; should be FG(pclose_ret) = WEXITSTATUS(wstatus); see man waitpid for details, basically wstatus contains more than just the exit code, and WEXITSTATUS() returns the relevant exit status number. So, I compiled again, and it worked! I ended up with: int wstatus; pid_t child, wait_pid; child = (pid_t)rsrc-ptr; do { wait_pid = waitpid(child, wstatus, 0); } while (wait_pid == -1 errno == EINTR); if (wait_pid == -1) FG(pclose_ret) = -1; else FG(pclose_ret) = WEXITSTATUS(wstatus); Now, it would be great if a PHP developer could apply this, or something along these lines, to the source tree to make proc_close() work (and close my bug!). As I say, I'm no PHP developer, nor even a particularly good C programmer, so there may well be other things to consider when applying a fix that I've missed, but this worked for me :) Thanks, KimS -- PHP Development Mailing List http://www.php.net/ To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Bidirectional Pipe
Hi All, I'm writing something in PHP at the moment, and I *really* need bi-directional pipe support, a la IPC::Open2 in Perl. IPC::Open2 works by returning two filehandles to the command to be run, one which can be written to and it goes to the STDIN of the command that gets run, and one that can be read from to get the output of the command. As far as I can tell, this cannot be done in PHP. passthru() doesn't allow writing to STDIN, apparently this has worked with popen() at some point according to a user comment in the manual, but it doesn't work for me using Linux and Apache. This is a very useful thing to be able to do, as there are many commands under *n?x that you can write to the STDIN of and read processed data from STDOUT, like tar, image processing utilities, tr, etc. I'd like to see this in PHP, and, if it's not there, I'm not opposed to writing to code to do it, since I know how to do this in C. I guess I'm asking: * am I correct that there isn't a way to do this in PHP at the moment? * do people agree that this would be a good thing to have? * if I were to write it, is someone interested in adding it to PHP, and perhaps helping me out with PHP-specific issues? Thanks, KimS -- PHP Development Mailing List http://www.php.net/ To unsubscribe, visit: http://www.php.net/unsub.php