Linux 内核 由fd获得文件名

fd 不是唯一的,只是进程打开文件的index. 利用current->files + fd 可获得文件名

{

struct file *ftmp = NULL;

struct fdtable *fdt = NULL;

fdt = (struct fdtable *)files_fdtable(current->files);

ftmp = fdt->fd[fd];

if ((ftmp->f_path.dentry != NULL) &&

(ftmp->f_path.dentry->d_iname != NULL)) {

printk("p %s\n", ftmp->f_path.dentry->d_iname);

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于编写一个完整的Linux内核的shell命令行解释程序需要较长的时间和精力,这里我提供一个简单的C程序,可以实现用户输入命令并执行,支持“&”操作符作为命令的结束符、重定向stdin和stdout描述符,以及管道操作符“|”来同时执行两个进程并重定向。 ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #define MAX_ARGS 10 #define MAX_LINE 80 int main() { char line[MAX_LINE]; // 存储用户输入的命令行 char *args[MAX_ARGS]; // 存储解析后的命令行参数 int should_run = 1; // 控制程序是否继续运行 int bg_flag = 0; // 判断是否使用“&”操作符作为命令的结束符 int in_flag = 0; // 判断是否使用“<”作为文件名前缀来重定向stdin描述符 int out_flag = 0; // 判断是否使用“>”作为文件名前缀来重定向stdout描述符 int pipe_flag = 0; // 判断是否使用“|”来同时执行两个进程并重定向 while (should_run) { printf("osh> "); fflush(stdout); // 读取用户输入的命令行 fgets(line, MAX_LINE, stdin); // 将命令行按空格分割成多个参数 char *token; int i = 0; token = strtok(line, " \n"); while (token != NULL) { args[i] = token; i++; token = strtok(NULL, " \n"); } args[i] = NULL; // 判断是否使用“&”操作符作为命令的结束符 if (i > 0 && strcmp(args[i-1], "&") == 0) { bg_flag = 1; args[i-1] = NULL; } // 判断是否使用“<”作为文件名前缀来重定向stdin描述符 for (int j = 0; j < i; j++) { if (strcmp(args[j], "<") == 0) { in_flag = 1; args[j] = NULL; freopen(args[j+1], "r", stdin); break; } } // 判断是否使用“>”作为文件名前缀来重定向stdout描述符 for (int j = 0; j < i; j++) { if (strcmp(args[j], ">") == 0) { out_flag = 1; args[j] = NULL; freopen(args[j+1], "w", stdout); break; } } // 判断是否使用“|”来同时执行两个进程并重定向 for (int j = 0; j < i; j++) { if (strcmp(args[j], "|") == 0) { pipe_flag = 1; // 将第一个进程的stdout重定向到管道写端 int fd[2]; pipe(fd); pid_t pid = fork(); if (pid == 0) { close(fd[0]); dup2(fd[1], STDOUT_FILENO); execvp(args[0], args); } // 将第二个进程的stdin重定向到管道读端 char *args2[MAX_ARGS]; int k = 0; args2[k] = strtok(args[j+1], " \n"); while (args2[k] != NULL) { k++; args2[k] = strtok(NULL, " \n"); } args2[k] = NULL; pid_t pid2 = fork(); if (pid2 == 0) { close(fd[1]); dup2(fd[0], STDIN_FILENO); execvp(args2[0], args2); } // 等待两个进程执行完毕 close(fd[0]); close(fd[1]); waitpid(pid, NULL, 0); waitpid(pid2, NULL, 0); break; } } // 如果没有使用“|”来同时执行两个进程并重定向,则直接执行命令 if (!pipe_flag) { pid_t pid = fork(); if (pid == 0) { execvp(args[0], args); } if (!bg_flag) { waitpid(pid, NULL, 0); } } // 重置标志位 bg_flag = 0; in_flag = 0; out_flag = 0; pipe_flag = 0; } return 0; } ``` 在shell中,可以使用以下命令进行编译和运行: ```bash $ gcc shell.c -o shell $ ./shell ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值