lab5: 实现 cd、pwd
This commit is contained in:
parent
cee4ec05ea
commit
9f3a58f966
@ -29,7 +29,8 @@ int fs_server_cap;
|
||||
#define FTYPE_FILE 0b01
|
||||
#define FTYPE_DIR 0b10
|
||||
|
||||
static char *builtin_complement_word[] = {"cd", "ls", "ll", "cat", "echo", "clear"};
|
||||
static char *builtin_complement_word[] = {"cd", "ls", "ll", "cat", "echo", "clear", "pwd",
|
||||
"exit", "quit"};
|
||||
static int n_builtin_complement_word = sizeof(builtin_complement_word) / sizeof(char *);
|
||||
|
||||
static char file_complement_buf[MAX_FILE_COMPLEMENT_WORD * (MAX_FILENAME_LEN + 1)];
|
||||
@ -38,6 +39,9 @@ void path_to_absolute(char *path);
|
||||
void path_append(char *path, char *sub);
|
||||
int fs_scan(char *path);
|
||||
|
||||
// 当前目录
|
||||
char working_directory[BUFLEN] = {'/'};
|
||||
|
||||
/**
|
||||
* 生成文件补全词列表
|
||||
* @param ret_words 返回列表
|
||||
@ -131,8 +135,10 @@ static char *match_builtin_command_param(char *complement, int complement_time,
|
||||
while (complement[start_pos] == ' ')
|
||||
start_pos++;
|
||||
// 匹配子目录文件
|
||||
if (*(complement + start_pos) != '\0') {
|
||||
n_words = make_file_complement_word(&words, complement + start_pos, type_mask);
|
||||
matched = match_complement_words(words, n_words, complement + start_pos, complement_time, match_count);
|
||||
}
|
||||
// 匹配当前目录文件
|
||||
if (!matched) {
|
||||
n_words = make_file_complement_word(&words, NULL, type_mask);
|
||||
@ -157,8 +163,10 @@ static int do_complement(char *buf, char *complement, int complement_time)
|
||||
int n_words;
|
||||
|
||||
// 匹配子目录内文件,如 tar 匹配 tar/file1
|
||||
if (*complement != '\0') {
|
||||
n_words = make_file_complement_word(&words, complement, FTYPE_FILE);
|
||||
matched = match_complement_words(words, n_words, complement, complement_time, &match_count);
|
||||
}
|
||||
|
||||
// 匹配当前目录文件,如 f 匹配 file1
|
||||
if (!matched) {
|
||||
@ -260,14 +268,29 @@ char *readline(const char *prompt)
|
||||
|
||||
int do_cd(char *cmdline)
|
||||
{
|
||||
char pathbuf[BUFLEN];
|
||||
cmdline += 2;
|
||||
while (*cmdline == ' ')
|
||||
cmdline++;
|
||||
if (*cmdline == '\0')
|
||||
return 0;
|
||||
// 解析路径
|
||||
if (*cmdline != '/') {
|
||||
// 相对路径
|
||||
strcpy(pathbuf, working_directory);
|
||||
path_append(pathbuf, cmdline);
|
||||
} else {
|
||||
// 绝对路径
|
||||
strcpy(pathbuf, cmdline);
|
||||
}
|
||||
printf("Build-in command cd %s: Not implemented!\n", cmdline);
|
||||
// 检查路径是否存在
|
||||
int ret = fs_scan(pathbuf);
|
||||
if (ret < 0) {
|
||||
printf("'%s' is not a dir!\n", cmdline);
|
||||
return -1;
|
||||
}
|
||||
// 切换
|
||||
strcpy(working_directory, pathbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -277,18 +300,24 @@ int do_top()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_pwd()
|
||||
{
|
||||
printf("%s\n", working_directory);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为绝对路径
|
||||
*/
|
||||
void path_to_absolute(char *path) {
|
||||
char pathbuf[BUFLEN];
|
||||
strcpy(pathbuf + 1, path);
|
||||
pathbuf[0] = '/';
|
||||
strcpy(pathbuf, working_directory);
|
||||
path_append(pathbuf, path);
|
||||
strcpy(path, pathbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路径连接
|
||||
* 路径连接,sub 必须为相对路径且不支持 ..
|
||||
*/
|
||||
void path_append(char *path, char *sub) {
|
||||
size_t path_len = strlen(path);
|
||||
@ -298,13 +327,19 @@ void path_append(char *path, char *sub) {
|
||||
path += path_len;
|
||||
} else {
|
||||
path[path_len] = '/';
|
||||
path += path_len + 1;
|
||||
path += ++path_len;
|
||||
}
|
||||
}
|
||||
// sub 之前没有 '/'
|
||||
while (*sub == '/') sub++;
|
||||
// 连接路径
|
||||
strcpy(path, sub);
|
||||
path += strlen(sub);
|
||||
path_len += strlen(sub);
|
||||
// 路径末尾不能出现 '/',个人感觉不是很合理,但是 tfs_open_path 行为如此
|
||||
while (*--path == '/' && --path_len > 0) {
|
||||
*path = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -551,6 +586,10 @@ int builtin_cmd(char *cmdline)
|
||||
ret = do_top();
|
||||
return !ret ? 1 : -1;
|
||||
}
|
||||
if (!strcmp(cmd, "pwd")) {
|
||||
ret = do_pwd();
|
||||
return !ret ? 1 : -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user