Prev: creating a socket
Next: Learn about proxy sites and how to use them to open blocked sites unlimited downloads from RapidShare and megaupload and increase the speed of the Internet with new sites for free
From: BigBrother on 26 Mar 2010 18:09 I'm trying to build a very basic shell (like bash but..bad). And I've decided the best way to do this would be to make my programs separately and put them in their own directory, much like /bin. Well how can I set something like this up. I tell my shell 'ls' and it looks in the directory I choose to store the data in, then it runs the program and when its done exits and returns to its own process? I'm teaching myself C so I'm pretty lost on how to do this. Sorry if this is poorly worded
From: Barry Margolin on 26 Mar 2010 21:54 In article <4559b36e-3bb6-48da-a9b0-97da42038d65(a)s20g2000prm.googlegroups.com>, BigBrother <cowboyninja(a)gmail.com> wrote: > I'm trying to build a very basic shell (like bash but..bad). And I've > decided the best way to do this would be to make my programs > separately and put them in their own directory, much like /bin. Well > how can I set something like this up. I tell my shell 'ls' and it > looks in the directory I choose to store the data in, then it runs the > program and when its done exits and returns to its own process? I'm > teaching myself C so I'm pretty lost on how to do this. Sorry if this > is poorly worded When a shell runs a program, it uses fork() to create a child process. The child process uses execv() (or one of the other exec* variants) to run the program, while the shell uses wait() to wait for it to finish. Things get a bit more complicated when pipelines are involved, but that's the basic structure. And if the program is run in the background, the shell simply continues on rather than using wait() (job control complicates this somewhat). -- Barry Margolin, barmar(a)alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
From: jellybean stonerfish on 27 Mar 2010 02:30 On Fri, 26 Mar 2010 15:09:53 -0700, BigBrother wrote: > I'm trying to build a very basic shell (like bash but..bad). And I've > decided the best way to do this would be to make my programs separately > and put them in their own directory, much like /bin. Well how can I set > something like this up. I tell my shell 'ls' and it looks in the > directory I choose to store the data in, then it runs the program and > when its done exits and returns to its own process? I'm teaching myself > C so I'm pretty lost on how to do this. Sorry if this is poorly worded Maybe add your own directory to your PATH PATH=yourdir:$PATH
From: Phred Phungus on 28 Mar 2010 01:31 Alan Curry wrote: > Or just call execvp() > I have something slightly different that I'm looking at. It's intorduced in Stevens and Rago as a basic shell, and it uses the exec family for the business end of it. My question is about the buffers. $ gcc -D_GNU_SOURCE -std=c99 -Iinclude -Wall -Wextra lib/error.o fig1.10.1.c -o out fig1.10.1.c:38: warning: unused parameter �signo� $ ./out % ls advio fig11.5 fig16.15 fig18.12 fig6.2 figC.4 .... fig11.4 fig16.14 fig18.11 fig5.5 figC.3 % ^Cinterrupt % Aborted $ $ cat fig1.10.1.c #include "apue.h" #include <sys/wait.h> static void sig_int(int); /* our signal-catching function */ int main(void) { char buf[MAXLINE]; /* from apue.h */ pid_t pid; int status; if (signal(SIGINT, sig_int) == SIG_ERR) err_sys("signal error"); printf("%% "); /* print prompt (printf requires %% to print %) */ while (fgets(buf, MAXLINE, stdin) != NULL) { if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; /* replace newline with null */ if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /* child */ execlp(buf, buf, (char *)0); err_ret("couldn't execute: %s", buf); exit(127); } /* parent */ if ((pid = waitpid(pid, &status, 0)) < 0) err_sys("waitpid error"); printf("%% "); } exit(0); } void sig_int(int signo) { printf("interrupt\n%% "); abort(); } // gcc -D_GNU_SOURCE -std=c99 -Iinclude -Wall -Wextra lib/error.o fig1.10.1.c -o out $ Basically, my question is whether the buffers here are well-constructed. MAXLINE will probably be a large number, while the commands I type will be no more than a hundred characters. execlp(buf, buf, (char *)0); To my eye, it looks like this could get by with one argument instead of three. To the OP, a basic shell is here if you can replicate the steps. You won't have the source for things like err_sys, but you can comment those lines out. HTH -- fred
From: Alan Curry on 28 Mar 2010 02:09
In article <8187ufFt6bU1(a)mid.individual.net>, Phred Phungus <Phred(a)example.invalid> wrote: | while (fgets(buf, MAXLINE, stdin) != NULL) { | if (buf[strlen(buf) - 1] == '\n') | buf[strlen(buf) - 1] = 0; /* replace newline with null */ [...] | |Basically, my question is whether the buffers here are well-constructed. | MAXLINE will probably be a large number, while the commands I type |will be no more than a hundred characters. If you type a line that's too long, some ugly stuff will happen, but that's an acceptable flaw in a small demonstration program. | |execlp(buf, buf, (char *)0); | |To my eye, it looks like this could get by with one argument instead of |three. Well the 0 at the end is a terminator, you have to have that or execlp doesn't know how many args there are. And the first 2 are semi-redundant: one is the name of the program to be executed, and the other one is what that program will get in its argv[0]. Normally those should be the same, and in this example they are the same (both are "buf"). If you left out the secnod arg to execlp, the exec'd program would get a null argv[0], which is not quite a disaster but it's really nasty. -- Alan Curry |