создание функции дерева в xv6 - PullRequest
0 голосов
/ 08 мая 2020

Я хочу создать команду tree в xv6, если вы не знаете, что дерево должно отображать каталоги на терминале. Я знаю, что это, вероятно, легко для вас, но код пока что

#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"
#include "fs.h"
#include "file.h"

int
main(int argc, char *argv[])
{
      if(argc < 2){
        printf(2, "Usage: tree [path]...\n");
        exit();
      }
      tree(argv[1]);


      int fd = open(argv[1],O_RDONLY);
      if(fd<0)
          return -1;

     struct dirent dir;

      while(read(fd,&dir,sizeof(dir))!=0){
          printf(1,"|_ %d,%d",dir.name,dir.inum);
          //struct stat *st;
          struct inode ip;
          ip= getinode(dir.inum);
          if(ip.type==T_DIR){
              int i;
              for(i=0;i<NDIRECT;i++ ){
                  uint add=ip.addrs[i];
                  printf(1,"%d",add);
              }
          }
      }

  return 0;
}

, и он выдает мне многочисленные ошибки на терминале, первая из которых file.h:17:20: error: field ‘lock’ has incomplete type struct sleeplock lock; // protects everything below here ^~~~

Я ищу для sleeplock и ничего подобного в коде нет. Что не так с кодом? Спасибо за помощь

1 Ответ

0 голосов
/ 10 мая 2020

Вы не можете использовать заголовки ядра (например, file.h) в пользовательском коде. Чтобы использовать функции ядра в своем коде, вы должны использовать системные вызовы.

Чтобы добиться желаемого, вы можете начать с функции ls и сделать ее рекурсивной.

Один пример, сделанный быстро:

  • Я добавил параметр к функции ls, чтобы отображать глубину сканирования
  • и вызывать себя для каждого элемента каталога, кроме двух первых: . и ..


void
ls(char *path, int decal)
{
    char buf[512], *p;
    int fd, i, skip = 2;
    struct dirent de;
    struct stat st;

    if((fd = open(path, 0)) < 0){
        printf(2, "tree: cannot open %s\n", path);
        return;
    }

    if(fstat(fd, &st) < 0){
        printf(2, "tree: cannot stat %s\n", path);
        close(fd);
        return;
    }

    switch(st.type){
        case T_FILE:
            for (i = 0; i < decal; i++)
                printf(1, " ");
            printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size);
            break;

        case T_DIR:
            if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
                printf(1, "tree: path too long\n");
                break;
            }
            strcpy(buf, path);
            p = buf+strlen(buf);
            *p++ = '/';
            while(read(fd, &de, sizeof(de)) == sizeof(de)){
                if(de.inum == 0)
                    continue;
                memmove(p, de.name, DIRSIZ);
                p[DIRSIZ] = 0;
                if(stat(buf, &st) < 0){
                    printf(1, "tree: cannot stat %s\n", buf);
                    continue;
                }
               for (i = 0; i < decal; i++)
                    printf(1, " ");

                printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
                if (skip)
                    skip--;
                else 
                    ls(buf, decal+1);
            }
            break;
    }
    close(fd);
}
...