Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
hi i have the following code
int main()
{
system("netsh interface ip show addresses");
}
and the output in the console to be written to a text file or else to a variable. pleaase help me out with this. THANKS in ADVANCE
if you use Linux, try this:
system("netsh interface ip show addresses > /path/to/file 2>&1 ");
void do_popen()
FILE *pf;
char command[200];
// Execute a process listing
sprintf(command, "netsh interface ip show addresses");
// Setup our pipe for reading and execute our command.
if(!(pf= popen(command, "r"))){
exit(EXIT_FAILURE);
}
if (pclose(pf) != 0)
fprintf(stderr," Error: Failed to close command stream \n");
return;
}
Here we are using popen which internally creates a process and run the command given to it. It returns an I/O stream from where the data can be fetched later. read and write system calls are being used while reading from the given command buffer or writing into the file back
To make it more generic, you can pass the command in the function parameter and return the data stored into the file in a dynamic array.
Although it is done nicely using popen but it creates a separate process where it run these commands as sh commands,and then put it in the file and before returning the file pointer, it closes all the process.
I would rather implement my own child process using fork() and then use exec and implement my own SIGCHILD handler to remove it from zombie and keep on processing other work in parallel instead of blocking the process
Hope the below code will help to solve your issue. Look at the man pages for the details of popen and pclose APIs.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *in;
char buff[512];
if(!(in = popen("netsh interface ip show addresses", "r"))){
return -1;
}
while(fgets(buff, sizeof(buff), in)!=NULL){
printf("%s", buff);
}
pclose(in);
return 0;
}
Related
I'm attempting to write an output to a bash fifo so I can pipe it into another program. However, as soon as I run it I get a segmentation fault. Any thoughts? (C amateur here)
(errorout in this case a global variable and is successfully called elsewhere)
void print_log(){
printf("about to creat file pointer");
FILE* image_fifo;
printf("open fifo");
image_fifo = fopen("image",O_WRONLY);
if(image_fifo == NULL){
printf("unable to open fifo");
}//end if
else{
printf("writing to fifo");
int j;
for(j=0;j<1024;j++){
fprintf(image_fifo,"%u",errorout[j]);
}//end for
}
fclose(image_fifo);
for now, reading it out using this: (isn't python great?)
with open("image","r") as f:
print(f.read())
I think the segmentation fault is caused by this:
image_fifo = fopen("image",O_WRONLY);
This is for calling Linux system style open() from sys/stat.h (or fcntl.h), where the second parameter is an int which indicates flags (and O_WRONLY is indeed defined to an int value in the header file). In C fopen() from stdio.h you do this with a char *, e.g. fopen("name", "w");.
To be sure next time include anything the program prints before ending. You might also want to look at valgrind output; it might give you some clues about what's gone wrong.
As for "bash style fifo", I am not sure what you're trying to do, but if you're just trying to write to a file, you're doing it almost correctly. If you're trying to make a pipeline (I've heard someone call them fifo's too, so might be the case), you should look at the libpipeline library and its usage.
I've got a utility that outputs a list of files required by a game. How can I run that utility within a C program and grab its output so I can act on it within the same program?
UPDATE: Good call on the lack of information. The utility spits out a series of strings, and this is supposed to be portable across Mac/Windows/Linux. Please note, I'm looking for a programmatic way to execute the utility and retain its output (which goes to stdout).
As others have pointed out, popen() is the most standard way. And since no answer provided an example using this method, here it goes:
#include <stdio.h>
#define BUFSIZE 128
int parse_output(void) {
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("OUTPUT: %s", buf);
}
if (pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
return 0;
}
Sample output:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
For simple problems in Unix-ish environments try popen().
From the man page:
The popen() function opens a process by creating a pipe, forking and invoking the shell.
If you use the read mode this is exactly what you asked for. I don't know if it is implemented in Windows.
For more complicated problems you want to look up inter-process communication.
popen is supported on Windows, see here:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
If you want it to be cross-platform, popen is the way to go.
Well, assuming you're on a command line in a windows environment, you can use pipes or command line redirects. For instance,
commandThatOutputs.exe > someFileToStoreResults.txt
or
commandThatOutputs.exe | yourProgramToProcessInput.exe
Within your program, you could use the C standard input functions to read the other programs output (scanf, etc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . You could also use the file example and use fscanf. This should also work in Unix/Linux.
This is a very generic question, you may want to include more details, like what type of output it is (just text, or a binary file?) and how you want to process it.
Edit: Hooray clarification!
Redirecting STDOUT looks to be troublesome, I've had to do it in .NET, and it gave me all sorts of headaches. It looks like the proper C way is to spawn a child process, get a file pointer, and all of a sudden my head hurts.
So heres a hack that uses temporary files. It's simple, but it should work. This will work well if speed isn't an issue (hitting the disk is slow), or if it's throw-away. If you're building an enterprise program, looking into the STDOUT redirection is probably best, using what other people recommended.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE * fptr; // file holder
char c; // char buffer
system("dir >> temp.txt"); // call dir and put it's contents in a temp using redirects.
fptr = fopen("temp.txt", "r"); // open said file for reading.
// oh, and check for fptr being NULL.
while(1){
c = fgetc(fptr);
if(c!= EOF)
printf("%c", c); // do what you need to.
else
break; // exit when you hit the end of the file.
}
fclose(fptr); // don't call this is fptr is NULL.
remove("temp.txt"); // clean up
getchar(); // stop so I can see if it worked.
}
Make sure to check your file permissions: right now this will simply throw the file in the same directory as an exe. You might want to look into using /tmp in nix, or C:\Users\username\Local Settings\Temp in Vista, or C:\Documents and Settings\username\Local Settings\Temp in 2K/XP. I think the /tmp will work in OSX, but I've never used one.
In Linux and OS X, popen() really is your best bet, as dmckee pointed out, since both OSs support that call. In Windows, this should help: http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN documentation says
If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. _popen works properly in a console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Windows SDK.
You can use system() as in:
system("ls song > song.txt");
where ls is the command name for listing the contents of the folder song and song is a folder in the current directory. Resulting file song.txt will be created in the current directory.
//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[262144];
string data;
string result;
int dist=0;
int size;
//TIME_START
while(!feof(pipe)) {
size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
data.resize(data.size()+size);
memcpy(&data[dist],buffer,size);
dist+=size;
}
//TIME_PRINT_
pclose(pipe);
return data;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a file that contains:
<Ip_Adress> <User_Id> <User_Name>
When a user wants to change his name he specifics a new one. That new name should replace the in the File. I can do it in two ways: by using C code or with a unix command. I don't have any idea about how to do it using unix but I will prefer that solution. I have tried do it by using C but I get a Segmentation error. I will paste the code. (In the function references the ip address of the user that will change his name)
void change_name(char* ip,char* new_name){
FILE *f1,*f2;
//Attending to one answer I have changed the var to array but the error persists
char buffer[30],ip_address[30],user_id[30],user_name[30];
f1 = fopen ( "data.txt", "r" );
f2 = fopen ( "temporal.txt", "w");
if (f1==NULL){
perror ("Error opening the file data.txt");
fclose(f1);
}
if (f2==NULL){
perror ("Error opening the file temporal.txt");
fclose(f2);
}
while (feof(f1)==0)
{
fscanf(f1,"%s %s %s",ip_address,user_id,user_name);
if(strcmp(ip,ip_address)==0){
fprintf(f2,"%s %s %s\n",ip_address,user_id,new_name);
}else{
fprintf(f2,"%s %s %s\n",ip_address,user_id,user_name);
}
}
fclose (f1);
fclose (f2);
remove(f1);
rename("temporar.txt","data.txt");
}
An example of data.txt would be:
100.100.1.31 af9a67fa8 Guest
200.200.1.31 a43fji462 Guest
so the problem would be change the specific Guest that matchs with the specific ip given
Example: User with 100.100.1.31 ip address wants to change his name to Superman so the data.txt file will resoult:
100.100.1.31 af9a67fa8 Superman
200.200.1.31 a43fji462 Guest
That command would work
sed -i 's/\(100.100.1.31 .\{9\} \)Guest/\1Superman/g' data.txt
The problem now is to pass it to C with execlp or another command like that.
Your segmentation fault comes from your char * that you use in fscanf.
If you malloc them (or declare them as arrays), it would work.
But, I think that the best way to do it is by using sed. Please, refer to other answers for commands that works
EDIT: You could use asprintf() to simply format your sed regex, and use system() or any derivate you want to call it (system() is the better, it allow you to exec shell commands without forking first).
As I told you in response to your comment, your code doesn't segfaults for me. You could just set ip_address to 16 (255.255.255.255 = 16 char) and user_id to 9, for a better memory usage.
EDIT2:
Here is your code that I modified to make it work. I added comments to let you know what and why I did it.
#include <stdlib.h>
#include <stdio.h>
void change_name(char* ip,char* new_name){
FILE *f1,*f2;
//Attending to one answer I have changed the var to array but the error persists
char ip_address[16],user_id[9],user_name[30]; //Better memory managment
f1 = fopen ( "data.txt", "r" );
if (f1==NULL){
perror ("Error opening data.txt file");
exit(EXIT_FAILURE); //If you can't open first file, exit. File isn't openned, so don't close it.
}
f2 = fopen ( "temporal.txt", "w");
if (f2==NULL){
perror ("Error opening temporal.txt file");
fclose(f1); //Close first file, because you openned it
exit(EXIT_FAILURE); //Then exit
}
while (fscanf(f1,"%s %s %s",ip_address,user_id,user_name)==3) //fscanf returns the number of args read. If not 3, there is a problem.
{ // Directly verify of fscanf avoids the last line double read problem
if(strcmp(ip,ip_address)==0){
fprintf(f2,"%s %s %s\n",ip_address,user_id,new_name);
}else{
fprintf(f2,"%s %s %s\n",ip_address,user_id,user_name);
}
}
remove((const char *)f1);
rename("temporal.txt","data.txt");
fclose(f1); //Close your files at end, so you will avoid problems when manipulating them
fclose(f2);
}
int main() // Simple test main
{
change_name("100.100.1.31", "Superman");
return (0);
}
Unix commandline, using SED:
sed -i 's/\(100.100.1.31 .\{9\} \)Guest/\1Superman/g' data.txt
That is a regular expression that specifies the IP Address any 9 characters for the UserID, and the Username.
Let's break down that expression:
s/ - Substitute Text
\( - Begin capturing the following text into Param #1
100.100.1.31 - The IP Address you want to match
.\{9\} - Any character (9 times) for the UserID
\) - End the capture to Param #1
Guest - Username you want to match
/ - End the "Search" part, Begin the "Replace" part
\1 - Put Param #1 (IP Address + UserID) here
Superman - Put the new username here
/g - Do this Search-Replace *Globally*
It gets replaced by the same IP Address and 9 characters, but with the username Superman instead of Guest.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to execute a shell script when loading a .php in a web-server, I've already been struggling with this for a while so I will ask for help.
What I've tried so far is to make a wrapper as explained in this post: Execute root commands via PHP
But I couldn't really get it to work making the wrapper execute a shell script, even when the script worked when being executed from the console with root privileges.
So the only solution I could found is to convert the shell code to a C code using "system ("") as using system(" ")
I don't really know if it's possible, what the shell script used to do is check the PID of the process running in the port 12321 and then kill it.
The shell script alone worked, so I am asking if anyone knows if it's possible to convert to C, here is the shell script I want to convert:
#!/bin/sh
pid=$(/bin/fuser -n tcp 12321 | /usr/bin/awk '{print $1}');
/bin/kill -9 $pid;
And here is the wrapper.c being used, that used to execute the code above called in my machine (testversion.sh), but I don't know why, isn't working.
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
setuid (0);
system ("/bin/bash /var/www/html/scrip/debugport/testversion.sh");
return 0;
}
As this doesn't seem to work, someone got a way of executing it all in the C code?
Try this. This code would only be able to kill a process owned by the same user unless run as root.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#define PORT_TO_LOOK_FOR "12321"
#define DO_NOT_KILL_BELOW 2 /* I am just putting 2 here, you can increase this */
int main(void) {
FILE *fp;
char buf[11] = {0};
pid_t pid;
/* Open the command for reading. */
fp = popen("lsof -t -i tcp:" PORT_TO_LOOK_FOR, "r");
if (fp == NULL) {
printf("Could not run lsof.\n");
exit(1);
}
else {
fgets(buf, sizeof(buf)-1, fp);
pclose(fp);
pid = (pid_t)atoi(buf);
if( pid < 1) {
printf("Either no one is listening on port "
PORT_TO_LOOK_FOR " or u don't have the "
"necessary permission.\n" );
exit(1);
}
else if( pid < DO_NOT_KILL_BELOW ) {
printf("The PID we got was not safe to kill.\n");
exit(1);
}
if( kill(pid, SIGKILL) != 0 ) {
perror("kill");
}
}
return 0;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
What is the difference between running an already compiled C program with a.out file_name_here and a.out < file_name_here?
I remember something about Linux pipelines, but I cannot remember how to make the a.out file accept a file using the < symbol.
Basically what I am asking is this: how does the C code look for a C program that:
file_name_here is a text file with "hello world" as content
terminal gets "a.out < file_name_here" in command line
terminal shows output: "hello world"
a.out file_name_here passes "file_name_here" as an argument.
a.out < file_name_here is processed by the shell and presents the contents of "file_name_here" to the program on its "stdin".
Note that when you type a.out < filename, the shell handles the I/O redirection. The program is run with its standard input coming from the named file instead of from the terminal. When you type a.out filename, the program must deal with opening the file, reading it (and preferably closing it too). Neither of these examples uses a pipe. You could write cat file1 file2 file3 | a.out which would use a pipe and supply the contents of the three files as the standard input to the program.
Many programs on Unix systems are filters. If they are given file names to process, those are read. If they are given no file names, then they read standard input instead. An example of such a program is grep; other examples include cat and sort.
The general solution, in outline, is:
extern void process_file(FILE *fp); // Where the real work is done
int main(int argc, char **argv)
{
int rc = EXIT_SUCCESS;
if (argc == 1)
process_file(stdin);
else
{
for (int i = 1; i < argc; i++)
{
FILE *fp = fopen(argv[i], "r");
if (fp == 0)
{
fprintf(stderr, "%s: failed to open file %s for reading\n",
argv[0], argv[i]);
rc = EXIT_FAILURE;
}
else
{
process_file(fp);
fclose(fp);
}
}
}
return rc;
}
This will process any command line arguments as files to be read, resorting to reading standard input if no files are specified on the command line. There are legions of extra tweaks you can make to this outline. You can easily add option processing with getopt() (or getopt_long() if you're using GNU), and you can treat a file name of - as standard input if you wish. You can exit on failure to open a file if you think that's appropriate (sometimes it is; sometimes it isn't — grep doesn't, for example). You can pass the file name to the process_file() function. You can have the process_file() function report success failure, and track whether everything worked, exiting with zero only if all the operations were successful.
Just realized the problem I had. The < symbol means that the shell replaces normal user input in C with the content of the file, so all the normal calls such as fgets and sscanf work on it.