Reputation: 103
I'm trying to solve a problem because I'm learning to use system calls in C. I used a Ubuntu 12.04 64bit.
I have this statement:
Implement a code that allows to redirect the standard out of the two commands deferred into a file (standard output) and all error output into another file (error file). The names of the files will be specificated using out parameter (for the name of standard out) and parameter -err (for the name of error file). Syntax: after2 [args...] --do [args...] --out --err
It's not specified in the statement but I think that I need to use pipes.
Also I can't use printf, scanf, getc... family functions.
And i have that code:
#include <syscall.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int cmd1 = system("sleep 5");
int cmd2 = write(1, "hello world", 11);
if((cmd1 != (0)))
{
write(1,"error in command 1",18);
}
if((cmd1==(0)))
{
write(1, "hello world", 11);
}
return EXIT_SUCCESS;
}
My question is, do you know some examples about similar questions? I look for some but I didn't find, also if you know other ways to help me I'm happy to accept.
I post the code that I've now without erase the last version, by this way all people can see the evolution.
#include <syscall.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
const char* cmd1 = system("sleep 5");
const char* cmd2 = write(1, "hello world", 11);
int out_fd = creat("out.txt",0644);
int err_fd = creat("err.txt",0644);
if(out_fd < 0){
write(2, "Can't open file out.txt", strlen("Can't open file out.txt"));
dup2(err_fd, 2);
write(2, "Can't open file out.txt \n", strlen("Can't open file out.txt \n"));
return -1;
}else if(err_fd < 0){
write(2, "Can't open file err.txt", strlen("Can't open file err.txt"));
dup2(err_fd, 2);
write(2, "Can't open file err.txt \n", strlen("Can't open file err.txt \n"));
return -1;
}
if((cmd1 !=(0)))
{
write(2, "There is an error on command1", strlen("There is an error on command1"));
dup2(err_fd, 2);
write(2, "Error on command1 \n", strlen("Error on command1 \n"));
return -1;
}else if((cmd1==(0)))
{
write(1, "success on command1", strlen("success on command1"));
dup2(out_fd, 1);
write(1, "success on command1 \n", strlen("success on command1 \n"));
write(1, "hello world", 11);
if((cmd2==(0)))
{
write(1, "hello world", strlen("hello world"));
dup2(out_fd, 1);
write(1, "hello world \n", strlen("hello world \n"));
}
if((cmd2 != (0)))
{
write(2, "There is an error on command2", strlen("There is an error on command2"));
dup2(err_fd, 2);
write(2, "Error on command2 \n", strlen("Error on command2 \n"));
}
}
return 0;
}
This time prints in the shell hello worldsuccess on command1There is an error on command2
and success on command1 and hello world in out.txt and There is an error on command2 in err.txt but I don't know why prints There is an error on command2 and in the same time prints hello world, any idea
Obviously I've some errors yet but I'm not sure what I need to do if anyone can help me I'll be happy!
Thanks.
Upvotes: 0
Views: 743
Reputation: 103
Well, finally I've got a code that seems that it works, I changed the command cmd2 = write(1, "hello world", 11);
for cmd2 = system("echo $HOME");
because I've troubles to write in a file a write function, changing this I achieve my objective fastly:
#include <syscall.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
const int cmd1 = system("sleep 5");
int out_fd = creat("out.txt",0644);
int err_fd = creat("err.txt",0644);
if(out_fd < 0){
//write(2, "Can't open file out.txt", strlen("Can't open file out.txt"));
dup2(err_fd, 2);
write(2, "Can't open file out.txt \n", strlen("Can't open file out.txt \n"));
return -1;
}else if(err_fd < 0){
//write(2, "Can't open file err.txt", strlen("Can't open file err.txt"));
dup2(err_fd, 2);
write(2, "Can't open file err.txt \n", strlen("Can't open file err.txt \n"));
return -1;
}
if((cmd1 !=(0)))
{
//write(2, "There is an error on command1", strlen("There is an error on command1"));
dup2(err_fd, 2);
write(2, "Error on command1 \n", strlen("Error on command1 \n"));
return -1;
}
if((cmd1==(0)))
{
//write(1, "success on command1", strlen("success on command1"));
dup2(out_fd, 1);
write(1, "success on command1 \n", strlen("success on command1 \n"));
const int cmd2 = system("echo $HOME");;
if(( cmd2==(0)))
{
//write(1, "success on command2", strlen("success on command2"));
dup2(out_fd, 1);
write(1, "success on command2 \n", strlen("success on command2 \n"));
}
else if(( cmd2 !=(0)))
{
//write(2, "There is an error on command2", strlen("There is an error on command2"));
dup2(err_fd, 2);
write(2, "Error on command2 \n", strlen("Error on command2 \n"));
}
}
return 0;
}
Only have a little problem, when I build an exe appears a warning who says: warning:implicit declaration of function 'creat'[-Wimplicit-function-declaration]
int out_fd = creat("out.txt",0644);
If anyone knows how to correct it please tell me. Thanks for all your help!
Upvotes: 0
Reputation: 95242
write(1, ...
writes to standard output. write(2,...
writes to standard error. So all you have to do is reopen those file descriptors so that they're going into the designated files. For example,
fd1 = open("outputfile", O_WRONLY); dup2(fd1, 1);
fd2 = open("errorfile", O_WRONLY); dup2(fd2, 2);
After that, any standard output will go into outputfile
and any error output will go to errorfile
.
But first, you have to parse the command-line options (found in argv
, which is the first argument to main
, whose length is given by the second argument to main
) to find the --out
and --err
options and get their values.
Upvotes: 2
Reputation: 1469
You can use dup2 to redirect STDIN and STDERR to any other file you have opened.
int out_fd = creat("out.txt",0644);
if(out_fd < 0){
printf("Could not open file for standard output\n");
}
write(STDOUT_FILENO, "This is printed on the standard output", strlen("This is printed on the standard output"));
dup2(out_fd, STDOUT_FILENO);
write(STDOUT_FILENO, "This goes into out.txt file \n", strlen("This goes into out.txt file \n"));
You can do it similarly for stderr.
Upvotes: 2