2

I am calling executable file with main() function from php script using exec(). Which works fine but return all printf() values rather only returning array:

main.cpp:

#include<stdio.h>
#include<string.h>
#include "foo.h"
int main(int argc, char *argv[] )
{
    char buffer[1024];
    char *ch;
    static int ar[2];
    strcpy(buffer,argv[1]);
    printf("Client : \n");
    if ( argc != 2 ) /* argc should be 2 for correct execution */
    {
              printf( "\n%s filename\n", argv[0] );
    }
    else 
    {
        printf("\nstring is :%s \n",buffer);
    ch=foo(buffer);
    ar[0]=((int*)ch)[0];
    ar[1]=((int*)ch)[1];
    printf("Counts is :%d  %d \n",ar[0],ar[1]);
    }
    return (int)ar;

}

my test.php

<?php
$s="critic worst";
escapeshellarg($s);
$a=array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad"'));
print_r($a[0]);
//echo exec('whoami');
?>

Which shows output:

Client : string is :nice bad Positive count: 2 Negative count: 2 array item2 2 Count is :2 2

I also tried with exec() which also gives same prob. Can any one suggest how to get ar[0] and ar[1] from main.cpp?

Client : string is :nice bad Positive count: 2 Negative count: 2 array item2 2 

This is from all printf() present in foo.cpp file.

When I use exec() then it gives Count is :2 2

How to get exact ar[0] and ar[1]

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
user123
  • 5,269
  • 16
  • 73
  • 121

3 Answers3

2

Perhaps simply

preg_match('/[0-9]*/', $output, $matches);

If I'm not mistaken...

To be sure:

preg_match('Counts is :([0-9]*)[^0-9]*([0-9]*)/',$output,$matches);

Also have a look at this question to find ouy how to use PHP and C(++) interactively

A quick, and hacky ugly messy workaround could be:

printf("%d",ar[0]);
return ar[1];//end main function

Then, in your PHP script:

$a = array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad"'),
           shel_exec('echo $?');
);

Then get the last numeric value from the output string, (preg_match('/([0-9]*)\w*$/',$a[0],$matches); should do it, and $a[1] will contain the value of ar[1] of the main.cpp file, because that was the exit code. Note that exit codes aren't for show. The signify something! Changeing them is generally a bad idea. I'd just change my main.cpp, and add the line:

printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);

This prints a clearly formatted string, which is easy to parse using a regular expression. Assuming *ar held values 123 and 456 respectively:

preg_match_all('/\]\=([^;@]*)/',$a[0],$matches);
var_dump($matches[1]);//[123,456]

Or better stil:

$parts = explode('@', $a[0]);
echo $parts[1];//ar[0]=123;ar[1]=456

Bottom line:

Add this to your main function in main.cpp:

printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);

and, to get the int values in php:

$a = array(shell_exec('..'));
preg_match_all('/[^=]*\=([^;@]*)/',$a[0],$matches);
var_dump($matches[1]);

That should do it.

$a = array();
$b = array();
if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('your command'), $matches))
{
   $a[] = (int) $matches[1][0];//optionally cast to int
   $b[] = (int) $matches[1][1];
}

