LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-27-2012, 07:54 AM   #1
alexantosh
LQ Newbie
 
Registered: Oct 2012
Posts: 13

Rep: Reputation: Disabled
Unhappy programming a linux shell using the c programming language


hi every one. well straight to the point. am trying to build a simple linux shell(command line) using the c programming line and cygwin on windows machine. the shell will implement a few easy linux commands like ,cd, ls, pwd, using child processes and fork() function i guess- but i couldnt even make the cursor appear yet on my shell so far!

any help or form of assistance provided is greatly appreciated in advance. reply ASAP
thanks.
 
Old 10-27-2012, 01:01 PM   #2
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060
How about and example (taken from Chapter 6, Stephen G. Kochan, Patrick H. Wood, Topics in C Programming, rev. ed., 1991):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <wait.h>
#include <sys/types.h>

void	main	(void)
{
	char	line [BUFSIZ];
	int	process;

	for ( ; ; ) {
		(void) fprintf (stderr, "cmd: ");
		if (gets (line) == (char *) NULL)
			exit (EXIT_FAILURE);
		/*	create new process	*/
		if ((process = fork ()) > 0)
			(void) wait ((int *) NULL);
		else if (process == 0) {	/* child	*/
			/*	execute program			*/
			(void) execlp (line, line, NULL);
			/*	some problem if exec returns	*/
			(void) fprintf (stderr, "can't execute %s\n", line);
			exit (errno);
		} else if (process == -1) {	/* can't create	*/
			(void) fprintf (stderr, "can't fork\n");
			exit (errno);
		}
	}
}
That'll get you started.

And a second example, also for Chapter 6 of the same work:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <wait.h>
#include <sys/types.h>
#include <sys/stat.h>

/*
 *	simple command interpreter
 *	supports < and > redirection and command line arguments
*/

int	breakup	(char *, char **);

void	main	(void)
{
	char	line [BUFSIZ], *args [15];
	int	process, nargs;

	process = 0;
	for ( ; ; ) {		/* loop forever			*/
		(void) fprintf (stderr, "cmd: ");
		if (gets (line) == (char *) NULL) {
			exit (EXIT_SUCCESS);
		}
		if ((process = fork ()) > 0)	/* parent	*/
			(void) wait ((int *) NULL);
		else if (process == 0) {	/* child	*/
			/*	parse command line		*/
			nargs = breakup (line, args);
			/*	make sure there's something	*/
			if (nargs == 0)
				exit (EXIT_SUCCESS);
			/*	execute program			*/
			(void) execvp (args [0], args);
			/*	some problem if execvp returns	*/
			(void) fprintf (stderr, "cannot execute %s\n", line);
			exit (errno);
		} else if (process == -1) {	/* can't create	*/
			(void) fprintf (stderr, "can't fork\n");
			exit (errno);
		}
	}
}

/*
 *	break up command line and return in "args"
 *	recognize < file and > file constructs and redirect
 *	standard input and output as appropriate
*/

