⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.c

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 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 + -