errang
asked on
how do I redirect the stdout and stderr from one file into another?
Hey, I don't have a lot of time to get this done... I'm trying to get the stderr from one file into another, this is what I have so far:
This program works for redirecting stdout from a file into another... but fails for stdin... could you please help me out?
Thanks in advance!!!
This program works for redirecting stdout from a file into another... but fails for stdin... could you please help me out?
Thanks in advance!!!
#include "sh.h"
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
char *which1(char *file);
int main(int argc, char **argv){
pid_t pid, pid1;
int ex, status;
int fid = 0;
int num = 0;
int num1 = 0;
char input[80];
char *temp, *temp1;
char *path, *cwd;
char name[1000][80];
cwd = getenv("PWD");
printf("%s\n", cwd);
printf(">>");
fgets(input, 80, stdin);
temp = strtok(input, " ");
while(temp!=NULL){
strcpy(name[num], temp);
temp = strtok(NULL, " ");
num++;
}
//temp1 = strtok(name[0], "\n");
//printf("%s\n", temp1);
pid = fork();
if(pid < 0){
printf("error!");
exit(1);
}
else if(pid == 0){
path = which1(cwd);
argv[0] = strtok(name[0], "\n");
argv[1] = NULL;
//printf("%s\n", argv[0]);
/*temp1 = strtok(name[2], "\n");
fid = open(temp1, O_WRONLY | O_CREAT | O_APPEND, 0666);
close(1);
dup(fid);
close(fid);*/
ex = execv(path, argv);
}
else {
fid = open("/dev/tty",O_WRONLY);
close(1);
ex = execv(path, argv);
dup(fid);
close(fid);
wait(NULL);
}
return(0);
}
//which1 takes the name of the file you are looking for as an argument.
//if it finds it, it appends that file to the directory it is in.
//if the file does not exist, it returns the default value, "Does not exist."
char *which1(char *file){
DIR *pdir;
struct pathelement *pathlist;
struct dirent *pfile;
char *return_file = "Does not exist.";
char *temp;
int str = 0;
pathlist = get_path();
pdir = opendir(pathlist->element);
//printf("in here\n");
while(pathlist!=NULL){
pfile = readdir(pdir);
while((pfile = readdir(pdir)) != NULL){
str = strcmp(pfile->d_name, file);
if(str == 0){
return_file = strcat(pathlist->element, "/");
return_file = strcat(return_file, pfile->d_name);
return return_file;
}
}
pathlist = pathlist->next;
pdir = opendir(pathlist->element);
}
return return_file;
}
ASKER
This version redirects the stdout of a command into a file... please help me with the stderr...
(sry bout the repetitiveness... i really really need help... this is due in < 12 hours...)
(sry bout the repetitiveness... i really really need help... this is due in < 12 hours...)
#include "sh.h"
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
char *which1(char *file);
int main(int argc, char **argv){
pid_t pid, pid1;
int ex, status;
int fid = 0;
int num = 0;
int num1 = 0;
char input[80];
char *temp, *temp1;
char *path;
char name[1000][80];
printf(">>");
fgets(input, 80, stdin);
temp = strtok(input, " ");
while(temp!=NULL){
strcpy(name[num], temp);
temp = strtok(NULL, " ");
num++;
}
pid = fork();
if(pid < 0){
printf("error!");
exit(1);
}
else if(pid == 0){
path = which1(name[0]);
argv[1] = strtok(name[1], "\n");
argv[2] = NULL;
temp1 = strtok(name[3], "\n");
fid = open(temp1, O_WRONLY | O_CREAT | O_TRUNC, 0666);
close(1);
dup(fid);
close(fid);
ex = execv(path, argv);
}
else {
fid = open("/dev/tty",O_WRONLY);
close(1);
ex = execv(path, argv);
dup(fid);
close(fid);
wait(NULL);
}
return(0);
}
//which1 takes the name of the file you are looking for as an argument.
//if it finds it, it appends that file to the directory it is in.
//if the file does not exist, it returns the default value, "Does not exist."
char *which1(char *file){
DIR *pdir;
struct pathelement *pathlist;
struct dirent *pfile;
char *return_file = "Does not exist.";
char *temp;
int str = 0;
pathlist = get_path();
pdir = opendir(pathlist->element);
//printf("in here\n");
while(pathlist!=NULL){
pfile = readdir(pdir);
while((pfile = readdir(pdir)) != NULL){
str = strcmp(pfile->d_name, file);
if(str == 0){
return_file = strcat(pathlist->element, "/");
return_file = strcat(return_file, pfile->d_name);
return return_file;
}
}
pathlist = pathlist->next;
pdir = opendir(pathlist->element);
}
return return_file;
}
what is sh.h?
what is get_path?
what is get_path?
ASKER
sh.h and get_path are simply functions that are used for which1, they just get all the available directories.
ASKER
Here they are.
get_path
#include "get_path.h"
struct pathelement *get_path()
{
/* path is a copy of the PATH and p is a temp pointer */
char *path, *p;
/* tmp is a temp point used to create a linked list and pathlist is a
pointer to the head of the list */
struct pathelement *tmp, *pathlist = NULL;
p = getenv("PATH");/* get a pointer to the PATH env var.
make a copy of it, since strtok modifies the
string that it is working with... */
path = malloc((strlen(p)+1)*sizeo f(char));/ * use malloc(3C) this time */
strncpy(path, p, strlen(p));
path[strlen(p)] = '\0';
p = strtok(path, ":"); /* PATH is : delimited */
do/* loop through the PATH */
{/* to build a linked list of dirs */
if ( !pathlist )/* create head of list */
{
tmp = calloc(1, sizeof(struct pathelement));
pathlist = tmp;
}
else/* add on next element */
{
tmp->next = calloc(1, sizeof(struct pathelement));
tmp = tmp->next;
}
tmp->element = p;
tmp->next = NULL;
} while ( p = strtok(NULL, ":") );
return pathlist;
} /* end get_path() */
sh.h
#include "get_path.h"
int pid;
int sh( int argc, char **argv, char **envp);
int which(char *command, struct pathelement *pathlist);
int where(char *command, struct pathelement *pathlist);
void list ( char *dir );
void printenv(char **envp);
#define PROMPTMAX 32
#define MAXARGS 10
sh.c
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include "sh.h"
int sh( int argc, char **argv, char **envp )
{
char *prompt = calloc(PROMPTMAX, sizeof(char));
char *commandline = calloc(MAX_CANON, sizeof(char));
char *command, *arg, *commandpath, *p, *pwd, *owd;
char **args = calloc(MAXARGS, sizeof(char*));
int uid, i, status, argsct, go = 1;
struct passwd *password_entry;
char *homedir;
struct pathelement *pathlist;
uid = getuid();
password_entry = getpwuid(uid); /* get passwd info */
homedir = password_entry->pw_dir;/* Home directory to start
out with*/
if ( (pwd = getcwd(NULL, PATH_MAX+1)) == NULL )
{
perror("getcwd");
exit(2);
}
owd = calloc(strlen(pwd) + 1, sizeof(char));
memcpy(owd, pwd, strlen(pwd));
prompt[0] = ' '; prompt[1] = '\0';
/* Put PATH into a linked list */
pathlist = get_path();
while ( go )
{
/* print your prompt */
/* get command line and process */
/* check for each built in command and implement */
/* else program to exec */
{
/* find it */
/* do fork(), execve() and waitpid() */
//else
//fprintf(stderr, "%s: Command not found.\n", args[0]);
}
}
return 0;
} /* sh() */
int which(char *command, struct pathelement *pathlist )
{
/* loop through pathlist until finding command and return it. Return
NULL when not found. */
int i = 0;
char *sep;
char *s = "/";
sep = strtok(pathlist->element, s);
while(sep!=NULL){
if(strcmp(sep, command)==0){
i = 1;
break;
}
sep = strtok(NULL, s);
}
return i;
} /* which() */
int where(char *command, struct pathelement *pathlist )
{
/* similarly loop through finding all locations of command */
} /* where() */
void list ( char *dir )
{
/* see man page for opendir() and readdir() and print out filenames for
the directory passed */
} /* list() */
get_path
#include "get_path.h"
struct pathelement *get_path()
{
/* path is a copy of the PATH and p is a temp pointer */
char *path, *p;
/* tmp is a temp point used to create a linked list and pathlist is a
pointer to the head of the list */
struct pathelement *tmp, *pathlist = NULL;
p = getenv("PATH");/* get a pointer to the PATH env var.
make a copy of it, since strtok modifies the
string that it is working with... */
path = malloc((strlen(p)+1)*sizeo
strncpy(path, p, strlen(p));
path[strlen(p)] = '\0';
p = strtok(path, ":"); /* PATH is : delimited */
do/* loop through the PATH */
{/* to build a linked list of dirs */
if ( !pathlist )/* create head of list */
{
tmp = calloc(1, sizeof(struct pathelement));
pathlist = tmp;
}
else/* add on next element */
{
tmp->next = calloc(1, sizeof(struct pathelement));
tmp = tmp->next;
}
tmp->element = p;
tmp->next = NULL;
} while ( p = strtok(NULL, ":") );
return pathlist;
} /* end get_path() */
sh.h
#include "get_path.h"
int pid;
int sh( int argc, char **argv, char **envp);
int which(char *command, struct pathelement *pathlist);
int where(char *command, struct pathelement *pathlist);
void list ( char *dir );
void printenv(char **envp);
#define PROMPTMAX 32
#define MAXARGS 10
sh.c
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include "sh.h"
int sh( int argc, char **argv, char **envp )
{
char *prompt = calloc(PROMPTMAX, sizeof(char));
char *commandline = calloc(MAX_CANON, sizeof(char));
char *command, *arg, *commandpath, *p, *pwd, *owd;
char **args = calloc(MAXARGS, sizeof(char*));
int uid, i, status, argsct, go = 1;
struct passwd *password_entry;
char *homedir;
struct pathelement *pathlist;
uid = getuid();
password_entry = getpwuid(uid); /* get passwd info */
homedir = password_entry->pw_dir;/* Home directory to start
out with*/
if ( (pwd = getcwd(NULL, PATH_MAX+1)) == NULL )
{
perror("getcwd");
exit(2);
}
owd = calloc(strlen(pwd) + 1, sizeof(char));
memcpy(owd, pwd, strlen(pwd));
prompt[0] = ' '; prompt[1] = '\0';
/* Put PATH into a linked list */
pathlist = get_path();
while ( go )
{
/* print your prompt */
/* get command line and process */
/* check for each built in command and implement */
/* else program to exec */
{
/* find it */
/* do fork(), execve() and waitpid() */
//else
//fprintf(stderr, "%s: Command not found.\n", args[0]);
}
}
return 0;
} /* sh() */
int which(char *command, struct pathelement *pathlist )
{
/* loop through pathlist until finding command and return it. Return
NULL when not found. */
int i = 0;
char *sep;
char *s = "/";
sep = strtok(pathlist->element, s);
while(sep!=NULL){
if(strcmp(sep, command)==0){
i = 1;
break;
}
sep = strtok(NULL, s);
}
return i;
} /* which() */
int where(char *command, struct pathelement *pathlist )
{
/* similarly loop through finding all locations of command */
} /* where() */
void list ( char *dir )
{
/* see man page for opendir() and readdir() and print out filenames for
the directory passed */
} /* list() */
ASKER
Redirecting stderr from a regular command is easy right? all we need to do is:
temp1 = strtok(name[3], "\n");
fid = open(temp1, O_WRONLY | O_CREAT | O_TRUNC, 0666);
close(2);
dup(fid);
close(fid);
ex = execv(path, argv);
Is redirecting stderr from the output of a file really that much harder? I can't seem to find anything good on it on google...
temp1 = strtok(name[3], "\n");
fid = open(temp1, O_WRONLY | O_CREAT | O_TRUNC, 0666);
close(2);
dup(fid);
close(fid);
ex = execv(path, argv);
Is redirecting stderr from the output of a file really that much harder? I can't seem to find anything good on it on google...
//rather than ask what get_path.h is and trying to figure out what your code is doing, I'll just give an example of piping stderr into stdin
int p2[2];
pipe(p2);
pid = fork();
if(pid < 0){
printf("error!");
exit(1);
}
else if(pid == 0){
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin t STDERR qq'err\\n';",0};
dup2(p2[1],2);
close(p2[0]);
ex = execv(path,argv);
}
else {
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
dup2(p2[0],0);
close(p2[1]);
ex = execv(path, argv);
wait(NULL);
}
int p2[2];
pipe(p2);
pid = fork();
if(pid < 0){
printf("error!");
exit(1);
}
else if(pid == 0){
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin
dup2(p2[1],2);
close(p2[0]);
ex = execv(path,argv);
}
else {
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
dup2(p2[0],0);
close(p2[1]);
ex = execv(path, argv);
wait(NULL);
}
ASKER
wait... what are the arguments in:
char *argv[]={"perl","-e","prin t STDERR qq'err\\n';",0};
and
char *argv[]={"cat","-ne",0};?
char *argv[]={"perl","-e","prin
and
char *argv[]={"cat","-ne",0};?
ASKER
hm... I'm guessing u'r returning stderr to the console with these?
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
dup2(p2[0],0);
close(p2[1]);
ex = execv(path, argv);
wait(NULL);
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
dup2(p2[0],0);
close(p2[1]);
ex = execv(path, argv);
wait(NULL);
ASKER
Hm... we need to add the open and close statements to this for it to work completely... right?
else if(pid == 0){
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin t STDERR qq'err\\n';",0};
p2[0] = open(filename, O_CREAT | O_TRUNC, 0666);
close(2);
dup2(p2[1],2);
close(p2[0]);
ex = execv(path,argv);
}
Yes?
else if(pid == 0){
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin
p2[0] = open(filename, O_CREAT | O_TRUNC, 0666);
close(2);
dup2(p2[1],2);
close(p2[0]);
ex = execv(path,argv);
}
Yes?
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin t STDERR qq'err\\n';",0};
execv(path,argv);
just runs a simple program that outputs to stderr
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
execv(path, argv);
just runs a simple program that inputs from stdin
for the purpose of demonstrating how two programs can be connected together
you can replace them with whatever programs you had wanted to run
char *argv[]={"perl","-e","prin
execv(path,argv);
just runs a simple program that outputs to stderr
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
execv(path, argv);
just runs a simple program that inputs from stdin
for the purpose of demonstrating how two programs can be connected together
you can replace them with whatever programs you had wanted to run
what do you want to do with the files?
what do you want to do with filename?
ASKER
but wait... does that example pipe from one file to another?
I'm just wondering because the path variable is "/usr/bin/perl"
int p2[2];
pipe(p2);
pid = fork();
if(pid < 0){
printf("error!");
exit(1);
}
else if(pid == 0){
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin t STDERR qq'err\\n';",0};
dup2(p2[1],2);
close(p2[0]);
ex = execv(path,argv);
}
else {
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
dup2(p2[0],0);
close(p2[1]);
ex = execv(path, argv);
wait(NULL);
}
I'm just wondering because the path variable is "/usr/bin/perl"
int p2[2];
pipe(p2);
pid = fork();
if(pid < 0){
printf("error!");
exit(1);
}
else if(pid == 0){
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin
dup2(p2[1],2);
close(p2[0]);
ex = execv(path,argv);
}
else {
char *path = "/bin/cat";
char *argv[]={"cat","-ne",0};
dup2(p2[0],0);
close(p2[1]);
ex = execv(path, argv);
wait(NULL);
}
ASKER
filename is the file I want to output the error to.
ASKER
What I need to be able to do with the program is to redirect any .o file into a .txt file or something.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
hm... could you please explain these 2 variables?
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin t STDERR qq'err\\n'; print STDOUT qq'out\n';",0};
is perl the program that does that? or what?
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin
is perl the program that does that? or what?
ASKER
It's 6 am my time... so I'd better take a short nap before I pass out for 6 hours...
But Thanks in advance!!! =D
But Thanks in advance!!! =D
char *path = "/usr/bin/perl";
char *argv[]={"perl","-e","prin t STDERR qq'err\\n'; print STDOUT qq'out\n';",0};
execv(path,argv);
just runs a program that outputs to stderr and to stdout
you can replace it with whatever program you wanted to run from which you wanted to capture stderr or stdout.
char *argv[]={"perl","-e","prin
execv(path,argv);
just runs a program that outputs to stderr and to stdout
you can replace it with whatever program you wanted to run from which you wanted to capture stderr or stdout.
ASKER
that even applies to executable C code?
ASKER
Sweet, Thanks!
ASKER
This would work right?
char *path = current directory;
char *argv[]= name of executable;
char *path = current directory;
char *argv[]= name of executable;
int execv(const char *path, char *const argv[]);
path is the pathname of a file which is to be executed.
argv will be passed to the process where it will be read as argv in
int main(int argc, char **argv){
path is the pathname of a file which is to be executed.
argv will be passed to the process where it will be read as argv in
int main(int argc, char **argv){
ASKER
hm... am I doing something wrong here?
temp1 = strtok(name[2], "\n");
err_fid = open(name[0], O_WRONLY | O_CREAT | O_APPEND, 0666);
fid = open(temp1, O_WRONLY | O_CREAT | O_APPEND, 0666);
dup2(err_fid, 2);
dup2(fid, 1);
ex = execv(path, argv);
It doesn't seem to be working.. =(
temp1 = strtok(name[2], "\n");
err_fid = open(name[0], O_WRONLY | O_CREAT | O_APPEND, 0666);
fid = open(temp1, O_WRONLY | O_CREAT | O_APPEND, 0666);
dup2(err_fid, 2);
dup2(fid, 1);
ex = execv(path, argv);
It doesn't seem to be working.. =(
ASKER
/*temp1 = strtok(name[2], "\n");
fid = open(temp1, O_WRONLY | O_CREAT | O_APPEND, 0666);
close(1);
dup(fid);
close(fid);*/
I really need to get this done quick... =(
this thing's supposed to work for stuff like:
./test1 >& test.txt
I can't figure out how to run a non-system call with execv, I tried putting the path as the current directory, and the argument as ./test1, but it didn't work.
Please, I need help...