int	breakup	(char *line, char *args [])
{
	char	*strptr = line, *file;
	int	nargs = 0;

	while ((args [nargs] = strtok (strptr, " \t")) != (char *) NULL) {
		strptr = (char *) NULL;
		/*	output redirection	*/
		if (args [nargs] [0] == '>') {
			if (args [nargs][1] != '\0')
				file = &args [nargs] [1];
			else {
				file = strtok (strptr, " \t");
				if (file == (char *) NULL) {
					(void) fprintf (stderr, "no file after >\n");
					return (0);
				}
			}
			(void) close (1);
			if (open (file, O_WRONLY | O_TRUNC | O_CREAT, 0666) == -1) {
				(void) fprintf (stderr, "can't open %s for output\n", file);
				return (0);
			}
			--nargs;
		/*	input redirection	*/
		} else if (args [nargs] [0] == '<') {
			if (args [nargs] [1] != '\0')
				file = &args [nargs] [1];
			else {
				file = strtok (strptr, " \t");
				if (file == (char *) NULL) {
					(void) fprintf (stderr, "no file after <\n");
					return (0);
				}
			}
			(void) close (0);
			if (open (file, O_RDONLY) == -1) {
				(void) fprintf (stderr, "can't open %s for input\n", file);
				return (0);
			}
			--nargs;
		}
		++nargs;
	}
	args [nargs] = (char *) NULL;
	return (nargs);
}
This one you can fiddle around with and implement pipes and other features (it already supports redirection (< and >).

You might want to look around for a newer edition of Topics; it's an excellent learning-by-example work.

Hope this helps some.
 
2 members found this post helpful.
Old 10-27-2012, 05:20 PM   #3
alexantosh
LQ Newbie
 
Registered: Oct 2012
Posts: 13

Original Poster
Rep: Reputation: Disabled
heey, i dont know who you are but i definitely know that you have gotten me going. Thanks a great deal!! now i guess i have no excuses!! let me get on with the fiddling and i will let you know as i proceed!
 
Old 10-28-2012, 07:59 AM   #4
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060
Yer welcome -- you might want to pick up a copy of that book: full of working, useful examples and well written. Amazon is a good place to look.

Best of luck with it.
 
Old 10-28-2012, 09:37 AM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,397
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
I think it is helpful to think of a shell as a way to expose kernel/system functionality to the end-user. Most of the things a typical shell does map directly, sometimes a bit indirectly, to core system functions, such as launching process, opening/reading/writing files & devices, setting process state like current working directory & the shell's environment, etc. On top of all of that is the built-in programming/scripting capability, which isn't completely necessary, but is a convenience.
I suggest that you use readline() from libreadline as the basis for your commandline processing.
--- rod.
 
Old 10-28-2012, 01:36 PM   #6
alexantosh
LQ Newbie
 
Registered: Oct 2012
Posts: 13

Original Poster
Rep: Reputation: Disabled
i guess i have to buy it from amazon. tried looking out for pdfs. no luck so far. so, to amazon i go!
 
Old 10-29-2012, 06:07 PM   #7
alexantosh
LQ Newbie
 
Registered: Oct 2012
Posts: 13

Original Poster
Rep: Reputation: Disabled
thanks

thanks alot guys, am almost done with my little shell. but now i have to implement the "batch mode". ideeaaass?
 
Old 10-29-2012, 11:48 PM   #8
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.9, Centos 7.3
Posts: 17,374

Rep: Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383
You'll need to ask your teacher what they mean by 'batch mode' as *nix doesn't actually have that concept....
Possibly they mean cron http://www.adminschoice.com/crontab-quick-reference ?
 
Old 10-30-2012, 04:49 AM   #9
alexantosh
LQ Newbie
 
Registered: Oct 2012
Posts: 13

Original Poster
Rep: Reputation: Disabled
well, i hear the shell wont then display a prompt when in this mode. it will just read the commands from a pre-written batch file and then simply display the commands and their out put. to activate or enter this mode i shoud type [batchfile] on the command prompt where "batchFile" is the name of the batch file prewritten.
 
Old 10-30-2012, 05:14 AM   #10
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.9, Centos 7.3
Posts: 17,374

Rep: Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383Reputation: 2383
Ok, that sounds more like reading and acting upon a shell file aka script file, which would make sense.
All a shell/script file really is, is a collection of cmds that you could run direct from the cli manually.

See these links
http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/
 
Old 10-30-2012, 08:24 AM   #11
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,397
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
And to implement that, I would guess that you are expected to exercise some file-descriptor gymnastics, possibly involving pipe(), popen(), dup(), dup2(), and other functions that are probably referenced in the 'SEE ALSO' sections of the respective man pages.

--- rod.
 
Old 10-30-2012, 10:25 AM   #12
alexantosh
LQ Newbie
 
Registered: Oct 2012
Posts: 13

Original Poster
Rep: Reputation: Disabled
thanks for the links and tips. the book links look good but they appear to need some time, so i will first take a look at the dup() function usage. 'coz i didnt expect this feature to take a lot of time. but i am planning on making a fully functioning shell so even if my project is done am sure to keep going.
by the way, for the record: you guys are alot of help really, this blog isn't just for show. you show lost sheep the way to light.
I LIKE THAT
 
  


Reply


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
linux programming employable programming language emekadavid Linux - General 8 09-21-2012 03:19 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:47 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration