📄 shell.c
字号:
/* Copyright (C) 2005 David Decotigny, Thomas Petazzoni This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <crt.h>#include <libc.h>#include <stdarg.h>#include <string.h>#include <debug.h>#include <drivers/devices.h>#include "fstest_utils.h"/** * @file shell.c * * Small shell. */static int shell_uname (int argc, char *argv[]){ printf ("SOS article 9\n"); return 0;}static void shell_ls_internal(int detailed, int recursive, int reclevel){ char tab[256], *c; int i; struct dirent * dirent; DIR * here; here = opendir("."); if (! here) return; /* Build initial tabulation */ if (recursive) { for (c = tab, i = 0 ; (i < reclevel) && (i < sizeof(tab)/2) ; i++) { *c++ = ' '; *c++ = ' '; } *c++ = '\0'; } else *tab = '\0'; while ((dirent = readdir(here)) != NULL) { char entrychar; char * entrysuffix; switch(dirent->type) { case S_IFREG: entrychar='-'; entrysuffix=""; break; case S_IFDIR: entrychar='d'; entrysuffix="/"; break; case S_IFLNK: entrychar='l'; entrysuffix="@"; break; case S_IFCHR: entrychar='c'; entrysuffix=NULL; break; default: entrychar='?'; entrysuffix="?!?"; break; } if (detailed) { struct stat stat; char target_name[SOS_FS_DIRENT_NAME_MAXLEN]; char majorminor[24]; if (lstat(dirent->name, & stat)) continue; *target_name = '\0'; if (stat.st_type == S_IFLNK) { int fd = open(dirent->name, O_RDONLY | O_NOFOLLOW); if (fd >= 0) { int len = read(fd, target_name, sizeof(target_name) - 1); if (len < 0) *target_name='\0'; else target_name[len] = '\0'; close(fd); } } else if (stat.st_type == S_IFCHR) { snprintf(majorminor, sizeof(majorminor), " %d,%d", stat.st_rdev_major, stat.st_rdev_minor); entrysuffix = majorminor; } printf("%s%c%c%c%c %lld %s%s%s%s (location=0x%llx)\n", tab, entrychar, (stat.st_access_rights&S_IRUSR)?'r':'-', (stat.st_access_rights&S_IWUSR)?'w':'-', (stat.st_access_rights&S_IXUSR)?'x':'-', stat.st_size, dirent->name, entrysuffix, (stat.st_type==S_IFLNK)?" -> ":"", target_name, stat.st_storage_location); } else printf("%s%s%s\n", tab, dirent->name, entrysuffix); /* Next iteration */ if (recursive) { int fd_here = dirfd(here); if (chdir(dirent->name)) continue; shell_ls_internal(detailed, recursive, reclevel+1); if(fchdir(fd_here)) { closedir(here); return; } } } closedir(here);}static void shell_ls(const char * path, int detailed, int recursive){ int fd_here = open(".", O_RDONLY | O_DIRECTORY); if (fd_here < 0) return; if (chdir(path)) { close(fd_here); return; } shell_ls_internal(detailed, recursive, 1); fchdir(fd_here); close(fd_here);}static int shell_touch (int argc, char *argv[]){ return creat (argv[1], S_IRUSR | S_IWUSR);}static int shell_mkdir (int argc, char *argv[]){ return mkdir (argv[1], S_IRUSR | S_IWUSR | S_IXUSR);}static int shell_cat (int argc, char *argv[]){ int fd; char buf[4096]; int len; fd = open (argv[1], O_RDONLY); if (fd < 0) { printf ("Cannot open '%s'\n", argv[1]); return -1; } while (1) { len = read (fd, buf, sizeof(buf)-1); if (len <= 0) break; buf[len] = '\0'; printf ("%s", buf); } close (fd); return 0;}static int shell_edit (int argc, char *argv[]){ int fd; char buf[16]; int len; fd = open (argv[1], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { printf ("Cannot create '%s': %d\n", argv[1], fd); return -1; } /* Activate echo and activate again canonical mode */ ioctl (0, SOS_IOCTL_TTY_SETPARAM, SOS_IOCTLPARAM_TTY_ECHO); ioctl (0, SOS_IOCTL_TTY_SETPARAM, SOS_IOCTLPARAM_TTY_CANON); while (1) { len = read (0, buf, sizeof(buf)); if (len <= 1) break; bochs_printf ("Writing %d bytes\n", len); len = write (fd, buf, len); if (len <= 0) { printf ("Cannot write to '%s': %d\n", argv[1], len); break; } } /* Desactivate echo and remove canonical mode */ ioctl (0, SOS_IOCTL_TTY_RESETPARAM, SOS_IOCTLPARAM_TTY_ECHO); ioctl (0, SOS_IOCTL_TTY_RESETPARAM, SOS_IOCTLPARAM_TTY_CANON); close (fd); return 0;}static int shell_hexdump (int argc, char *argv[]){ int fd; char buf[16]; int count = 0; int len; fd = open (argv[1], O_RDONLY); if (fd < 0) { printf ("Cannot open '%s': %d\n", argv[1], fd); return -1; } while (1) { int i; len = read (fd, buf, sizeof(buf)); if (len <= 0) break; if (count < 0x10) printf ("00%x ", count); else if (count < 0x100) printf ("0%x ", count); else if (count < 0x1000) printf ("%x ", count); for (i = 0; i < len; i++) { if (buf[i] < 0x10) printf ("0%x ", buf[i]); else printf ("%x ", buf[i]); } printf ("\n"); count += len; } close (fd); return 0;}static int shell_test (int argc, char *argv[]){ int i; for (i = 0; i < argc; i++) { printf ("argv[%d] = %s\n", i, argv[i]); } return 0;}static int shell_devtest (int argc, char *argv[]){ bochs_printf("WARNING: This test will eventually write 0 on kernel code !\n"); bochs_printf("This WILL crash the kernel (as expected...) !\n"); printf("WARNING: This test will eventually write 0 on kernel code !\n"); printf("This WILL crash the kernel (as expected...) !\n"); if (fork() == 0) exec("devtest"); return 0;}static int shell_fstest (int argc, char *argv[]){ if (fork() == 0) exec("fstest"); return 0;}void command_exec (char * cmd){ char *c; int argc = 1, i; char **argv; for (c = cmd; *c != '\0'; c++) if (*c == ' ') argc++; argv = malloc (argc * sizeof(char*)); if (argv == NULL) return; for (i = 0, c = cmd; i < argc; i++) { argv[i] = c; while (*c != ' ' && *c != '\0') c++; *c = '\0'; c++; } if (! strcmp (argv[0], "uname")) shell_uname(argc, argv); else if (! strcmp (argv[0], "ls")) { if (argv[1]) shell_ls (argv[1], 1, 0); else shell_ls (".", 1, 0); } else if (! strcmp (argv[0], "touch")) { shell_touch (argc, argv); } else if (! strcmp (argv[0], "mkdir")) { shell_mkdir (argc, argv); } else if (! strcmp (argv[0], "cat")) { shell_cat (argc, argv); } else if (! strcmp (argv[0], "edit")) { shell_edit (argc, argv); } else if (! strcmp (argv[0], "hexdump")) { shell_hexdump (argc, argv); } else if (! strcmp (argv[0], "test")) { shell_test (argc, argv); } else if (! strcmp (argv[0], "devtest")) { shell_devtest (argc, argv); } else if (! strcmp (argv[0], "fstest")) { shell_fstest (argc, argv); } else printf ("Command not found\n"); free (argv);}int main(){ char buffer[256]; int i; char chr; ioctl (0, SOS_IOCTL_TTY_RESETPARAM, SOS_IOCTLPARAM_TTY_CANON); while (1) { memset (buffer, 0, sizeof(buffer)); i = 0; printf ("$ "); while (1) { read (0, & chr, 1); if (chr == '\n') { buffer[i] = '\0'; printf ("\n"); if (i != 0) command_exec (buffer); break; } else if (chr == '\b') { if (i > 0) { i--; printf ("\b"); } } else if (i < 256) { buffer[i++] = chr; printf ("%c", chr); } else printf ("%c", chr); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -