I wrote a little test program which compiles and runs as expected when compiled with GCC:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSZ 512
int ping_test(char *host);
int main(void) {
if (ping_test("192.168.1.1"))
printf("PING OK!\n");
else
printf("PING FAIL!\n");
}
// returns 1 if ping succeeds, 0 otherwise
int ping_test(char *host)
{
FILE *in;
int i = 0;
int ok = 1;
extern FILE *popen();
char buff[BUFFSZ] = {0};
char res[BUFFSZ] = {0};
char cmd[50]={0};
sprintf(cmd,"ping -c 1 %s",host);
if(!(in = popen(cmd, "r"))){
exit(1);
}
while(fgets(buff, sizeof(buff), in)!=NULL){
strcat(res,buff);
}
pclose(in);
printf("RESULT: %s\n",res);
// check for string "100%"
for (i=0;i<BUFFSZ;i++) {
if (res[i] == '\%' &&
res[i-1] =='0' &&
res[i-2] =='0' &&
res[i-3] =='1'){
ok = 0;
return ok;
} else
ok = 1;
}
return ok;
}
now I'd want to use this same function in a Qt C++ program I'm working on, so I copied the function into a private method in my class:
int JTFTestSuite::Ping(char *host)
{
FILE *in;
int i = 0;
int ok = 1;
extern FILE *popen();
char buff[BUFFSZ] = {0};
char res[BUFFSZ] = {0};
char cmd[BUFFSZ]={0};
sprintf(cmd,"ping -c 1 %s",host);
if(!(in = popen(cmd, "r"))){
exit(1);
}
while(fgets(buff, sizeof(buff), in)!=NULL){
strcat(res,buff);
}
pclose(in);
printf("RESULT: %s\n",res);
// check for string "100%"
for (i=0;i<BUFFSZ;i++) {
if (res[i] == '\%' &&
res[i-1] =='0' &&
res[i-2] =='0' &&
res[i-3] =='1'){
ok = 0;
return ok;
} else
ok = 1;
}
return ok;
}
declaration in header:
private:
int Ping(char *host);
but now, it doesn't compile, the compiler complains with:
error: too many arguments to function 'FILE* popen()'
if(!(in = popen(cmd, "r"))){
^
Why is this I'm wondering? The includes are identical in both source files
In C, you can declare a function without declaring any particular prototype, by using an empty parameter list. (You shouldn't do this. It has been deprecated for a long time. But you can.) If you want to declare a function which takes no parameters, you need to use void
as the parameter list.
This doesn't work in C++. In C++, an empty parameter list means the function takes no arguments.
So in C,
FILE* popen(); // unspecified what the parameters are
FILE* f = popen(cmd, "r"); // called with two strings
In C++
FILE* popen(); // takes no arguments
FILE* f = popen(cmd, "r"); // illegal because popen takes no argument.
Rather than declaring popen
(and other library functions) yourself, #include
the correct header file. popen
and pclose
are in <stdio.h>
, but you need to make sure you define the correct feature test macro before any #include
s. (#define _XOPEN_SOURCE 700
will work, for example.)