我被要求爲操作系統類實現我自己的shell。系統調用execve不會使用ls函數返回
我的殼運行的每個命令很好,除了LS不會在execve的,因爲CD,CP,MV,和所有其它主要的命令返回還好這是奇怪的回報。
ls仍然顯示正確的輸出(文件夾中的文件列表),但只是繼續運行(execve掛起並需要回車完成)。
像-l,-a之類的所有選項也可以正常工作,並具有相同的問題。
編輯:我修改了代碼,以徹底避免任何內存泄漏(我用的valgrind跟蹤它們),增加了一些評論,所以你可以看到發生了什麼事情,但LS依然沒有回來。以下是更新版本:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAXPATHLEN 40
#define MAXSIZE 100
#define MAXARGS 10
static char cwd[MAXPATHLEN];
typedef void (*sighandler_t)(int);
void handle_signal(int signo);
void parse_command(char *command, char **arguments);
int main(int argc, char *argv[], char *envp[])
{
int status;
char *command;
char **arguments;
signal(SIGINT, SIG_IGN);
signal(SIGINT, handle_signal);
while(1) {
//Allocating memory
command = calloc(MAXSIZE, sizeof(char));
arguments = calloc(MAXARGS, sizeof(char *));
//Print shell name and cwd
getcwd(cwd,MAXPATHLEN);
printf("[MY_SHELL]:%s$ ", cwd);
parse_command(command, arguments);
//Displays command and arguments
printf("Command is %s\n", command);
int i;
for(i=0; arguments[i] != NULL; ++i){
printf("Argument %d is %s\n", i, arguments[i]);
}
//Fork exec code
if (fork() != 0){
waitpid(1, &status, 0);
} else{
execve(command, arguments, 0);
}
free(command);
for (i=0; arguments[i] != NULL; ++i) {
free(arguments[i]);
}
free(arguments);
}
return 0;
}
void handle_signal(int signo)
{
getcwd(cwd,MAXPATHLEN);
printf("\n[MY_SHELL]:%s$ ", cwd);
fflush(stdout);
}
void parse_command(char *command, char **arguments){
char buf[MAXSIZE];
char env[MAXPATHLEN];
char *tmp;
//Initiate array values to avoid buffer overflows
memset(buf, 0, sizeof(buf));
memset(env, 0, sizeof(env));
//Read command and put it in a buffer
char c = '\0';
int N = 0; //Number of chars in input - shouldn't be more than MAXSIZE
while(1) {
c = getchar();
if (c == '\n')
break;
else{
if (N == MAXSIZE)
break;
buf[N] = c;
}
++N;
}
//Extract command name (e.g "ls"), fetch path to command, append it to command name
tmp = strtok(buf, " ");
strcpy(env, "/bin/");
size_t len1 = strlen(env);
size_t len2 = strlen(tmp);
memcpy(command, env, len1);
memcpy(command + len1, tmp, len2);
//Extracts arguments array: arguments[0] is path+command name
arguments[0] = calloc(strlen(command) + 1, sizeof(char));
strcpy(arguments[0], command);
int i = 1;
while(1){
tmp = strtok(NULL, " ");
if (tmp == NULL)
break;
else{
arguments[i] = calloc(strlen(tmp) + 1, sizeof(char));
strcpy(arguments[i],tmp);
++i;
}
}
}
編輯2:這似乎有事情做與STDIN(或標準輸出):相若方式比LS,貓使得執行後execve的掛了,我需要回車讓我的shell行[MY_SHELL] current_working_directory $:回來。有關爲什麼會出現這種情況的任何想法?
標準警告:請[不要轉換](http://stackoverflow.com/q/605845/2173917)'malloc()'和系列的返回值。 – 2015-02-10 09:13:02
我懷疑'cd'與'execve'一起工作... – mafso 2015-02-10 10:55:06
對不起,關於cd,是的,它應該是一個內置的命令。我修復了代碼,內存泄漏,但ls仍然沒有返回。 – 2015-02-10 21:48:22