LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Closed Thread
  Search this Thread
Old 08-31-2003, 10:23 PM   #1
Tozilla
LQ Newbie
 
Registered: Aug 2003
Posts: 4

Rep: Reputation: 0
UNIX shell programming


I'm trying to write a problem in C which can display a prompt,e.g My_shell$ and accept a command entered by the user by using fgets. Also, it needs to execute the command by invoking fork() and execvp() system call. Then, if user type "logout", the shell should exit.

My problem is that I don't know how to combine fgets, fork() and execvp() together inside the program.
Can anyone please show me some examples or suggestions?
Thank you
 
Old 08-31-2003, 10:40 PM   #2
SaTaN
Member
 
Registered: Aug 2003
Location: Suprisingly in Heaven
Posts: 223

Rep: Reputation: 33
In a while loop
{
First accept the input using fgets .....
Use strtok to split the fgets into arguments for use in execvp()
Check if command is "logout" and exit from the program .
Then fork to create a child .
In the child process , use exec to run the command requested by the user
In the parent , wait until the child has exited n then print
"Command successful or something "
}


I suppose this should do it for you unless u want to include background , redirection and other stuff....

If you still aren't able to get it I'll post the program.

Welcome to LQ.

Last edited by SaTaN; 08-31-2003 at 10:44 PM.
 
Old 09-01-2003, 03:32 AM   #3
vanquisher
Member
 
Registered: Aug 2003
Location: Hyderabad, India
Posts: 126

Rep: Reputation: 15
hey, i wrote this program just a few weeks ago for my OS course. it is online at http://gdit.iiit.net/~vamsee_k/myshell.c
hope it helps you out. it supports redirection but doesn't run a process in the background( the `&' thing ). Hope it helps you out...
 
Old 09-01-2003, 11:09 AM   #4
Tozilla
LQ Newbie
 
Registered: Aug 2003
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Originally posted by SaTaN
In a while loop
{
First accept the input using fgets .....
Use strtok to split the fgets into arguments for use in execvp()
Check if command is "logout" and exit from the program .
Then fork to create a child .
In the child process , use exec to run the command requested by the user
In the parent , wait until the child has exited n then print
"Command successful or something "
}


I suppose this should do it for you unless u want to include background , redirection and other stuff....

If you still aren't able to get it I'll post the program.

Welcome to LQ.
Thank you for replying me...I forgot something that I also need to take care of the background like '&' in my program.

I've already startd a little bit. But I did differently from what you wrote. In my program , I used functions and still don't know how to implement fgets() in the UNIX environment. Can you take a look at it and give me some suggestions?

Thank you

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main();
void parent(int pid);
void child();

int main()
{
	int ret;
	if( (ret=fork()) > 0 )
		parent(ret);
	else if ( ret == 0 )
		child();
	else 
		perror("fork() failed");
	exit(0);
}

