《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.5 KiB

10 years ago
  1. #include <ulib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <dir.h>
  5. #include <file.h>
  6. #include <stat.h>
  7. #include <dirent.h>
  8. #include <unistd.h>
  9. #define printf(...) fprintf(1, __VA_ARGS__)
  10. #define BUFSIZE 4096
  11. static char
  12. getmode(uint32_t st_mode) {
  13. char mode = '?';
  14. if (S_ISREG(st_mode)) mode = '-';
  15. if (S_ISDIR(st_mode)) mode = 'd';
  16. if (S_ISLNK(st_mode)) mode = 'l';
  17. if (S_ISCHR(st_mode)) mode = 'c';
  18. if (S_ISBLK(st_mode)) mode = 'b';
  19. return mode;
  20. }
  21. static int
  22. getstat(const char *name, struct stat *stat) {
  23. int fd, ret;
  24. if ((fd = open(name, O_RDONLY)) < 0) {
  25. return fd;
  26. }
  27. ret = fstat(fd, stat);
  28. close(fd);
  29. return ret;
  30. }
  31. void
  32. lsstat(struct stat *stat, const char *filename) {
  33. printf(" [%c]", getmode(stat->st_mode));
  34. printf(" %3d(h)", stat->st_nlinks);
  35. printf(" %8d(b)", stat->st_blocks);
  36. printf(" %8d(s)", stat->st_size);
  37. printf(" %s\n", filename);
  38. }
  39. int
  40. lsdir(const char *path) {
  41. struct stat __stat, *stat = &__stat;
  42. int ret;
  43. DIR *dirp = opendir(".");
  44. if (dirp == NULL) {
  45. return -1;
  46. }
  47. struct dirent *direntp;
  48. while ((direntp = readdir(dirp)) != NULL) {
  49. if ((ret = getstat(direntp->name, stat)) != 0) {
  50. goto failed;
  51. }
  52. lsstat(stat, direntp->name);
  53. }
  54. printf("lsdir: step 4\n");
  55. closedir(dirp);
  56. return 0;
  57. failed:
  58. closedir(dirp);
  59. return ret;
  60. }
  61. int
  62. ls(const char *path) {
  63. struct stat __stat, *stat = &__stat;
  64. int ret, type;
  65. if ((ret = getstat(path, stat)) != 0) {
  66. return ret;
  67. }
  68. static const char *filetype[] = {
  69. " [ file ]",
  70. " [directory]",
  71. " [ symlink ]",
  72. " [character]",
  73. " [ block ]",
  74. " [ ????? ]",
  75. };
  76. switch (getmode(stat->st_mode)) {
  77. case '0': type = 0; break;
  78. case 'd': type = 1; break;
  79. case 'l': type = 2; break;
  80. case 'c': type = 3; break;
  81. case 'b': type = 4; break;
  82. default: type = 5; break;
  83. }
  84. printf(" @ is %s", filetype[type]);
  85. printf(" %d(hlinks)", stat->st_nlinks);
  86. printf(" %d(blocks)", stat->st_blocks);
  87. printf(" %d(bytes) : @'%s'\n", stat->st_size, path);
  88. if (S_ISDIR(stat->st_mode)) {
  89. return lsdir(path);
  90. }
  91. return 0;
  92. }
  93. int
  94. main(int argc, char **argv) {
  95. if (argc == 1) {
  96. return ls(".");
  97. }
  98. else {
  99. int i, ret;
  100. for (i = 1; i < argc; i ++) {
  101. if ((ret = ls(argv[i])) != 0) {
  102. return ret;
  103. }
  104. }
  105. }
  106. return 0;
  107. }