Im mid way through writting my own c shell and having trouble with my redirecting,

i use strtok to spilt the input into 2 parts, argv0 being command and argv1 being cmd

i have this for redirecting so far

if(strcmp(cmd,">")==0)
			{		
				strcpy(filename, command); 
				filein = open(filename, O_RDONLY);
				dup2(filein,0);
				close(filein);
				break;
			 }

			else if(strcmp(cmd,"<")==0)
			{   			
				strcpy(filename, command);
				fileout = open(filename, O_WRONLY);
				dup2(fileout,1);
				close(fileout);
				break;
			}

any help?

Recommended Answers

All 22 Replies

Im mid way through writting my own c shell and having trouble with my redirecting,

i use strtok to spilt the input into 2 parts, argv0 being command and argv1 being cmd

i have this for redirecting so far

if(strcmp(cmd,">")==0)
			{		
				strcpy(filename, command); 
				filein = open(filename, O_RDONLY);
				dup2(filein,0);
				close(filein);
				break;
			 }

			else if(strcmp(cmd,"<")==0)
			{   			
				strcpy(filename, command);
				fileout = open(filename, O_WRONLY);
				dup2(fileout,1);
				close(fileout);
				break;
			}

any help?

What's the question or what's the problem?

It not working properly and i cannot think why.
here the output i get when i do it

phil@shell ~/home/phil/Desktop $ new > ello.txt
argv0 = new
argv1 = >
argv2 = (null)
phil@shell ~/home/phil/Desktop $ argv0 = ello
argv1 = you
argv2 = (null)
phil@shell ~/home/phil/Desktop $ phil@shell ~/home/phil/Desktop $ phil@shell ~/home/phil/Desktop $

typing new > ello.txt (new is a file with ello you in and ello.txt is empty) it doesnt put the input of new to ello.txt

You'll have to show us where your parsing your input...

Also try this

new \> ello.txt

< and > are meta-chararters

Ok heres my whole program

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h> 

int main(int argc, char **argv)
{
	system("clear");
	int z =1;

    do
	{
		char dir[50];
		char *user;
	
		char *progname; 
   		char *parameters;

		int filein, fileout;
		char filename[50];

		char *cmd, *command, *cmd1, *cmd2 = 0;
		char buffer[50], *input;

		int childstatus = 1, status;
		int cmdlen;
		pid_t child;

		int ridline;

		int x = 0;

		user = (char *)getenv("USER");
   		getcwd(dir,50);
	
	
  		if( user == NULL )
   		{
			user == "Unknown";
   	 	}

		printf("%s@dmush ~%s $ ", user, dir);

		input = fgets(buffer, 50, stdin);

		

		ridline = strlen(input);		//Take out new line char
		if (input[ridline-1] == '\n') 
		{	
			input[ridline-1] = '\0';	
		}				

       	
		command = strtok(input, " ");
		cmd1 = command;
		printf("argv0 = %s\n", command);

    	while(1)
    	{

		if (strcmp(command, "exit") == 0)
		{
			printf("Good Bye\nTerminating shell..........\n");
			return 0;
		}

			
		else if(strcmp(command,"set") == 0)
		{
	    		int true;
	    	     //set environment variable
	    	 
	    	     setenv(command, cmd, true);
			perror("env");
	   			 
		}

			cmd = strtok(NULL, " ");
			printf("argv1 = %s\n",cmd);	

			cmd2 = strtok(NULL, " ");	
			printf("argv2 = %s\n",cmd2);
			
			if(cmd == NULL)
			{
				x = 1;
			}	

			while(!strcmp(command,"cd")) 
			{
				if(x == 1)
				{
					chdir(getenv("HOME"));
					break;
				}
				else
				{
					chdir(cmd);
					perror("dir");
					break;
				}			
			}
   
			childstatus = fork();
			progname = cmd1;
    			parameters = cmd;

			if (childstatus != 0) 
			{ //if parent process is running
				wait(&status);
			}
			else
			{
    				int i;	
	
     			for (i=0; i<3; i++)
     			{
         				execlp(progname,progname,parameters,(char *)0);		
     			}

			if(strcmp(cmd,">")==0)
			{		
				strcpy(filename, command); 
				filein = open(filename, O_RDONLY);
				dup2(filein,0);
				close(filein);
				break;
			 }

			else if(strcmp(cmd,"<")==0)
			{   			
				strcpy(filename, command);
				fileout = open(filename, O_WRONLY);
				dup2(fileout,1);
				close(fileout);
				break;
			}
			}
			
			break;
	

   		}
 
	}while (z == 1);

    return 0;
	
}

