C and C++

Moderators: None (Apply to moderate this forum)
Number of threads: 28629
Number of posts: 94611

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Unix Shell (A problem for C Masters) Posted by MDC on 6 Nov 2003 at 4:43 PM
Hi, i have to make my own unix shell (Which works like csh, tcsh and so on), i've created a basic shell and it works (i will post it below), but there are a very problems which i cannot figure out.

1)How do i make the shell exit when the user types (exit or control-D)
(something tells me i have to use a signal handler...but the various one's i've tried did not work...Grrrr)

second problem (this one is worse than the first)

If a child process is running @ foreground, the user can send the interrupt singal (Control-C) to terminate the child process, but the current parent process should not die.

Thanks []v[]atty-D

-------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <unistd.h>
pid_t myFork();
int readArgs(const char *, char *[]);
int main(int argc, char *argv[]){
pid_t pid;
char line[255];
char *argList[20];
int ampersand, status, i;
printf("This program executes commands and\n");
printf("programs for you\n");
while(1){
printf("To exit, enter CTR-C, or enter\n");
printf("a program name with its arguments> ");
fgets(line, 255, stdin);
ampersand=readArgs(line, argList);
if((pid = myFork()) == -1){
perror("impossible to fork");
exit(1);
}

if(pid > 0) // This is the parent
if(ampersand) // Background execution
printf("Process [%d]\n", pid);
else{
waitpid(pid, &status, 0);
printf("My child has terminated\n");
}
else // this is the child
if(execvp(argList[0], argList)==-1){
perror("child Process");
exit(22);
}
}
}

pid_t myFork(){
static int count=0;
count++;
if(count <= 20)
return(fork());
else
return(-1);
}

int readArgs(const char *line, char *argList[]){
static int yes=0;
int i=0, offset=0, found=0;
char name[50];
while(yes && argList[i] != NULL)
free(argList[i++]);
i=0; // reset i to ZERO
while(sscanf(line+offset, "%s", name)==1){
argList[i] = (char *) malloc(strlen(name)+1);
strcpy(argList[i++], name);
while(line[offset]==' ') offset++; //skip blanks
offset += strlen(name);
}

if(!strcmp(argList[i-1], "&")){
argList[i-1] = NULL;
found = 1;
}
else{
if(argList[i-1][strlen(argList[i-1])-1]=='&'){
argList[i-1][strlen(argList[i-1])-1]='\0';
found = 1;
}
argList[i] = NULL;
}
yes=1;
return(found);
}
Report
Re: Unix Shell (A problem for C Masters) Posted by macpherson on 6 Nov 2003 at 4:49 PM
: Hi, i have to make my own unix shell (Which works like csh, tcsh and so on), i've created a basic shell and it works (i will post it below), but there are a very problems which i cannot figure out.
:
: 1)How do i make the shell exit when the user types (exit or control-D)
: (something tells me i have to use a signal handler...but the various one's i've tried did not work...Grrrr)
:
: second problem (this one is worse than the first)
:
: If a child process is running @ foreground, the user can send the interrupt singal (Control-C) to terminate the child process, but the current parent process should not die.
:
: Thanks []v[]atty-D
:
Now we can read it.
: -------------------------------------------------------------
: #include <stdio.h>
: #include <string.h>
: #include <unistd.h>
: pid_t myFork();
: int readArgs(const char *, char *[]);
: int main(int argc, char *argv[]){
: pid_t pid;
: char line[255];
: char *argList[20];
: int ampersand, status, i;
:    printf("This program executes commands and\n");
:    printf("programs for you\n");
:      while(1){
:       printf("To exit, enter CTR-C, or enter\n");
:       printf("a program name with its arguments> ");
:       fgets(line, 255, stdin);
:       ampersand=readArgs(line, argList);
:       if((pid = myFork()) == -1){
:            perror("impossible to fork");
:            exit(1);
:          }
: 
:       if(pid > 0) // This is the parent
:           if(ampersand) // Background execution
:                printf("Process [%d]\n", pid);
:            else{
:                  waitpid(pid, &status, 0);
:                  printf("My child has terminated\n");
:                 }
:      else // this is the child
:         if(execvp(argList[0], argList)==-1){
:         perror("child Process");
:         exit(22);
:       }
:     }
:   }
: 
: pid_t myFork(){
:   static int count=0;
:   count++;
:   if(count <= 20)
:   return(fork());
:   else
:   return(-1);
: }
: 
: int readArgs(const char *line, char *argList[]){
: static int yes=0;
: int i=0, offset=0, found=0;
: char name[50];
: while(yes && argList[i] != NULL)
: free(argList[i++]);
: i=0; // reset i to ZERO
: while(sscanf(line+offset, "%s", name)==1){
: argList[i] = (char *) malloc(strlen(name)+1);
: strcpy(argList[i++], name);
: while(line[offset]==' ') offset++; //skip blanks
: offset += strlen(name);
: }
: 
: if(!strcmp(argList[i-1], "&")){
: argList[i-1] = NULL;
: found = 1;
: }
: else{
: if(argList[i-1][strlen(argList[i-1])-1]=='&'){
: argList[i-1][strlen(argList[i-1])-1]='\0';
: found = 1;
: }
: argList[i] = NULL;
: }
: yes=1;
: return(found);
: }
: 


Report
Re: Unix Shell (A problem for C Masters) Posted by MDC on 6 Nov 2003 at 7:01 PM
Ok i think i sorta figured out Part 2, but part 1 is still giving me problems. Someone told me instead of using a alarm handler i have to edit the string, whatever that means lol.
Report
Re: Unix Shell (A problem for C Masters) Posted by abc on 7 Nov 2003 at 2:31 AM
: Ok i think i sorta figured out Part 2, but part 1 is still giving me problems. Someone told me instead of using a alarm handler i have to edit the string, whatever that means lol.
:

actually, part 2 is rather easy. when doing Ctrl-C, the controlling terminal sends SIGINT to the foreground process group. all you have to do is ignore it in the parent while there's a child running.
...
if(pid > 0)
{
...
    signal(SIGINT, SIG_IGN);
    waitpid(pid, &status, 0);
    signal(SIGTSTP, SIG_DFL);
...
}


for part 1, you need to figure out what was entered, so parse the input. to break it down into pieces:
...
fgets(line, 255, stdin);
if(10 == line[0]) /*ENTER or Ctrl-D will give you this*/
    exit(0);
if('e' == line[0] && !strncmp(line, "exit",4) )
    exit(0);
/*otherwise proceed with interpreting the command*/
...




 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.