what kinds of errors popen record - c

I am trying to execute the command "adb tcpip 5555" in cmd and get the output to use it in another statement.
This adb code should give error: no devices/emulators found but the buffer remains empty.
FILE* lsofFile_p = popen("c:\\adb tcpip 5555" ,"r");
char* line_p = fgets(buffer, sizeof(buffer), lsofFile_p);
printf("\n***\nbuffer = %s***\n\n", buffer);
pclose(lsofFile_p);
printf("\n***\nbuffer = %s***\n\n", buffer);

popen() returns FILE* to the stdout of the command you run. So, if you want to read stderr (it looks like the command you run gives errors that goes to stderr), then
you could do redirect stderr to stdout:
FILE* lsofFile_p = popen("c:\\adb tcpip 5555 2>&1" ,"r");
Be aware that this will mix stdout and stderr. So, there's no way to differentiate output and errors, if that matters.

Related

How to enter in to network namespace and read the file content using C program

In my Linux machine, i have configured the network namespace. With shell script or command line or system command I was able to fetch the file content present in the network namespace.
ip netns exec test_namespace cat /var/test_namespace/route.conf
Output:
cardIP=10.12.13.1
In a C program, I can use system("ip netns exec test_namespace cat /var/test_namespace/route.conf") command to get the output. But I prefer not to use this option.
Looking for an alternative method, I am not sure about the system call setns, how to use it. Any ideas?
If you're alergic to system, you can use popen to read the script output as a file:
Example
/* the command to execute */
FILE *f = popen("ls", "r");
/* Here, we should test that f is not NULL */
printf("result of `ls`:\n");
/* read process result */
char buffer[256];
while (fgets(buffer, sizeof buffer, f)
{
puts(buffer);
}
/* and close the process */
pclose(f);

how to echo std output exactly in C

I'm making essentially a terminal wrapper. I want my program to read from stdin, and for any inputs that come in, echo it EXACTLY the way it is, even if it's wrong.
Right now, I'm doing:
FILE *output = popen(buffer, "r");
memset(buffer, '\0', BUFF_SIZE * 2);
while (fgets(buffer, sizeof(buffer), output) != 0)
{
printf("%s", buffer);
memset(buffer, '\0', BUFF_SIZE * 2);
}
pclose(output);
}
where I'm calling shell commands using popen, but in certain situations, for example, when the command is not found, the output returned by using popen won't be exactly the same compared to when using the terminal without the wrapper. For example, if I input $ asd, linux terminal will return
No command 'asd' found, but there are 24 similar ones
asd: command not found
whereas popen will return:
sh: 1: asd not found
I would like to have the default terminal response rather than what popen returns, would this be possible? If so, how?

C - popen not showing right output

