popen() is successfull for all commands - c

No matter what "cmd" string is passed in popen(), it is never FAILING for me
So fp is never NULL even for random "cmd" string.
FILE *fp;
char path[1035];
char cmd = "randomrandomrandom";
fp = popen(cmd, "r");
if (fp == NULL) {
//Handle Error
exit(1);
}
while (fgets(path, sizeof(path)-1, fp) != NULL) {
printf("%s", path);
}
pclose(fp);

popen runs an instance of the shell. Starting a shell normally succeeds. You need to determine if it has terminated successfully. popen itself cannot do that, but pclose can: it returns the status of the child process (or -1 if another error has occurred).
So in order to verify that the command has been executed successfully, one needs to check return values of both popen and pclose.

It seems to be behaving as expected:
http://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html
As you can see, popen only fails when its internal pipe command fails--the stream cannot be opened. For example, all the file descriptors are in use

Related

Segmentation fault when not specifying input file on command line

I am writing a program that reads from a file passed as an arguement, or reads from stdin if no arguements are given.
The code runs fine with a file passed, but I get a seg fault when no file is passed.
I basically call fopen on argv[1] if a file was given, but if no file was given I call:
f = fopen("stdin", "r");
Is this the correct syntax for opening stdin as a file?
When you start a program, the main() function is not the first thing that
get's called, quite a few things happen before the main() function is
called. One of those things is to open stdin, stdout and stderr. In
general you don't need to worry about the details how the OS does that, you
just can relay that when main() is executed, these streams are open and you
can use them.
So in your case, you can do this:
#include <stdio.h>
int main(int args, char **argv) {
FILE *fp;
if(args == 1) {
fp = stdin;
} else {
fp = fopen(argv[1], "r");
if(fp == NULL) {
fprintf(stderr, "Unable to open %s for writing\n", argv[1]);
return 1;
}
}
// do your read operations on fp
if(fp != stdin) {
fclose(fp);
}
return 0;
}
So when you call the program without arguments, stdin is used, otherwise a
file is used.
The reason why your code crashes is because
f = fopen("stdin", "r");
tries to open a file literally called stdin, which you most probably don't
have. fopen will return NULL and you probably don't check for that. If you
try to use a function that expects a FILE* pointer but pass NULL, then
you'll most likely will get a segfault.
USE f = stdin;
NOT f = fopen("stdin", "r");

Run a system command with system() and send output

So what I am trying to do is to invoke a system command with system() function and then whatever its output is I would like to take it and send it over to the client (socket connection).
Client can send various messages. It can be ls but it might be even qwerty. I would like to take the ouput and place it in the write() function as a const void* buffer argument. I have seen this topic but I can get it done to work. So far I thought it could go somewhere of these lines but whatever I tried it did not work.
/* buffer is message from the client: ls, ls -l, whatever*/
system(buffer)
fp = popen(buffer, "r");
if(fp == NULL)
printf("Failed ot run command\n");
while(fgets(path, sizeof(path), fp) != NULL) {
//modify output here?
}
pclose(fp);
write(socket_fd, output, strlen(buffer));
You should only use popen() and not system() as it describes in the question you linked.
The path variable in the question you linked seems to be misnamed. It contains the output of the system call. You can rename it to output if you wish.
write() takes the length of the buffer you are sending it. In this case, that will be the length of output, not the length of buffer.
Putting this all together gives the following:
char output[1035];
fp = popen(buffer, "r");
if(fp == NULL)
printf("Failed ot run command\n");
while(fgets(output, sizeof(output), fp) != NULL) {
write(socket_fd, output, strlen(output));
}
pclose(fp);

calling commands using 'system()' from inside a program

I want to execute some executable files from inside a C program using system(). I want to ensure that the command executed completely; after that, I want to use the output of the previously executed command. For example:
{
...
...
sprintf(cmd, "./a1.out > temp.txt");
system(cmd);
fp = fopen("temp.txt", "r");
...
...
}
In this example, it is not ensured that cmd executed completely after that the file is opened for reading. And, I want to ensure that. Any help?
You can use popen() to execute the command and read its output directly.
fp = popen("./a1.out", "r");
if (fp) {
...
r = pclose(fp);
if (r < 0) {
/*...command exited abnormally */
}
} else {
/*...fork or pipe error */
}
You can choose to write the data to a file if that is what is required.
I don't know about the os you are using but under Linux the manual says
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.
Moreover Posix says
The system() function shall not return until the child process has terminated.
So you are sure that the command is completed.

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.

How to capture process output in C?

Is there any analog of PHP's system in C?
man system says, that system return status of the command, but I need the output (like in PHP).
Of course, I can use pipes for this, but is there any standard way?
You can make use of popen and related function as:
// command to be run.
char *cmd = "date";
// open pipe stream.
FILE *fp = popen(cmd,"r");
int ch;
// error checking.
if(!fp) {
fprintf(stderr,"Error popen with %s\n",cmd);
exit(1);
}
// read from the process and print.
while((ch = fgetc(fp)) != EOF) {
putchar(ch);
}
// close the stream.
pclose(fp);
Ideone link
If you need the output of the command, you'd use popen() on Unix (with "r" to indicate that you want to read from the command).
FILE *fp = popen("some -convoluted command", "r");
...check for validity...
...read data from command...
pclose(fp);

Resources