I have a small binary program that I’m trying to write a web-based front end for. I realise this is probably stupid, but the program is safe: it doesn’t really do much, other than take an input, do some calculation, then return the output (and is written in a language where buffer overruns etc. are impossible).
I asked the best way to do this a few weeks ago, and was told PHP’s exec functions should work. Now that I’ve got round to it, I’ve been trying to get this working all morning, with no success. I can get the output of ‘ls …’ echo’d to the browser using PHP, like so:
However, replacing “ls” with the name of my executable, “MainWeb”, and I get no output! The executable is in the same directory as the PHP file. It lies in my path, and sshing onto the server allows me to execute it from the command line, permissions are also set correctly with chmod. I created a special version of the executable for running on the server which outputs everything to stdout (which I heard is often the problem). Even with no input, the executable should return two lines of output (and does from the command line), but … it isn’t when called from PHP.
Replacing the shell_exec call with a call to system, and analysing the return value, I see the call to MainWeb is giving me a 127 return value. Changing the path to an absolute path to the executable gives me a 11 return value, but no output. Does anybody have any idea what is wrong? It’s driving me crazy!
or it’s shell_exec counterpart, that the problems start. Running any standard unix utility seems to work, but not my program, as with the above snippet, I get return code 11 printed in my browser. Apparently this is a SIGSEGV (can anyone confirm)? And if so, what exactly is segfaulting? My program, or something else?
Not sure if this’ll help, but remember that ls is a shell built-in command. In my OS class (years ago now), this gave me fits on a project until I realized it gets treated differently than non-built-ins.
What happens if you exec ls but using the full path to ls (/bin/ls or whatever)?
Barring the results from that, I’m going to guess that it’s your executable that is segfaulting, and that it is because it is expecting some environment variable to be set, which is different when executed from within PHP.
I’m not sure which OS’es this is true for, but Linux and Solaris I’m pretty sure have actual binaries for ls.
but still returns the SEGFAULT return code, and no output, when run on the server. It looks like it’s something on the server that’s at fault, unless somebody can think of something else? AFAIK, the code doesn’t rely on any environment variables, or anything like that (unless hidden in a library, somewhere).
So, the question bugged me enough to look into it a little bit. Note that I have no knowledge of or experience with PHP, so I can’t help with specifics there. However…
From this page, the comment by Milen A. Radev says that system is translated as /bin/sh -c. I recall having some issues with something similar. One thing to realize (aside from the built-ins I mention above) is that interactive and non-interactive shells are handled differently. Also, minor differences do exist between bash and sh.
One issue I discovered (using ssh to execute commands; so it’s similar, but different) was that the spawned environment did not run my .bashrc (i.e., none of my usual environment variables were set). So, my PATH consisted only of the basic stuff; that might explain why you get a 127 with a standalone executable name, but an 11 when using a fully qualified name. In essence, what arseNal said.
Isn’t there a flag in PHP to set the system call to be verbose?
Huh, you’re absolutely right. I have to assume that it was a different command (probably cd).
This only reinforces my belief that it is somehow related to the shell environment. Because that’s really the only difference between your server php and your php cli. It might not be your binary explicitly looking at an env var but one of its dependencies could be.
Can you try running “set” as the system call in both the php server and php-cli and compare the output of the two? See if something jumps out at you?
Otherwise, you’ll just have to debug the thing by putting log statements in the binary or something, to see which line is causing the grief.
Ah yeah, that’s probably what you were thinking of.
Guys, thanks all for the help. I now have it working. I’d compiled my binary on my own computer (Ubuntu Karmic 32bit) then scp’d it into my webspace. The default server is a 64bit machine with an older kernel, and trying to execute the program with that was making PHP segfault. I’ve now got access to a 32bit machine, and the program works.