I'm writing a stupid and simple shell. So far I've finished coding and I've compiled it. It works like a charm. But the thing I'm concerned about is that gcc gives me a warning.
shelltox.c:(.text+0x2a): warning: the `gets' function is dangerous and should not be used.
I've googled this and learned why it was dangerous.
After getting this warning I decided to use fgets(). After the implementation my code doesn't work anymore. It compiles perfectly. After it prints the prompt I write for example "ls" command. Then I get the error "ls command not found". I guess there is a NULL character or something like that which is passed with the command to execvp call thats why it cant find the command.
It's been 39 hours now just for a stupid shell and I really really really want to sleep (had 15 cups of coffee). Please help me out here. I'm totally cursed!
I'm posting my code. One with gets() other one with fgets.
I hope your day will be perfect "if you help me"!
#define _GNU_SOURCE
//#include <curses.h> /* for coloring? */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <sysexits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/utsname.h>
#include <unistd.h>
void sig_int(int signo)
{
exit(0);
}
void prompt(void){
struct passwd *passwd;
passwd = getpwuid (getuid()); /* Get login name, home directory */
char *homedir = passwd->pw_dir;
char *currentdir = getcwd(NULL, 0);
char *loginname = passwd->pw_name;
//struct utsname *sysinfo; /* Get machine name (didn't work correctly) */
//int a=uname(sysinfo);
printf("\n%s@%s:%s>", loginname, /*sysinfo->nodename*/ getenv("HOSTNAME"), currentdir);
}
void parse(char *line, char **argv)
{
while(*line != '\0') { /* if not the end of line ....... */
while(*line == ' ' || *line == '\t' || *line == '\n'){
*line++ = '\0'; /* replace white spaces with 0 */
}
*argv++=line; /* save the argument position */
while(*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n'){
line++; /* skip the argument until ... */
}
}
*argv='\0'; /* mark the end of argument list */
}
void execute(char **argv)
{
pid_t pid;
int status;
if((pid = fork()) < 0){ /* fork a child process */
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if(pid == 0){ /* for the child process: */
if (execvp(*argv, argv) < 0) { /* execute the command */
printf("kabuk: %s: command not found",argv[0]);
exit(1);
}
}
else{ /* for the parent: */
while (wait(&status) != pid); /* wait for completion */
}
}
void export(void){
extern char **environ;
int i=0;
while(environ[i]!='\0'){
printf("%d %s\n",i,environ[i++]);
}
}
int main(int argc, char *argv[])
{
char line[1024];
char *argva[64]; /* kabuk is limited to take 64 command + arguments in a line */
while (1) {
prompt(); /* Print the prompt */
gets(line); /* Get user input */
parse(line, argva); /* Parse user input */
if(!strcmp(argva[0],"exit")){
exit(0);
}
else if(!strcmp(argva[0],"cd")){
if(argva[1]!='\0')
if(chdir(argva[1])){printf("kabuk: cd: %s: No such file or directory",argva[1]);}
}
else if(!strcmp(argva[0],"cd..")){
chdir("..");
}
else if(!strcmp(argva[0],"cd;")){
chdir(getenv("HOME"));
}
else if(!strcmp(argva[0],"export")){
export();
}
else if(!strcmp(argva[0],"$PATH")||!strcmp(argva[0],"path")){
printf(getenv("PATH"));
}
else {
execute(argva); /* otherwise, execute the command */
}
}
return( 0 );
}
gets(line); WORKS
instead of that I wrote fgets(line,sizeof(line),stdin);
now it doesn't work. S.O.S ... --- ... !!!!
Regards,
clargs

New Topic/Question
Reply




MultiQuote



|