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];
51 RamFS::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)
109 RamFS::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);
151 void ExecuteCommand()
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.");
224 write_stream_.Commit();
225 write_mutex_->Unlock();
226 ans->Run(arg_number_, arg_tab_);
227 write_mutex_->Lock();
241 char* path = &input_line_[0];
248 char *tmp = path, *path_end = path;
250 while (*tmp !=
' ' && *tmp !=
'\0')
260 if (tmp - &input_line_[0] !=
static_cast<int>(input_line_.Size() + offset_))
266 char* prefix_start =
nullptr;
267 RamFS::Dir* dir =
nullptr;
269 if (path_end == path)
272 prefix_start = path_end;
276 prefix_start = path_end + 1;
283 dir = Path2Dir(path);
292 RamFS::FsNode* ans_node =
nullptr;
294 size_t shared_prefix_len = 0;
296 if (*prefix_start ==
'/')
301 int prefix_len =
static_cast<int>(tmp - prefix_start);
303 auto foreach_fun_find = [&](RamFS::FsNode& node)
305 if (strncmp(node.GetName(), prefix_start, prefix_len) == 0)
311 return ErrorCode::OK;
315 dir->Foreach(foreach_fun_find);
321 else if (number == 1)
323 auto name_len = strlen(ans_node->GetName());
324 for (
size_t i = 0; i < name_len - prefix_len; i++)
326 DisplayChar(ans_node->GetName()[i + prefix_len]);
334 auto foreach_fun_show = [&](RamFS::FsNode& node)
336 if (strncmp(node.GetName(), prefix_start, prefix_len) == 0)
338 auto name_len = strlen(node.GetName());
339 write_stream_ << ConstRawData(node.GetName(), name_len);
341 if (ans_node ==
nullptr)
344 shared_prefix_len = name_len;
345 return ErrorCode::OK;
348 for (
size_t i = 0; i < name_len; i++)
350 if (node.GetName()[i] != ans_node->GetName()[i])
352 shared_prefix_len = i;
359 if (shared_prefix_len > name_len)
361 shared_prefix_len = name_len;
367 return ErrorCode::OK;
370 dir->Foreach(foreach_fun_show);
373 write_stream_ << ConstRawData(&input_line_[0], input_line_.Size());
375 for (
size_t i = 0; i < shared_prefix_len - prefix_len; i++)
377 DisplayChar(ans_node->GetName()[i + prefix_len]);