Right yeah thx, actially its possible to do it w/o reallocating the memory and still getting the last line of the result: https://github.com/voron00/libcod/co...9b91bba6b580d0
Printable View
Right yeah thx, actially its possible to do it w/o reallocating the memory and still getting the last line of the result: https://github.com/voron00/libcod/co...9b91bba6b580d0
Just this:
Because:PHP Code:
void gsc_utils_execute() { // Returns complete command output as a string
char *cmd;
if ( ! stackGetParams("s", &cmd)) {
printf("scriptengine> ERROR: please specify the command as string to gsc_execute_command()\n");
stackPushUndefined();
return;
}
setenv("LD_PRELOAD", "", 1); // dont inherit lib of parent
char *result = exec(cmd);
stackPushString( result );
free(result); // <------
}
http://man7.org/linux/man-pages/man3/getline.3.html
And init the char *result in exec(char *) to NULL, since setting a pointer to NULL automatically is "luck" (depending on compiler if they init it).Code:getline() reads an entire line from stream, storing the address of
the buffer containing the text into *lineptr. The buffer is null-
terminated and includes the newline character, if one was found.
If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line. This buffer
should be freed by the user program even if getline() failed.
Full test:
Just compile it:PHP Code:
#include <stdio.h>
#include <stdlib.h>
char *exec(const char* command) {
FILE *fp;
char *result = NULL; // plz init, otherwise it COULD be non-NULL (depending on compiler)
size_t len = 0;
fp = popen(command, "r");
if (fp == NULL) {
printf("Cannot execute command:\n%s\n", command);
return NULL;
}
while(getline(&result, &len, fp) != -1) {
fputs(result, stdout); // nice for debugging, but in actual release server kinda spammy to print every result
}
pclose(fp);
return result;
}
int main() {
char *result = exec("ls -l");
printf("ret: \"%s\"", result);
free(result);
return 0;
}
gcc exec.c -o exec.exe
And run it with valgrind: valgrind --tool=memcheck ./exec.exe
Everything will be ok then, but when you forget free(result);, valgrind will print the error:
About the pointer syntax, the asterix belongs to the variable name. You can simply understand this, when you want e.g. 2 pointers. What do you write?Code:k_tracker@euve78301:~$ valgrind --tool=memcheck ./exec.exe
==17356== Memcheck, a memory error detector
==17356== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==17356== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==17356== Command: ./exec.exe
==17356==
total 625772
-rwxr-xr-x 1 k_tracker k_tracker 1300 Dez 12 2014 autobahn2.js
-rwxr-xr-x 1 k_tracker k_tracker 913 Dez 10 2014 autobahn.js
drwxr-xr-x 3 k_tracker k_tracker 4096 Okt 15 2013 bin
drwxrwxr-x 2 k_tracker k_tracker 4096 Nov 30 05:21 boost
-rwxr-xr-x 1 k_tracker k_tracker 22803 Jan 21 2015 calculator.js
-rwxr-xr-x 1 k_tracker k_tracker 3737 Dez 10 2014 chat.js
drwxr-xr-x 2 k_tracker k_tracker 4096 Okt 15 2013 classes
-rwxr-xr-x 1 k_tracker k_tracker 3475 Nov 19 2012 debug.php
-rwxr-xr-x 1 k_tracker k_tracker 330 Dez 15 2014 dns.js
-rw-rw-r-- 1 k_tracker k_tracker 516 Jan 3 03:15 exec.c
-rwxrwxr-x 1 k_tracker k_tracker 8832 Jan 3 03:15 exec.exe
drwxrwxr-x 2 k_tracker k_tracker 4096 Okt 1 03:06 filefront
-rw-rw-r-- 1 k_tracker k_tracker 452 Okt 1 03:00 kt.txt
drwxr-xr-x 4 k_tracker k_tracker 4096 Okt 15 2013 lib
-rwxr-xr-x 1 k_tracker k_tracker 3380 Nov 19 2012 main.php
drwxr-xr-x 14 k_tracker k_tracker 4096 Dez 1 20:16 mariadb
-rwxr-xr-x 1 k_tracker k_tracker 309533236 Jun 17 2015 mariadb.1
-rw-rw-r-- 1 k_tracker k_tracker 331091501 Okt 15 23:14 mariadb.tar.gz
-rwxr-xr-x 1 k_tracker k_tracker 3858 Jul 1 2015 my.cnf
drwxr-xr-x 7 k_tracker k_tracker 4096 Dez 10 2014 nodejs
drwxr-xr-x 28 k_tracker k_tracker 4096 Sep 24 16:07 node_modules
drwxr-xr-x 2 k_tracker k_tracker 4096 Jul 2 2015 ntop
-rwxr-xr-x 1 k_tracker k_tracker 6681 Nov 19 2012 query_master.js
-rwxr-xr-x 1 k_tracker k_tracker 335 Dez 10 2014 rpc.js
-rwxr-xr-x 1 k_tracker k_tracker 46 Okt 15 2013 server.sh
drwxr-xr-x 2 k_tracker k_tracker 4096 Sep 24 16:07 tmp
drwxr-xr-x 4 k_tracker k_tracker 4096 Jun 30 2015 tracker
drwxr-xr-x 4 k_tracker k_tracker 4096 Jun 30 2015 tracker_floater
drwxr-xr-x 5 k_tracker k_tracker 4096 Nov 15 00:13 tracker_iznogod
-rwxr-xr-x 1 k_tracker k_tracker 327 Jul 10 2014 unity2.js
-rwxr-xr-x 1 k_tracker k_tracker 1082 Jul 10 2014 unity.js
-rwxr-xr-x 1 k_tracker k_tracker 709 Dez 11 2014 wamp_client.js
-rwxr-xr-x 1 k_tracker k_tracker 238 Dez 11 2014 wamp.js
ret: "-rwxr-xr-x 1 k_tracker k_tracker 238 Dez 11 2014 wamp.js
"==17356==
==17356== HEAP SUMMARY:
==17356== in use at exit: 120 bytes in 1 blocks
==17356== total heap usage: 2 allocs, 1 frees, 376 bytes allocated
==17356==
==17356== LEAK SUMMARY:
==17356== definitely lost: 120 bytes in 1 blocks
==17356== indirectly lost: 0 bytes in 0 blocks
==17356== possibly lost: 0 bytes in 0 blocks
==17356== still reachable: 0 bytes in 0 blocks
==17356== suppressed: 0 bytes in 0 blocks
==17356== Rerun with --leak-check=full to see details of leaked memory
==17356==
==17356== For counts of detected and suppressed errors, rerun with: -v
==17356== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
k_tracker@euve78301:~$
This?
Or this?Code:char* a, b;
Well, as said already, the 2nd way is the correct way, since the asterix belongs to the variable name.Code:char *a, *b;
Also why just return the last line? Just return an array with every line :^)
Simple example from scandir():
PHP Code:
void gsc_utils_scandir() {
char *dirname;
if ( ! stackGetParams("s", &dirname)) {
stackPushUndefined();
return;
}
DIR *dir;
struct dirent *dir_ent;
dir = opendir(dirname);
if ( ! dir) {
stackPushUndefined();
return;
}
stackPushArray();
while (dir_ent = readdir(dir)) {
stackPushString(dir_ent->d_name);
stackPushArrayLast();
}
closedir(dir);
}
Pth... What use me? :D