Mon*_*bus 6 c unix directory posix
我会继续说这是 Linux 课程介绍的家庭作业。我不会在没有自己广泛尝试的情况下发布它,并且由于我本学期是远程学生,因此无法到校园进行辅导。我需要一些帮助来找出问题所在。
本质上,作业要求我们制作一个程序,该程序的基本功能与pwdPOSIX 中的命令相同,以显示当前目录的绝对路径。我们将与 main 一起使用三个函数。我们也不要使用该getcwd命令。我会列出他们和他们的目的
inum_to_filename: 接受三个参数(要转换的 inode 编号、指向写入名称的缓冲区的指针以及缓冲区的大小)。什么都不返回。它是为了:
filename_to_inum: 接受一个参数(achar *表示文件名)。它返回相应的 inode 编号。它是为了:
display_path: 接受一个参数(来自当前工作目录的 inode)。它什么都不返回。它是为了:
filename_to_inode。inum_to_filename来查找传递给函数的 inode 的名称。使用步骤 1 中的缓冲区来存储它。display_path显示绝对路径。这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
void inum_to_filename (int inode_arg, char *pathBuffer, int size_arg) {
DIR *dir_ptr = opendir(".");
struct dirent *dirent_ptr = readdir(dir_ptr);
int counter = 0;
while (counter != 1) {
if (inode_arg == dirent_ptr->d_ino) {
strcat(pathBuffer, "/");
strcat(pathBuffer, dirent_ptr->d_name);
counter = counter + 1;
return;
} else {
dirent_ptr = readdir(dir_ptr);
}
}
closedir(dir_ptr);
}
int filename_to_inum (char *src) {
int res = 0;
struct stat info;
int result = stat(src, &info);
if (result != 0) {
fprintf(stderr, "Cannot stat ");
perror(src);
exit(EXIT_FAILURE);
} else {
res = info.st_ino;
}
return res;
}
void display_path (int ino_src) {
int bufSize = 4096;
char pathBuffer[bufSize];
int ino_prnt = filename_to_inum("..");
if (ino_src == ino_prnt) {
//print for test
inum_to_filename(ino_src, pathBuffer, bufSize);
printf("%s", pathBuffer);
return;
} else {
//print for test
chdir("..");
inum_to_filename(ino_src, pathBuffer, bufSize);
display_path(ino_prnt);
printf("%s", pathBuffer);
}
}
int main (int argc, char *argv[]) {
int c_ino = filename_to_inum(".");
display_path(c_ino);
printf("\n");
}
Run Code Online (Sandbox Code Playgroud)
截至目前,它显示“/./MyName”,其中 MyName 是我在服务器上的个人命名目录。这是我运行程序的目录。使用密码时,我返回“/home/MyName”。我不太确定我要获得正确绝对路径的下一步是什么。
该代码主要设置为以正确的顺序一次打印一个名称,因此主要问题是使用strcat()而不是strcpy(). 此外,在开始时检测您何时位于根目录也很重要;如果不这样做,/.当当前目录是根目录时,您可能会得到类似的结果(具体取决于您协调打印的方式)。
您的此版本的代码具有:
\n\n压缩了 中的循环inum_to_filename(),但还添加了错误报告。请记住,进程可以在它没有权限访问的目录中运行(它需要 setuid 程序,通常为 \xe2\x80\x94,尽管在程序启动后可以更改权限)。在这种情况下,可能无法打开..(或.)。
丢失变量count;它没有起到任何有用的作用。使用分配和测试习惯用法允许代码包含对readdir().
使用strcpy()而不是strcat().
使用 typeino_t来存储 inode 编号。用于size_t尺寸。
减少 中中间变量的数量filename_to_inum()。
注意语句体中的代码if (ino_src == ino_prnt)是针对根目录的;如果没有测试打印,它什么也做不了。
请注意,零件中的打印else是操作的主要部分,而不仅仅是测试打印。
错误检查chdir("..");
检测 中的根main()。
请注意,此代码不适合直接重写为函数,因为它会将进程的当前目录更改为/成功时的目录。
修改后的代码:
\n\n#include <assert.h>\n#include <dirent.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <unistd.h>\n\nstatic void inum_to_filename(ino_t inode_arg, char *pathBuffer, size_t size_arg)\n{\n assert(size_arg > 0);\n DIR *dir_ptr = opendir(".");\n if (dir_ptr == 0)\n {\n fprintf(stderr, "Failed to open directory \'.\' (%d: %s)\\n", errno, strerror(errno));\n exit(EXIT_FAILURE);\n }\n struct dirent *dirent_ptr;\n\n while ((dirent_ptr = readdir(dir_ptr)) != 0)\n {\n if (inode_arg == dirent_ptr->d_ino)\n {\n if (strlen(dirent_ptr->d_name) >= size_arg)\n {\n fprintf(stderr, "File name %s too long (%zu vs %zu max)\\n",\n dirent_ptr->d_name, strlen(dirent_ptr->d_name), size_arg);\n exit(EXIT_FAILURE);\n }\n strcpy(pathBuffer, dirent_ptr->d_name);\n break;\n }\n }\n\n closedir(dir_ptr);\n}\n\nstatic ino_t filename_to_inum(char *src)\n{\n struct stat info;\n\n if (stat(src, &info) != 0)\n {\n fprintf(stderr, "Cannot stat ");\n perror(src);\n exit(EXIT_FAILURE);\n }\n return info.st_ino;\n}\n\nstatic void display_path(ino_t ino_src)\n{\n size_t bufSize = 4096;\n char pathBuffer[bufSize];\n ino_t ino_prnt = filename_to_inum("..");\n\n if (ino_src == ino_prnt)\n {\n // print for test\n inum_to_filename(ino_src, pathBuffer, bufSize);\n printf("%s", "(root): /\\n");\n }\n else\n {\n // print for real\n if (chdir("..") != 0)\n {\n fprintf(stderr, "Failed to chdir to .. (%d: %s)\\n",\n errno, strerror(errno));\n }\n inum_to_filename(ino_src, pathBuffer, bufSize);\n display_path(ino_prnt);\n printf("/%s", pathBuffer);\n }\n}\n\nint main(void)\n{\n ino_t c_ino = filename_to_inum(".");\n ino_t r_ino = filename_to_inum("/");\n if (r_ino == c_ino)\n putchar(\'/\');\n else\n display_path(c_ino);\n printf("\\n");\n}\nRun Code Online (Sandbox Code Playgroud)\n\n毫无疑问还有其他方法可以解决这个问题。
\n\n警告:这让我在使用/Volumes/CRUZER/Sub-Directory记忆棒工作时感到有些悲伤。扫描时它找不到索引节点(1令人惊讶)/Volumes,我还没有弄清楚原因。我的程序之一 \xe2\x80\x94 的getpwd实现 \xe2\x80\x94 工作正常;另一个有不同的问题。我希望我能查出这一切的真相。在 Mac OS X 10.10.5 上使用 GCC 5.1.0 进行测试。
| 归档时间: |
|
| 查看次数: |
869 次 |
| 最近记录: |