Hi all,
I'm writing a toy shell (again

) and this is the code so far:
Code:
/**
Ett enkelt skal.
2011-04-16
*/
//includes
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //För fork
#include <errno.h> //För perror
#include <sys/types.h> //För waitpid
#include <sys/wait.h> //För waitpid
#include <string.h> //För strcat, strdup
//Makron
#define DEBUGLEVEL 1
#define DEBUGT(x) if(DEBUGLEVEL > 0) printf("%s\n", x)
#define DEBUGN(x) if(DEBUGLEVEL > 0) printf("%i", x)
int main(int argc, char **argv, char **envp){
char input[128];
char *args[7];
char *c;
while(1){
printf("> ");
//Läs input från användaren, använder fgets för att förhindra buffer overflow.
fgets(input, 128, stdin);
//Ta bort '\n', ersätt med '\0' annars hittar inte execv.
c = strchr(input, '\n');
*c = '\0';
DEBUGT(input);
if(strcmp(input, "exit") == 0){
break;
}
//Skapa ny process.
pid_t child = fork();
if(child == 0){
//Detta är barnet
args[0] = NULL;
//Leta efter programmet i alla mappar i PATH samt i den mapp man befinner sig i nu.
char *temp = NULL;
char *path = getenv("PATH");
path = strtok(path, ":");
while(path != NULL){
DEBUGT("PATH:");
DEBUGT(path);
temp = strdup(path);
DEBUGT("TEMP:");
DEBUGT(temp);
//Klistra ihop sökvägen och sätt parametrar till execv
strcat(temp, "/");
args[0] = strcat(temp, input);
//Sätt övriga parametrar
args[1] = NULL; //TEMP här
DEBUGT("ARGS[0]:");
DEBUGT(args[0]);
//run the requested program
execv(args[0], args);
free(temp);
path = strtok(NULL, ":");
}
//Kommer vi hit så blev det nått fel
perror("execv");
return 1;
}
else{
//Jag är föräldern.
//Vänta på att barnet ska bli klart (barnet är en förgrundprocess), och kolla dess status.
int childStatus;
waitpid(child, &childStatus, 0);
if(WEXITSTATUS(childStatus) == 0){
DEBUGT("Child exited normally!");
}
else{
DEBUGT("Child did not exit well!");
}
//Gör nått.
}
}
return 0;
}
As you can see its in a early stage yet. Now, when I give commands which are less then 4 characters long it works just fine but if I give it commands longer then 3 characters long I get the following error message:
Code:
*** glibc detected *** ./SmallShell: free(): invalid next size (fast): 0x08a1f020 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6c501)[0x803501]
/lib/libc.so.6(+0x6dd70)[0x804d70]
/lib/libc.so.6(cfree+0x6d)[0x807e5d]
./SmallShell[0x8048858]
/lib/libc.so.6(__libc_start_main+0xe7)[0x7adce7]
./SmallShell[0x8048621]
======= Memory map: ========
0025f000-00260000 r-xp 00000000 00:00 0 [vdso]
002e9000-00305000 r-xp 00000000 08:01 651592 /lib/ld-2.12.1.so
00305000-00306000 r--p 0001b000 08:01 651592 /lib/ld-2.12.1.so
00306000-00307000 rw-p 0001c000 08:01 651592 /lib/ld-2.12.1.so
00719000-00733000 r-xp 00000000 08:01 651756 /lib/libgcc_s.so.1
00733000-00734000 r--p 00019000 08:01 651756 /lib/libgcc_s.so.1
00734000-00735000 rw-p 0001a000 08:01 651756 /lib/libgcc_s.so.1
00797000-008ee000 r-xp 00000000 08:01 651618 /lib/libc-2.12.1.so
008ee000-008f0000 r--p 00157000 08:01 651618 /lib/libc-2.12.1.so
008f0000-008f1000 rw-p 00159000 08:01 651618 /lib/libc-2.12.1.so
008f1000-008f4000 rw-p 00000000 00:00 0
08048000-08049000 r-xp 00000000 08:01 274582 /home/ss/Desktop/ID2206/Labb2/SmallShell
08049000-0804a000 r--p 00000000 08:01 274582 /home/ss/Desktop/ID2206/Labb2/SmallShell
0804a000-0804b000 rw-p 00001000 08:01 274582 /home/ss/Desktop/ID2206/Labb2/SmallShell
08a1f000-08a40000 rw-p 00000000 00:00 0 [heap]
b7600000-b7621000 rw-p 00000000 00:00 0
b7621000-b7700000 ---p 00000000 00:00 0
b773a000-b773b000 rw-p 00000000 00:00 0
b774a000-b774e000 rw-p 00000000 00:00 0
bfab3000-bfad4000 rw-p 00000000 00:00 0 [stack]
Child exited normally!
And I cant figure out why. I have tested the code with valgrind (I ran the command: valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./SmallShell) and it tells me:
Code:
==2610== All heap blocks were freed -- no leaks are possible
So i dont really know whats going on here. I'm using gcc version 4.4.5 on Ubuntu 10.10. Try it out, give a command shorter than or equal to 3 characters long such as 'pwd' and then a longer one such as 'printenv', see if you guys get the same error. If somebody could shed some light on this it would be greatly appreciated!
//C++arl