Line 41

user == "Unknown";

or should this be

user = "Unknown";

Line 41

user == "Unknown";

or should this be

user = "Unknown";

No its right, il explain what it does, if the getenv "USER" does not work, i.e it cannot find the user for whatever reason, it will make user Unknown,
so it should be
user == "Unknown";

Line 73

you name an int variable true...Probably not a good idea.

No its right, il explain what it does, if the getenv "USER" does not work, i.e it cannot find the user for whatever reason, it will make user Unknown,
so it should be
user == "Unknown";

== comparison
= sets equal

that's funny, I changed it and now its working...

Here's the results of running your test "new > ello.txt"

user@dmush ~/home/user/share/test/data $ new > ello.txt
argv0 = new
argv1 = >
argv2 = ello.txt
user@dmush ~/home/user/share/test/data $

OK sorry yes it was a single = was me getting confused.

you say its working fine?
with the test new > ello.txt, did you create a file named new,and the input of that file was copied to ello.txt??
as i believe that what redirect is i.e < or >

also about the true on 73, i dont understand?

Let me jump in. One immediate problem is that redirections seem to be reversed. On ">" your code prepares for reading, and on "<" for writing.

OK sorry yes it was a single = was me getting confused.

you say its working fine?
with the test new > ello.txt, did you create a file named new,and the input of that file was copied to ello.txt??
as i believe that what redirect is i.e < or >

also about the true on 73, i dont understand?

true is a value used in the bool variable type which is included in stdbool.h

with the test new > ello.txt, did you create a file named new,and the input of that file was copied to ello.txt??

that wasn't your original problem...remember this..Now that this parses correctly you should be able to straighten out the rest

phil@shell ~/home/phil/Desktop $ new > ello.txt
argv0 = new
argv1 = >
argv2 = (null)

that wasn't your original problem...remember this..

Let me jump in. One immediate problem is that redirections seem to be reversed. On ">" your code prepares for reading, and on "<" for writing.

Yup that would be a problem nezachem

Let me jump in. One immediate problem is that redirections seem to be reversed. On ">" your code prepares for reading, and on "<" for writing.

swopped. still not getting anything written to ello.txt .
Trying a number of different ways at the moment.
Iv got it opening the 2nd file like so.

if(strcmp(cmd,">")==0)
			{		
				strcpy(filename, command); 
                                strcpy(filename2, cmd2);
				filein = open(filename, O_WRONLY);
                                fileout = open(filename2, O_WRONLY);
				dup2(filein,0);
				close(filein);
                                close(fileout);
				break;
			 }

is there a way i can say open filein to read it and copy it, then just put that into fileout, using dup maybe? iv tried dup2(filein, fileout);
to no affect

swopped. still not getting anything written to ello.txt .
Trying a number of different ways at the moment.
Iv got it opening the 2nd file like so.

if(strcmp(cmd,">")==0)
			{		
				strcpy(filename, command); 
                                strcpy(filename2, cmd2);
				filein = open(filename, O_WRONLY);
                                fileout = open(filename2, O_WRONLY);
				dup2(filein,0);
				close(filein);
                                close(fileout);
				break;
			 }

is there a way i can say open filein to read it and copy it, then just put that into fileout, using dup maybe? iv tried dup2(filein, fileout);
to no affect

Just curious, where are you writing the data to the file..

Just curious, where are you writing the data to the file..

that my point, i dont now how to!
why i said i tried dup2(filein, fileout);

