I am very new to using C and Xv6. I am trying to create a shell within Xv6 that can run simple commands. However, when I use fork(), my exec() function doesn't seem to do anything.
CODE:
#include "kernel/types.h"
#include "user/user.h"
int getCmd(char *buf, int buflen){
fprintf(1, ">>>");
gets(buf, buflen);
printf("%s", buf);
if (buf[0] == '\n' || buf[0] == ' ')
{
fprintf(2, "Please enter a command \n");
return 0;
}
return 1;
}
int forking(void){
int pid;
pid = fork();
if (pid < 0){
fprintf(2, "fork failed");
exit(0);
}
return pid;
}
void exec_line(char *buf){
char cmdstr[10][10];
for (int i = 0; i < strlen(buf); i++)
{
cmdstr[0][i] = buf[i];
}
char *str[2];
cmdstr[0][(strlen(cmdstr[0]) - 1)] = '\0';
str[0] = cmdstr[0];
printf("HRE1 %s,\n", str[0]);
exec(str[0], str);
printf("HRE2 %s,\n", str[0]);
exit(0);
}
int main(int argc, char *argv[])
{
char buf[512];
int buflen = sizeof(buf);
int a = 0;
while (a == 0){
if (getCmd(buf,buflen) == 1){
if (forking() == 0){
exec_line(buf);
} else{
wait(0);
}
}
}
exit(0);
}
Output:
>>>ls
ls
HRE1 ls
HRE2 ls
It seemed to work fine when it wasn't in the child fork. Would appreciate any help with this!
If the xv6 exec
function is anything like the Posix exec*
functions that takes an array of char*
, the last pointer should point at NULL
.
Your last pointer, str[1]
, is uninitialized - so it could point anywhere, and the program will (if the pointer doesn't happen to point at NULL
) have undefined behavior.
Add:
str[1] = NULL;
before calling
exec(str[0], str);
and also add perror(str[0]);
after calling exec
to get a clue about why it couldn't start the program in case it still fails.
Another option is to initialize all pointers when you define str
:
char *str[2] = {0};
or skipping the whole copying into cmdstr
:
char *str[2] = {buf}; // the second char* will be NULL
But: It's customary to provide the program name to the program you start so I suggest:
char *str[3] = {buf, buf}; // the third char* will be NULL