S
souissipro
Hi,
I have written a C program that does some of the functionalities
mentionned in my previous topic posted some days ago. This shell
should:
1- execute input commands from standard input, and also from a file
conatining the commands
2- does the redirection of the input and output from and to files.
3- retrieve the environment variables like HOME,..
I did the first question and it works fine, however when I modified the
code to implement the redirection it does not work anymore.
Could you please have a look to my code and tell me which is wrong
with?
I would also appreciate if you can tell me how to implement the 2nd
question in the function parse_line (see the code below):
Thank you very much for your help on this
Souissipro:
---------------SHELL---------------------------
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
/* maximal number of command arguments */
#define NARGS 50
#define MAXL 255
static char *prompt = "$ ";
static char *sep = " \n";
int
do_exit(char *argv[])
{
if (argv[1]==NULL)
exit(EXIT_SUCCESS);
else
fprintf(stderr,"Error: don't take arguments.\n");
return 1;
}
int
simple_cmd(char *argv[])
{
int i;
int pid, status;
if (strcmp(argv[0],"exit")==0)
return do_exit(argv);
for(i=0;argv!=NULL;i++)
printf("argv[%i]=\"%s\";\n",i,argv);
if (strcmp(argv[0],"cd")==0)
{
return chdir(*argv);
}
/*
* get the child process.
*/
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
/*
* child execute code inside if.
*/
if (pid == 0) {
execvp(*argv, argv);
perror(*argv);
exit(1);
}
/*
* parent execute wait.
*/
while (wait(&status) != pid)
/* empty */ ;
}
int
redir_cmd(char *argv[],char *in, char *out)
{
int i;
int pid, status;
int fd1, fd2;
int dummy;
if (strcmp(argv[0],"exit")==0)
return do_exit(argv);
for(i=0;argv!=NULL;i++)
printf("argv[%i]=\"%s\";\n",i,argv);
if (strcmp(argv[0],"cd")==0)
{
return chdir(*argv);
}
if (fork() == 0) {
fd1 = open(in, O_RDONLY);
if (fd1 < 0) {
perror("can't open file : in");
exit(1);
}
if (dup2(fd1, out) != 0) {
perror("catf1f2: dup2(in, 0)");
exit(1);
}
close(fd1);
fd2 = open(out, O_WRONLY | O_TRUNC | O_CREAT, 0644);
if (fd2 < 0) {
perror("catinout: out");
exit(2);
}
/*
if (dup2(fd2, 1) != 1) {
perror("catf1f2: dup2(out, 1)");
exit(1);
}
*/
close(fd2);
execvp(*argv, argv);
perror(*argv);
exit(1);
}
/*
* parent executes wait.
*/
else {
wait(&dummy);
}
}
int
parse_line(char *s,char *in, char *out)
{
char *argv[NARGS], *cur, *old;
int i=0;
if ((s[0]=='#')||(s[0]=='\n'))
return 0;
old=cur=s;
while((cur=strpbrk(cur,sep))!=NULL) {
argv[i++]=old;
cur[0]='\0';
cur++;
old=cur;
}
argv=NULL;
if
return redir_cmd(argv,in, out);
}
/* Main function
*/
int
main(int argc, char *argv[])
{
char s[MAXL];
int i;
char buf[255];
FILE *f;
if (argc > 3) {
fprintf(stderr,"incorrect arguments \n");
exit(EXIT_FAILURE);
}
if (argc == 2) {
f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "impossible to open the file for reading\n");
exit(EXIT_FAILURE);
}
while (fgets(buf, 255, f) != NULL) {
parse_line(buf,argv[1],"stdout");
printf("%s",buf);
}
fclose(f);
}
if (argc == 3) {
f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "impossible to open the file for reading\n");
exit(EXIT_FAILURE);
}
while (fgets(buf, 255, f) != NULL) {
parse_line(buf,argv[1],argv[2]);
printf("%s",buf);
}
fclose(f);
}
if (argc == 1) {
printf("vsh - mini-shell5.\n\n%s",prompt);
while(fgets(s,MAXL,stdin)!=NULL) {
parse_line(s,"stdin","stdout");
printf("%s",prompt);
}
}
return EXIT_FAILURE;
}
I have written a C program that does some of the functionalities
mentionned in my previous topic posted some days ago. This shell
should:
1- execute input commands from standard input, and also from a file
conatining the commands
2- does the redirection of the input and output from and to files.
3- retrieve the environment variables like HOME,..
I did the first question and it works fine, however when I modified the
code to implement the redirection it does not work anymore.
Could you please have a look to my code and tell me which is wrong
with?
I would also appreciate if you can tell me how to implement the 2nd
question in the function parse_line (see the code below):
Thank you very much for your help on this
Souissipro:
---------------SHELL---------------------------
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
/* maximal number of command arguments */
#define NARGS 50
#define MAXL 255
static char *prompt = "$ ";
static char *sep = " \n";
int
do_exit(char *argv[])
{
if (argv[1]==NULL)
exit(EXIT_SUCCESS);
else
fprintf(stderr,"Error: don't take arguments.\n");
return 1;
}
int
simple_cmd(char *argv[])
{
int i;
int pid, status;
if (strcmp(argv[0],"exit")==0)
return do_exit(argv);
for(i=0;argv!=NULL;i++)
printf("argv[%i]=\"%s\";\n",i,argv);
if (strcmp(argv[0],"cd")==0)
{
return chdir(*argv);
}
/*
* get the child process.
*/
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
/*
* child execute code inside if.
*/
if (pid == 0) {
execvp(*argv, argv);
perror(*argv);
exit(1);
}
/*
* parent execute wait.
*/
while (wait(&status) != pid)
/* empty */ ;
}
int
redir_cmd(char *argv[],char *in, char *out)
{
int i;
int pid, status;
int fd1, fd2;
int dummy;
if (strcmp(argv[0],"exit")==0)
return do_exit(argv);
for(i=0;argv!=NULL;i++)
printf("argv[%i]=\"%s\";\n",i,argv);
if (strcmp(argv[0],"cd")==0)
{
return chdir(*argv);
}
if (fork() == 0) {
fd1 = open(in, O_RDONLY);
if (fd1 < 0) {
perror("can't open file : in");
exit(1);
}
if (dup2(fd1, out) != 0) {
perror("catf1f2: dup2(in, 0)");
exit(1);
}
close(fd1);
fd2 = open(out, O_WRONLY | O_TRUNC | O_CREAT, 0644);
if (fd2 < 0) {
perror("catinout: out");
exit(2);
}
/*
if (dup2(fd2, 1) != 1) {
perror("catf1f2: dup2(out, 1)");
exit(1);
}
*/
close(fd2);
execvp(*argv, argv);
perror(*argv);
exit(1);
}
/*
* parent executes wait.
*/
else {
wait(&dummy);
}
}
int
parse_line(char *s,char *in, char *out)
{
char *argv[NARGS], *cur, *old;
int i=0;
if ((s[0]=='#')||(s[0]=='\n'))
return 0;
old=cur=s;
while((cur=strpbrk(cur,sep))!=NULL) {
argv[i++]=old;
cur[0]='\0';
cur++;
old=cur;
}
argv=NULL;
if
return redir_cmd(argv,in, out);
}
/* Main function
*/
int
main(int argc, char *argv[])
{
char s[MAXL];
int i;
char buf[255];
FILE *f;
if (argc > 3) {
fprintf(stderr,"incorrect arguments \n");
exit(EXIT_FAILURE);
}
if (argc == 2) {
f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "impossible to open the file for reading\n");
exit(EXIT_FAILURE);
}
while (fgets(buf, 255, f) != NULL) {
parse_line(buf,argv[1],"stdout");
printf("%s",buf);
}
fclose(f);
}
if (argc == 3) {
f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "impossible to open the file for reading\n");
exit(EXIT_FAILURE);
}
while (fgets(buf, 255, f) != NULL) {
parse_line(buf,argv[1],argv[2]);
printf("%s",buf);
}
fclose(f);
}
if (argc == 1) {
printf("vsh - mini-shell5.\n\n%s",prompt);
while(fgets(s,MAXL,stdin)!=NULL) {
parse_line(s,"stdin","stdout");
printf("%s",prompt);
}
}
return EXIT_FAILURE;
}