22 for (
int i = 0; input_line_[i] !=
'\0'; i++)
24 if (input_line_[i] ==
' ')
26 input_line_[i] =
'\0';
28 else if (i == 0 || input_line_[i - 1] ==
'\0')
30 if (arg_number_ >= MAX_ARG_NUMBER)
34 arg_tab_[arg_number_++] = &input_line_[i];
51RamFS::Dir* Path2Dir(
char* path)
59 RamFS::Dir* dir = current_dir_;
65 if (path[index] ==
'\0')
71 for (
size_t i = 0; i < MAX_LINE_SIZE; i++)
73 auto tmp = strchr(path + index,
'/');
76 return dir->FindDir(path + index);
78 else if (tmp == path + index)
85 dir = dir->FindDir(path + index);
87 index =
static_cast<size_t>(tmp - path + 1);
88 if (path[index] ==
'\0' || dir ==
nullptr)
109RamFS::File* Path2File(
char* path)
116 auto name = StrchrRev(path,
'/');
120 return current_dir_->FindFile(path);
129 RamFS::Dir* dir = name == path ? &ramfs_.root_ : Path2Dir(path);
133 return dir->FindFile(name + 1);
157 if (arg_number_ < 1 || arg_number_ > MAX_ARG_NUMBER)
162 if (strcmp(arg_tab_[0],
"cd") == 0)
164 RamFS::Dir* dir = arg_number_ >= 2 ? Path2Dir(arg_tab_[1]) : nullptr;
173 if (strcmp(arg_tab_[0],
"ls") == 0)
175 auto ls_fun = [&](RamFS::FsNode& item)
177 switch (item.GetNodeType())
179 case RamFS::FsNodeType::DIR:
180 write_stream_ << ConstRawData(
"d ");
182 case RamFS::FsNodeType::FILE:
183 if (
static_cast<RamFS::File&
>(item).IsExecutable())
185 write_stream_ << ConstRawData(
"x ");
189 write_stream_ << ConstRawData(
"f ");
192 case RamFS::FsNodeType::CUSTOM:
193 write_stream_ << ConstRawData(
"? ");
196 write_stream_ << ConstRawData(
"? ");
199 write_stream_ << ConstRawData(item.GetName());
201 return ErrorCode::OK;
204 current_dir_->Foreach(ls_fun);
208 auto* ans = Path2File(arg_tab_[0]);
212 write_stream_ << ConstRawData(
"Command not found.");
217 if (!ans->IsExecutable())
219 write_stream_ << ConstRawData(
"Not an executable file.");
225 (void)write_stream_.Commit();
226 write_mutex_->Unlock();
227 ans->Run(arg_number_, arg_tab_);
228 write_mutex_->Lock();
242 char* path = &input_line_[0];
249 char *tmp = path, *path_end = path;
251 while (*tmp !=
' ' && *tmp !=
'\0')
261 if (tmp - &input_line_[0] !=
static_cast<int>(input_line_.Size() + offset_))
267 char* prefix_start =
nullptr;
268 RamFS::Dir* dir =
nullptr;
270 if (path_end == path)
273 prefix_start = path_end;
277 prefix_start = path_end + 1;
284 dir = Path2Dir(path);
293 RamFS::FsNode* ans_node =
nullptr;
295 size_t shared_prefix_len = 0;
297 if (*prefix_start ==
'/')
302 int prefix_len =
static_cast<int>(tmp - prefix_start);
304 auto foreach_fun_find = [&](RamFS::FsNode& node)
306 if (strncmp(node.GetName(), prefix_start, prefix_len) == 0)
312 return ErrorCode::OK;
316 dir->Foreach(foreach_fun_find);
322 else if (number == 1)
324 auto name_len = strlen(ans_node->GetName());
325 for (
size_t i = 0; i < name_len - prefix_len; i++)
327 DisplayChar(ans_node->GetName()[i + prefix_len]);
335 auto foreach_fun_show = [&](RamFS::FsNode& node)
337 if (strncmp(node.GetName(), prefix_start, prefix_len) == 0)
339 auto name_len = strlen(node.GetName());
340 write_stream_ << ConstRawData(node.GetName(), name_len);
342 if (ans_node ==
nullptr)
345 shared_prefix_len = name_len;
346 return ErrorCode::OK;
349 for (
size_t i = 0; i < name_len; i++)
351 if (node.GetName()[i] != ans_node->GetName()[i])
353 shared_prefix_len = i;
360 if (shared_prefix_len > name_len)
362 shared_prefix_len = name_len;
368 return ErrorCode::OK;
371 dir->Foreach(foreach_fun_show);
374 write_stream_ << ConstRawData(&input_line_[0], input_line_.Size());
376 for (
size_t i = 0; i < shared_prefix_len - prefix_len; i++)
378 DisplayChar(ans_node->GetName()[i + prefix_len]);