That's all... not sure why $a and $b need to be arrays, but that's probably because you're going to call the client bin a couple of times.

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Thanks dear but I dont want to make that much complicated, my purpose is different so I just want to access the ar[] values! – user123 Jul 08 '13 at 10:55
  • 1
    @user174889: Well, you can't access the stack of your program through a php script. You just can't. You'll either have to write a function like `void getAr(int idx){ printf("%d", ar[idx]);}`, where `*ar` needs to be in scope, obviously... or you're going to have to parse the `main` functions output – Elias Van Ootegem Jul 08 '13 at 10:57
  • Can any how I call to main() function so that I can get in return value? can you please tell me how to parse main() functions output? – user123 Jul 08 '13 at 11:03
  • 2
    @user174889: You've got several issues: `(int) ar;` is casting a pointer to an int (don't ignore the compiler warnings). The regex I provided parses the output of the main function already. Accessing the return value of the `shel_exec` is easy on *NIX systems: change the command to `'(your command here) && echo $?'`, since `echo $?` echoes the exit code of the last executed program, which is the int returned by `int main`, that should yield what you need – Elias Van Ootegem Jul 08 '13 at 11:14
  • $a=array(shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad" && echo $?')); is it correct? – user123 Jul 08 '13 at 11:18
  • 1
    @user174889: Updated my answer. Don't use exit values, and the cast will still be wrong. You'll also need the parentheses,I think. PHP and shel_exec can do weird things if you combine several commands – Elias Van Ootegem Jul 08 '13 at 11:26
  • thank you very much, but this will really not gonna accepted! I have to access return array from main()! – user123 Jul 08 '13 at 11:40
  • You have very good command, can you please tell can I call main() function something like php extension? – user123 Jul 08 '13 at 11:40
  • 1
    @user174889: I'm sorry, but sometimes the answer you get isn't the answer you were hoping for, but PHP doesn't allow you to access stack memory that was allocated by another program. You _can't access a C(++) function from PHP_ you just can't. If you refuse to accept that, then no answer to your question will ever get accepted. – Elias Van Ootegem Jul 08 '13 at 11:45
  • @user174889: I've tried with `int* main(){ return ar;}` which merely returns the memory address of a pointer. you could try writing your own PHP extension to deal with C-pointers being returned to a PHP script, but that's just total overkill. Why won't you just print the values out, and parse the string that's being returned? I mean, really I've given you the regex to do just that – Elias Van Ootegem Jul 08 '13 at 11:50
  • yeah I accepted your answer but I was looking for what I exactly want! Do you think regex you constructed would let me achieve whatever int value return by my main() function? Later on I have to insert the sentence I passed and array values in database also! – user123 Jul 08 '13 at 13:18
  • 1
    @user174889: I don't know for sure, I don't know what you're actually doing. But if you have the int values printed out as I suggested `@ar[0]=%d;ar[1]=%d@`, then `/[@;][^=]*\=([^;@]*)/` is a pretty solid expression, that'll match negative, positive, and (if in due time it'd be a requirement) floats or even strings can be parsed – Elias Van Ootegem Jul 08 '13 at 13:23
  • Could you please tell me again which line should I add to main.cpp and php? Your post is little bit confusing! May in new answer! – user123 Jul 08 '13 at 13:34
  • 1
    'preg_match_all('/\]\=([^;@]*)/',$a[0],$matches); var_dump($matches[1]);' This in php and 'printf("@ar[0]=%d;ar[1]=%d@",ar[0],ar[1]);' in main.cpp right? – user123 Jul 08 '13 at 13:36
  • 1
    @user174889: check update, everything below _"Bottom line"_ is what you have to do. that should do the trick. I've tested it, and it worked for me – Elias Van Ootegem Jul 08 '13 at 13:43
  • 1
    Thanks a lot! It gave me `array(2) { [0]=> string(1) "2" [1]=> string(1) "2" }` as output. Can you please edit it to store ar[0] into $a and ar[1] to $b[] – user123 Jul 08 '13 at 13:48
  • @user174889: Done, now I'd really appreciate an upvote or accept vote for my efforts, if you don't mind my asking – Elias Van Ootegem Jul 08 '13 at 13:52
  • I respect you passion and effort! – user123 Jul 08 '13 at 13:56
  • 1
    @user174889: Of course not, because they're arrays, try replacing `$a[] = $matches[1][0];` with `$a = (int) $matches[1][0];` and then `echo $a;` – Elias Van Ootegem Jul 08 '13 at 14:02
  • 1
    It gives error `Notice: Array to string conversion in /opt/lampp/htdocs/test/test.php on line 16 Array`. My new code is: `$a = array(); $b = array(); if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad worst good"'), $matches)) { $a[] = (int) $matches[1][0];//optionally cast to int $b[] = (int) $matches[1][1]; } echo $a;` – user123 Jul 08 '13 at 14:33
  • Sorry but please review it! – user123 Jul 08 '13 at 14:33
  • 1
    @user174889: change `$a = array();` to `$a = null;` and `$a[] = (int) $matches[1][0];` to `$a = (int) $matches[1][0];` The warning merely says you're trying to echo an array. which you can't. Alternatively, just replace `echo $a;` with `echo implode(', ', $a);` to echo the entire echo as comma-separated values – Elias Van Ootegem Jul 08 '13 at 14:53
  • 1
    Why taking `$s="nice bad worst good";` and passing $s gives error: 'Notice: Undefined offset: 0 in /opt/lampp/htdocs/test/test.php on line 13'. Could I take string in var and passing var in place of string? – user123 Jul 08 '13 at 15:10
  • @Karimkhan: I don't know what line 13 is, so I don't know what the problem is. My guess is `$s` is `null` at that point, and you're accessing it as an array – Elias Van Ootegem Jul 09 '13 at 06:38
2

Thanks to Elias for help. This is the solution:

<?php

if (preg_match_all('/[^=]*\=([^;@]*)/', shell_exec('/home/technoworld/Videos/LinSocket/client "nice bad worst good"'), $matches))
{
   $x = (int) $matches[1][0];//optionally cast to int
   $y = (int) $matches[1][1];
   echo $x. '<br/>'. $y. '<br/>'
}

?>

$x,$y contain ar[0] and ar[1] respectively

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
user123
  • 5,269
  • 16
  • 73
  • 121
1

This will also work:

if (preg_match_all('/[^=]*=([^;@]*)/', shell_exec("/home/technoworld/Videos/LinSocket/client '$s'"), $matches)) //Values stored in ma.
{
    $x = (int) $matches[1][0];  //optionally cast to int
    $y = (int) $matches[1][1];
}

echo "<br/>"; echo "Positive count :$x";
echo "<br/>"; echo "Negative count :$y"; echo "<br/>";