void parent(int pid)
{
int child_ExitVal;

/*The parent only invokes the wait() if the command is a foreground command,** i.e. there is no '&' at the end of the line*/
	if (wait(&child_ExitVal) < 0
	{	perror("wait");
		exit(1);
	}


}

void child()
{
	char *argv[100]; 
/*this part should use strtok.  But I read it from the Unix manual, I'm still unable to manipulate the command typed in so that it is usable by execvp.*/

	argv[0] = "ls";
	argv[1] = "-l";
	argv[2] = "/";
	argv[3] = NULL;
	execvp(argv[0], argv);
/* If the program arrives here, an error must have occurred otherwise a different program image would be active.*/
	perror("execvp");
	exit(1); 
}


To vanquisher:

I found little bit hard to follow your program. Can you explain your program to me please? Also, unforunately, I need to run a process in the background (the '&' thing). Can you tell me how to implement into my above code.
Thank you
 
Old 09-01-2003, 11:12 AM   #5
SaTaN
Member
 
Registered: Aug 2003
Location: Suprisingly in Heaven
Posts: 223

Rep: Reputation: 33
You are going on the right track .

If ever you need help with this , post a message .....

I'll be there to help you.

P.S :- Do you need help with strtok ??

Last edited by SaTaN; 09-01-2003 at 11:15 AM.
 
Old 09-01-2003, 11:21 AM   #6
Tozilla
LQ Newbie
 
Registered: Aug 2003
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Originally posted by SaTaN
You are going on the right track .

If ever you need help with this , post a message .....

I'll be there to help you.
I'm still reading a UNIX tutorial how to use fgets() in the UNIX. I'm confused how to use it. Because I need to accept a command entered by user using fgets(). Should I use printf() to prompt user to enter a command and invoke the fork() and execvp() in the main function? can you show me a useful example for it?

thanks again
 
Old 09-01-2003, 11:23 AM   #7
Tozilla
LQ Newbie
 
Registered: Aug 2003
Posts: 4

Original Poster
Rep: Reputation: 0
sorry..I clicked it wrong.

Quote:
Originally posted by Tozilla
I'm still reading a UNIX tutorial how to use fgets() in the UNIX. I'm confused how to use it. Because I need to accept a command entered by user using fgets(). Should I use printf() to prompt user to enter a command and invoke the fork() and execvp() in the main function? can you show me a useful example for it?

P.S I'm still reading about that strtok command. Maybe, let me have more understanding of it. If I still don't undertand how to implement it, then I'll post the message to ask you for help =)

thanks again

Last edited by Tozilla; 09-01-2003 at 11:25 AM.
 
Old 09-01-2003, 11:32 AM   #8
SaTaN
Member
 
Registered: Aug 2003
Location: Suprisingly in Heaven
Posts: 223

Rep: Reputation: 33
Yeah you can use printf to print the prompt .....
After that you can use either "scanf or fgets"
The problem with scanf is that the default delimiter is " " and
so for an input of "ls -l -a --color" only "ls" will be stored in the var
So u need to use

scanf("%[^\n]",string);

Here we have are going to accept characters until a "\n" is encountered
Check man scanf for more details

In case of fgets the syntax is as follows
fgets(buf,MAX_SIZE,stdin);

where buf is a character array , MAX_SIZE is the maximum no. of characters you want to accept , stdin for reading from the stdin

You can use either of these for reading for your shell program....
 
Old 11-03-2005, 11:01 PM   #9
damocles
LQ Newbie
 
Registered: Nov 2005
Posts: 7

Rep: Reputation: 0
Hello
I am new to shell programmin and need to learn how to implement a simple unix shell. Any help(code sinppets,learning material etc) would be greatly appreciated.


thanks
 
Old 01-23-2006, 05:11 AM   #10
smiswera
LQ Newbie
 
Registered: Jan 2006
Posts: 1

Rep: Reputation: 0
hai,

I need myshell.c program, anybody please help me for this
 
Old 09-27-2006, 10:41 PM   #11
Francinoman
LQ Newbie
 
Registered: Sep 2006
Posts: 13

Rep: Reputation: 0
Hey guys,

Just so you know I am just about to start working on a very similar if not the same project.

I have done alot of research and looking on forums such as this one, and I see alot of the people creating a shell using C are students. I am no different :P This is a project that I have chosen to take up.

So I have read alot of the questions and answers on this subject and it all seems very helpful. So im already thankful to all the people that have helped me with out even knowing.

I have alot of idea's on how i will implement this, and I will work on this throughout the next month and keep everyone updated with anything I learn... or any problems I have

Last edited by Francinoman; 09-27-2006 at 10:45 PM.
 
Old 10-10-2006, 05:45 AM   #12
Francinoman
LQ Newbie
 
Registered: Sep 2006
Posts: 13

Rep: Reputation: 0
Hi guys,

Well here is my first update of code. Anyone can use it, and i would be very thankful for any experts to look at my code and suggests improvments. Of course its not finished yet, but it does have the basic functionality of:
ls with args
mkdir
rmdir
most basic shell commands except cd

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>	// Mainly for strtok

#define MAX_ARGS 2

char * PATH = "MyShell:$:";

char *path; //for the command path

typedef struct{
	char *cmd_path;	//path of command
	int argc;	//number of args for the cmd
	char *argv[MAX_ARGS];
	char cmd_suffix;
}commandStruct;

int runCommand(commandStruct * command1);

int main() {
	
	system("clear");
	int flag = 1;
	do {
		char buffer[256], *input;
		pid_t child;
		int childstatus, status;	//For Fork
	
		int x = 1;
		char *cmd;			//For strtok

		char *command;			//The command
		int cmdlen;

		commandStruct *command1 = (commandStruct*) malloc(sizeof(commandStruct));	
		command1->argc = 1;
		
		printf("\n%s", PATH);
		fflush(stdout);
		input = fgets(buffer, 256, stdin);

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

		//Get first token (the command) from input
       		cmd = strtok(input, " ");
		command = cmd;

		if (strcmp(command, "exit") == 0){
			flag = 0;
		}	

		command1->cmd_path = command;
		command1->argv[0] = command1->cmd_path;
	
		//Loop thru until whole command is tokenized
	        while (1)
	        {
	               	//Check command has no more than 2 args
			if (command1->argc > 3) {
				printf("\nError! Too many command arguements!\n");
				break;
			}

			//Extract next part of command
	                cmd = strtok(NULL, " ");

	                //Check that there is nothing else to extract
	                if (cmd == NULL)
	                {
	                        //printf("Command Tokenised");
				break;
			}

			command1->argv[command1->argc] = cmd;	//put arg into arg array
			command1->argc = command1->argc+1;	//increase count of args
		         	
	        }

		printf("Number of args: %d\n", command1->argc);
	
		childstatus = fork();
		if (childstatus != 0) { //if parent process is running
			wait(&status);
		} else {
			/* This area is child process */
			runCommand(command1);
			return(0);
		}	

	}while (flag == 1);

	return 0;
	exit(0);
}

int runCommand(commandStruct * command1) {
	
	printf("Command: %s\n", command1->cmd_path);
	execvp(command1->cmd_path, command1->argv);
	//printf("%s\n%s\n%s\n", command1->argv[0], command1->argv[1], command1->argv[2]);
	return 1;

}
 
Old 10-10-2006, 10:16 PM   #13
Francinoman
LQ Newbie
 
Registered: Sep 2006
Posts: 13

Rep: Reputation: 0
The first problem I had was actually getting commands that were input to run. But that was fixed however i think it might be a bit dodgy? What i actually did was the array of arguements for execvp() did not include the command as the first entry of the array. Once the first entry of this array was set to the command, and the arguments were set to the following array entries, the execute function seemed to work fine.

So the next step in my shell is to allow directory walking with the chdir() command... which i am having trouble with and researching. And also to add redirection of input and output.

If anyone has any tips on either of these, that would be great! :P

And this might be getting ahead of myself, but does anyone know much about changing the colour of the text output? Or perhaps making the output bold?

Last edited by Francinoman; 10-10-2006 at 10:17 PM.
 
Old 10-11-2006, 12:04 AM   #14
9GB
LQ Newbie
 
Registered: Oct 2006
Location: Pakistan
Posts: 5

Rep: Reputation: 0
Object not found

Quote:
Originally Posted by vanquisher
hey, i wrote this program just a few weeks ago for my OS course. it is online at link
hope it helps you out. it supports redirection but doesn't run a process in the background( the `&' thing ). Hope it helps you out...

The link is not working i suppose ...
Are you sure it was the correct link?
 
Old 10-11-2006, 11:45 PM   #15
Francinoman
LQ Newbie
 
Registered: Sep 2006
Posts: 13

Rep: Reputation: 0
yeah, i also tried to look at that and the link seemed broken.

So now i have fixed my code so the ability to walk thur directories is now complete.

Now my shell has most basic functions including exit and cd and generally acts as a shell (Even a function to change the shell prompt!!! hehe). From there I am going to add in re-direction... then see where i get from there.

is it strange that i am enjoying this project? (no im not a nerd! :P)
 
  


Closed Thread


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Unix Shell Programming If Statement ']['HeBroken Programming 2 12-06-2004 03:21 PM
[c] unix systems programming in MS VS C++? saiz66 Programming 2 10-07-2004 08:16 AM
c programming in unix dilberim82 Programming 7 04-21-2004 04:32 PM
UNIX (Linux, BSD, etc) Programming :: UNIX kuphryn Programming 8 04-04-2004 11:50 PM
is there actually a market for Unix programming? ShawnD Programming 37 05-16-2003 04:16 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration