c - C - 在这里调用 getcwd 会导致错误吗?
问题描述
我正在学习 stat 和 readlink 之类的系统调用。我尝试以两种不同的方式统计根目录:
- 只需统计root的路径。简单的。
- 然后,一个迂回的方式,fopen“/”,从我得到的 fd 中创建一个文件描述符路径,并读取链接它以获得“/”。然后统计。
我不明白这是我期望的工作方式,并且 inode 编号是相同的,除了当我在之后引入更多代码时,即 getcwd,inode 奇怪地不一样并且测试 2 失败。如果您同时运行这两个版本,无论有没有它说要删除的部分,p2 的 printf 也会发生变化,您可以看到/
. 我在这里做错了什么或这里发生了什么?这些初始语句之后的代码是如何导致代码更早发生变化的?
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
int main()
{
/* Stat root this way */
struct stat st1;
char *p1 = "/";
if (!stat(p1, &st1))
printf("PASS\n");
else
printf("FAIL - %m\n");
/* Stat root another way */
struct stat st2;
char fdpath[100], p2[100];
FILE *fp = fopen("/", "r");
sprintf(fdpath, "/proc/self/fd/%d", fileno(fp));
readlink(fdpath, p2, sizeof(p2));
if (!stat(p2, &st2))
printf("PASS\n");
else
printf("FAIL - %m\n");
printf("p2 = %s\n", p2);
/* Check inodes are the same */
printf(" st1.st_ino = %ld\n", st1.st_ino);
printf(" st2.st_ino = %ld\n", st2.st_ino);
/* TRY WITHOUT THIS - Adding this makes the inodes different! Take it out and they're the same */
char cwd_buf[100];
char *cwd_ret = getcwd(cwd_buf, sizeof(cwd_buf));
if (cwd_ret == NULL)
printf("getcwd failed - %m\n");
printf("cwd_ret = %s\n", cwd_ret);
return 0;
}
解决方案
从手册页:
readlink() 将符号链接路径名的内容放在缓冲区 buf 中,缓冲区大小为 bufsiz。 readlink() 不会将空字节附加到 buf。 如果缓冲区太小而无法容纳所有内容,它将(默默地)截断内容(到 bufsiz 字符的长度)。
因此,如果要p2
用作字符串,则需要手动执行:
int size = readlink(fdpath, p2, sizeof(p2) - 1);
if (size < 0)
{
// error
}
p2[size] = 0;
注意 -1: 应该为空终止符保留一个字节,即使字符串被截断。
推荐阅读
- javascript - Preact 错误 - 对象不支持属性或方法“平面”
- saml-2.0 - 注销抛出证书无效签名
- javascript - VS Code 代码格式化 JavaScript 不正确
- javascript - 尝试使用枚举属性从 History 对象中提取状态时遇到 Typescript 错误
- azure - 如何将 AddAzureWebAppDiagnostics 与 IFunctionsHostBuilder 一起使用
- php - TCPDF:如何计算并在一页上放置适当的块,然后从表格开始
- selenium - Webdriver 页面源未更改
- javascript - 为什么这段代码同时使用 useMemo 和 createSelector?
- python - 使用命名参数从 Node.js (child_process) 运行 python 脚本
- wpf - 如何使用 VB.NET 区分 SHDocVw.InternetExplorer 和 SHDocVw.WebBrowser_v1?