Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data between PHP and C executable in linux

Under Linux ,if I want to pass pure string from PHP to C, how do i do that? what I've tried do far is:

exec("./myexec.bin -a mystring");

in PHP and

getopt(argc,argv, "a:");

in C

everything works, but when i pass strings longers than MAX_ARG_STRLEN (131072), it will no longer return 0 instead it returns 127 which is command not found....

is there any other ways to pass string data to a linux executable? or is there any way to overcome the MAX_ARG_STRLEN problem?

like image 288
tom91136 Avatar asked Nov 19 '11 09:11

tom91136


3 Answers

You could use popen() to open a pipe to the executable:

$fp = popen('./myexec.bin', 'w');
fwrite($fp, $data);
pclose($fp);

Then, as previously suggested, read from stdin in your C program:

fopen(stdin, "r");
// ...

It is "safer" to use popen() rather than exec('/bin/echo') because you can write characters that would otherwise be interpreted by the shell (&, |, ...). Note that the handle returned from PHP's popen() must be closed with pclose().

like image 107
Linus Kleen Avatar answered Sep 24 '22 09:09

Linus Kleen


A few options spring immediately to mind:

  • Store the data in a file and pass the filename on the command line. It's easy and simple but does require permissions to create and store files somewhere on the filesystem.

  • Open a pipe between your program and the C program; leave both processes running, at least until the C program has consumed the entire contents of your string. popen() is a convenient wrapper around this approach, but it does assume that standard input is the right destination, and it is unidirectional. Managing the pipes yourself lets you use a different file descriptor -- and you can tell the child which file descriptor to read via a command line argument. (See gpg(1)'s command line option --passphrase-fd to see what I mean.)

  • Use a SysV or POSIX shared memory segment to store you data in PHP, and then attach to the shared memory segment from your C program to read the contents. Note that shared memory segments persist, so you must clean up after them when you are done -- otherwise you will leak memory. This doesn't require permissions to create files in the filesystem and might be a nicer mechanism than dealing with pipes and keeping both processes alive long enough for one to completely write the data and the other to completely read the data.

like image 32
sarnold Avatar answered Sep 22 '22 09:09

sarnold


If it is more like a data structure than a string, what about using an embedded webserver? At first sight it may sound like overkill for your purpose, but mongoose for example is a very lightweight embeddable webserver:

http://code.google.com/p/mongoose/

There's also a nice tutorial about the exact same problem you have, transfering data between a PHP application and a C/C++ application. It's in german, though ... but maybe google translator can help:

http://blog.aditu.de/2010/05/15/serverbridge-zwischen-php-und-cc/

like image 36
aurora Avatar answered Sep 23 '22 09:09

aurora