anyone know how I can fix this?
char bash_cmd[256] = "curl";
char buffer[1000];
FILE *pipe;
int len;
pipe = popen(bash_cmd, "r");
if (NULL == pipe) {
perror("pipe");
exit(1);
}
fgets(buffer, sizeof(buffer), pipe);
printf("OUTPUT: %s", buffer);
pclose(pipe);
The above code snippit is returning the following:
OUTPUT: (�3B
instead of what it should be returning which is:
curl: try 'curl --help' or 'curl --manual' for more information
Something is wrong, I can't figure out what. When I replace "curl" with, say, "ls -la" it works fine, but for whatever reason only when I use curl, it doesn't properly save the output into buffer. What could I do to fix this?? thanks in advance
Also, replacing "curl" with the full path to curl, (/usr/bin/curl) doesn't work either. ;(
When I run your code, I find that the output is indeed approximately what you describe, but that the output you expect is also printed immediately previous. It seems highly likely, therefore, that curl is printing the usage message to its stderr rather than to its stdout, as indeed it should do.
You do not check the return value of fgets(); I suspect you would find that it is NULL, indicating that the end of the stream occurred before any data was read. In that case, I do not think fgets() modifies the provided buffer.
If you want to capture curl's stderr in addition to its stdout, then you can apply I/O redirection to the problem:
char bash_cmd[256] = "curl 2>&1";
That would not work (directly) with the execve()-family functions, but popen() runs the given command via a shell, which should handle the redirection operator just fine.
For general purposes, however, combining curl's output and error streams may not be what you want. If both real output and real diagnostics were emitted then they would be intermingled.
The output you expect from curl is going to stderr not stdout. In fact nothing is written to stdout. The output you are printing is the uninitialized contents of the buffer.
Your code should check the return value of fgets, which will be null if no characters were read (or if an error occurred).

C: Linux command executed by popen() function not showing results

I have the code below that I refer the thread on here to use the popen function
int main(int argc,char *argv[]){
FILE* file = popen("ntpdate", "r");
char buffer[100];
fscanf(file, "%100s", buffer);
pclose(file);
printf("buffer is :%s\n", buffer);
return 0;
}
It outputs:
21 Apr 03:03:03 ntpdate[4393]: no server can be used, exiting
buffer is:
why printf does not output anything? If I use ls as a command, then printf outputs the ls output. what am I doing wrong ntpdate executing?
If I execute the code below (referring the webpage)
#define COMMAND_LEN 8
#define DATA_SIZE 512
int main(int argc,char *argv[]){
FILE *pf;
char command[COMMAND_LEN];
char data[DATA_SIZE];
// Execute a process listing
sprintf(command, "ntpdate");
// Setup our pipe for reading and execute our command.
pf = popen(command,"r");
if(!pf){
fprintf(stderr, "Could not open pipe for output.\n");
return;
}
// Grab data from process execution
fgets(data, DATA_SIZE , pf);
// Print grabbed data to the screen.
fprintf(stdout, "-%s-\n",data);
if (pclose(pf) != 0)
fprintf(stderr," Error: Failed to close command stream \n");
return 0;
}
I get
21 Apr 03:15:45 ntpdate[5334]: no servers can be used, exiting
-�2}�����"|�4#|�-
Error: Failed to close command stream
what are wrongs on the codes above?
Since the output is going to stderr you need to redirect stderr like so:
FILE* file = popen("ntpdate 2>&1", "r");
this will redirect stderr to stdout and so you will see output from both. Second issue fscanf will stop at the first space so you can replace with fgets:
fgets(buffer, 100, file);
As Shafik Yaghmour correctly diagnosed, the output you see from ntpdate is written (correctly) to its standard error, which is the same as your programs standard error.
To get the error messages sent down the pipe, use:
FILE *file = popen("ntpdate 2>&1", "r");
That sends the standard error output from ntpdate to the standard output of the command, which is the pipe you're reading from.
Of course, it looks like using ntpdate isn't going to work well until you've configured something.

How to execute a bash command in C and retrieve output?

I'm trying to execute a bash command from c and retrieve and show the result.
I've tried with system but it doesn't work.
My code looks like:
char command[200];
sprintf(command,"lsof -iTCP:%d | cut -d\"\" -f1 | tail -1",port);
printf("Port %d is open\n and is listened by %s",port,system(command));
Please help. I need this .
Edit aside from the actual question, I'd be using
sudo netstat -tlpn
(shows the processes that are listening on TCP ports, not resolving the ports/addresses)
Perhaps combine it with a bit of grep:
sudo netstat -tlpn | grep :7761
to find where port :7761 is being listened?
You can use popen.
With popen you get the benefit that you receive the process output asynchronously (you will be able to stop processing if the answer is on the first line of output without having to wait for the subprocess to complete; simply pclose and the subprocess will die with SIGPIPE)
A sample straight from the Standards Documentation:
The following example demonstrates the use of popen() and pclose() to execute the command ls * in order to obtain a list of files in the current directory:
#include <stdio.h>
...
FILE *fp;
int status;
char path[PATH_MAX];
fp = popen("ls *", "r");
if (fp == NULL)
/* Handle error */;
while (fgets(path, PATH_MAX, fp) != NULL)
printf("%s", path);
status = pclose(fp);
if (status == -1) {
/* Error reported by pclose() */
...
} else {
/* Use macros described under wait() to inspect `status' in order
to determine success/failure of command executed by popen() */
...
}
system(command) returns the return code of the command, not its output.
If you want to read the output of a command, you should use popen
This returns a file descriptor to the output, which you can read from just like a normal file.

Resources