is there a function that will simply write one file to another?

Here's an example of using dup2

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char**argv)
{
	int fd = open("myfile", O_WRONLY|O_CREAT, 0666);
	if (fd < 0)
	{
		fputs("could not open myfile!\n", stderr);
		exit(EXIT_FAILURE);
	}

	dup2(fd, 1);

	fputs("Hello, World!\n", stdout);/*write to myfile*/

	close(fd);
	exit(EXIT_SUCCESS);
}

Here's one reading a file

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char**argv)
{
	char ch[100];
	int fd = open("myfile", O_RDONLY, 0666);
	if (fd < 0)
	{
		fputs("could not open myfile!\n", stderr);
		perror("open");
		exit(EXIT_FAILURE);
	}

	dup2(fd, 0);

	fgets(ch, 100, stdin);/*read from myfile*/
	fprintf(stdout, "ans->%s\n", ch);
	
	fgets(ch, 100, stdin);/*read from myfile*/
	fprintf(stdout, "ans->%s\n", ch);

	close(fd);
	exit(EXIT_SUCCESS);
}

Sorry to be a pain but i dont think you understand what i want to do, or maybe im just reading it wrong, anyway for sakes,

when i type new.txt > ello.txt
i want to copy the contents of new.txt into ello.txt if it already exists, or if not create it and copy the contents of new.txt into it.


Now from the dup2 man page it says,
int dup2(int oldfd, int newfd);
dup2() makes newfd be the copy of oldfd, closing newfd first if necessary.

so from that i came up with this code: (just for > atm)

if(strcmp(cmd,">")==0)
			{   			
                                char filename[50];
                                char filename2[50];	
				strcpy(filename, command);
				strcpy(filename2, cmd2);
                                filein = open(filename, O_RDONLY); //reads in the first file name and opens it for reading only
				fileout = open(filename2, O_WRONLY|O_CREAT, 0666); //reads in the 2nd file for writting/creating
				dup2(filein, fileout);	//copies the content of filein into fileout
				close(fileout);
				close(filein);
				break;
			}

now i dont understand why this doesnt work , can someone point out if iv done it wrong or why it doesnt work etc...

Sorry to be a pain but i dont think you understand what i want to do, or maybe im just reading it wrong, anyway for sakes,

when i type new.txt > ello.txt
i want to copy the contents of new.txt into ello.txt if it already exists, or if not create it and copy the contents of new.txt into it.


Now from the dup2 man page it says,
int dup2(int oldfd, int newfd);
dup2() makes newfd be the copy of oldfd, closing newfd first if necessary.

so from that i came up with this code: (just for > atm)

if(strcmp(cmd,">")==0)
			{   			
                                char filename[50];
                                char filename2[50];	
				strcpy(filename, command);
				strcpy(filename2, cmd2);
                                filein = open(filename, O_RDONLY); //reads in the first file name and opens it for reading only
				fileout = open(filename2, O_WRONLY|O_CREAT, 0666); //reads in the 2nd file for writting/creating
				dup2(filein, fileout);	//copies the content of filein into fileout
				close(fileout);
				close(filein);
				break;
			}

now i dont understand why this doesnt work , can someone point out if iv done it wrong or why it doesnt work etc...

You still have to preform the I/O actions...Copy my examples and run them

dup2(filein, fileout); //copies the content of filein into fileout

The above code only makes a duplicate of the file descriptor...it does not copy the file contents..

Right from my man dup2

dup, dup2 - duplicate an open file descriptor

While i understand your code and have run them, they dont actually deal with my situation.

while i can easily replace "myfile" with any input file by justsing using the strcpy function like in my examples.

there is no way to use the code with my text

fgets(ch, 100, stdin);/*read from myfile*/

fprintf(stdout, "ans->%s\n", ch); 

OR 

fputs("Hello, World!\n", stdout);/*write to myfile*/

well not that i can see anyway, if i could use something like

fputs([thefilehere], stdout);/*write to myfile*/

then i believe that would work. but i cant see a way i can do this

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.