C - /proc/pid/exe 上的 Lstat

2024-01-24

我正在尝试使用 lstat 获取 /proc/pid/exe 文件的大小(以字节为单位)。这是我的代码:

int     main(int argc, char *argv[]) 
{   
 struct stat    sb;
 char       *linkname;
 ssize_t    r;

  if (argc != 2) 
  {
    fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  if (lstat(argv[1], &sb) == -1) 
  {
    perror("lstat");
    exit(EXIT_FAILURE);
  }

  printf("sb.st_size %d\n", sb.st_size);   

  exit(EXIT_SUCCESS);
}

似乎 sb.st_size 总是等于 0,我不明白为什么。另外,该示例是从 readlink(2) 手册页中提取的。

Edit:我正在尝试让它在 openSUSE 上运行。

预先感谢您的帮助。


文件在/proc http://man7.org/linux/man-pages/man5/proc.5.html不是普通文件。对于他们中的大多数人来说,stat() http://man7.org/linux/man-pages/man2/stat.2.html等人。返回.st_size == 0.

尤其,/proc/PID/exe并不是真正的符号链接或硬链接,而是一个特殊的伪文件,其行为mostly就像符号链接一样。

(如果需要,您可以检测 procfs 文件,检查.st_dev场地。相比于.st_dev从...获取lstat("/proc/self/exe",..), 例如。)

要根据 PID 获取特定可执行文件的路径,我推荐一种依赖于返回值的方法readlink() http://man7.org/linux/man-pages/man2/readlink.2.html反而:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

/* Creative Commons CC0: Public Domain dedication
 * (In jurisdictions without public domain, this example program
 *  is licensed under the Creative Commons CC0 license.)
 *
 * To the extent possible under law, Nominal Animal has waived all
 * copyright and related or neighboring rights to this example program.
 *
 * In other words, you are free to use it in any way you wish,
 * but if it breaks something, you get to keep all the pieces.
*/

/** exe_of() - Obtain the executable path a process is running
 * @pid: Process ID
 * @sizeptr: If specified, the allocated size is saved here
 * @lenptr: If specified, the path length is saved here
 * Returns the dynamically allocated pointer to the path,
 * or NULL with errno set if an error occurs.
*/
char *exe_of(const pid_t pid, size_t *const sizeptr, size_t *const lenptr)
{
    char   *exe_path = NULL;
    size_t  exe_size = 1024;
    ssize_t exe_used;
    char    path_buf[64];
    int     path_len;

    path_len = snprintf(path_buf, sizeof path_buf, "/proc/%ld/exe", (long)pid);
    if (path_len < 1 || path_len >= sizeof path_buf) {
        errno = ENOMEM;
        return NULL;
    }

    while (1) {

        exe_path = malloc(exe_size);
        if (!exe_path) {
            errno = ENOMEM;
            return NULL;
        }

        exe_used = readlink(path_buf, exe_path, exe_size - 1);
        if (exe_used == (ssize_t)-1)
            return NULL;

        if (exe_used < (ssize_t)1) {
            /* Race condition? */
            errno = ENOENT;
            return NULL;
        }

        if (exe_used < (ssize_t)(exe_size - 1))
            break;

        free(exe_path);
        exe_size += 1024;
    }

    /* Try reallocating the exe_path to minimum size.
     * This is optional, and can even fail without
     * any bad effects. */
    {
        char *temp;

        temp = realloc(exe_path, exe_used + 1);
        if (temp) {
            exe_path = temp;
            exe_size = exe_used + 1;
        }
    }

    if (sizeptr)
        *sizeptr = exe_size;

    if (lenptr)
        *lenptr = exe_used;

    exe_path[exe_used] = '\0';
    return exe_path;
}

int main(int argc, char *argv[])
{
    int   arg;
    char *exe;
    long  pid;
    char  dummy;

    if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
        printf("\n");
        printf("Usage: %s [ -h | --help ]\n", argv[0]);
        printf("       %s PID [ PID ... ]\n", argv[0]);
        printf("\n");
        return 0;
    }

    for (arg = 1; arg < argc; arg++)
        if (sscanf(argv[arg], " %ld %c", &pid, &dummy) == 1 && pid > 0L) {
            exe = exe_of((pid_t)pid, NULL, NULL);
            if (exe) {
                printf("Process %ld runs '%s'.\n", pid, exe);
                free(exe);
            } else
                printf("Process %ld: %s.\n", pid, strerror(errno));
        } else {
            printf("%s: Invalid PID.\n", argv[arg]);
            return 1;
        }

    return 0;
}

上面,exe_of()函数返回伪符号链接所在位置的动态分配副本/proc/PID/exe指向,也可以选择存储分配的大小和/或路径长度。 (上面的示例程序不需要它们,所以它们是 NULL。)

这个想法非常简单:分配一个初始动态指针,该指针对于大多数情况来说足够大,但又不会大得离谱。保留最后一个字节作为字符串结尾 NUL 字节。如果返回的大小为readlink() http://man7.org/linux/man-pages/man2/readlink.2.html与给定的缓冲区长度相同——它本身不添加终止字符串结尾 NUL 字节——那么缓冲区可能太短;丢弃它,分配更大的缓冲区,然后重试。

同样,如果您想读取下面的伪文件的完整内容/proc/,你不能使用lstat()/stat()首先找出您可能需要多大的缓冲区;您需要分配一个缓冲区,尽可能多地读取,并在必要时重新分配更大的缓冲区。 (我也可以展示示例代码。)

问题?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C - /proc/pid/exe 上的 Lstat 的相关文章

  • 在 LINQ 查询中返回不带时间的日期

    我正在编写一个查询 我想计算按日期联系我们的呼叫中心的次数 看起来很简单 但由于联系日期字段是日期时间字段 我得到了时间 因此当我按联系日期 时间 分组时 每个联系日期实例的计数为 1 所以 我想只按日期分组 而不按时间分组 下面是我用来查
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 模板类的不明确多重继承

    我有一个真实的情况 可以总结为以下示例 template lt typename ListenerType gt struct Notifier void add listener ListenerType struct TimeListe
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 像“1$”这样的位置参数如何与 printf() 一起使用?

    By man I find printf d width num and printf 2 1 d width num 是等价的 但在我看来 第二种风格应该与以下相同 printf d num width 然而通过测试似乎man是对的 为什
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • C 中的位移位

    如果与有符号整数对应的位模式右移 则 1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is impleme
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐

  • 如何从这段代码中绘制控制流图?

    int main int i grade 0 printf Enter points n scanf d i if i gt 50 i lt 60 grade 5 else if i gt 50 i lt 60 grade 6 else i
  • 根据用户限制字​​段的选择

    我希望表单仅在 ChoiceField 中显示当前用户的帐户 我尝试执行以下操作 但它不起作用 编辑 抱歉 我忘记提及我添加的 if kwargs 因为 TransForm 没有显示任何字段 我想这是错误的 但我不知道其他方法 视图 py
  • MySQL 无法连接到使用 Rubber 部署的 EC2

    我正在使用 ruby 来部署 Rails 应用程序 但在连接到 MySQL 时遇到问题 我是否必须在 EC2 上手动设置 MySQL 还是 Rubber 应该已经这样做了 虽然这并不是很有帮助 但以下是运行 rake 时的日志输出 out
  • 设置 时 POST 请求失败

    考虑以下情况 Web 服务器正在运行 NET 应用程序
  • 通过命令行替换 pom.xml 中的 Maven 属性

    我想替换 Maven 属性pom xml通过某些 Maven 插件使用命令行调用文件
  • 调用另一个对象的触摸开始iOS

    假设我有 view1 正在拦截触摸事件 而 view2 则没有 view1 可以将这些事件传递给 view2 并调用 view2 TouchesBegin view2 TouchMoved 等吗 是的 有时 也许 您所询问的技术被称为事件转
  • 有没有办法在 C# 中继续异常?

    当您的程序 在调试器中 发生意外异常时 有时您只想跳过它 因为此时终止程序比继续运行更有害 或者您只是想继续 因为您对另一个错误 错误更感兴趣 是否有选项 编译器标志 秘密开关来启用此功能 我知道应该立即解决异常 但在某些情况下 就像我所描
  • 如何使内联ckeditor工具栏固定在顶部而不是浮动

    我在我的页面中使用内联 CKEditor 我想将其固定在 contenteditable div 的顶部 目前 每当我滚动页面时它就会浮动 如何让工具栏位置固定在顶部 结合使用内联编辑器和共享空间 http ckeditor com add
  • 如何将模块添加到我的 SystemJs 配置文件中,以便我可以以角度导入它

    如何使用 SystemJS 和此 system config js 文件将我刚刚从 npm 下载的新包添加到我的 Angular 2 组件中 下面的代码是由入门包为我生成的 我尝试将模块的链接放在该文件的地图和包部分中 但它似乎不起作用 我
  • d3.js 如何从 csv 或表生成树层次结构

    我有一个包含以下数据的 csv world country state World US CA World US NJ World INDIA OR World INDIA AP 我需要转换为树层次结构 如下所示 name World ch
  • 在 Rails 中显示 404 而不是 500

    在我的 Rails 应用程序中 我定义了路线 以便用户可以访问类似的记录http mydomain com qwe2 http mydomain com qwe2 但如果他们输入错误的 qwe2 他们会得到 500 页 我认为404会更合适
  • 从文本文件的行范围中删除 \n 字符

    假设我们有一个 1000 行的文本文件 我们如何删除第20行到第500行的新行字符 例如用空格替换它们 My try sed 20 500p N s n better not to say anything 所有其他行 1 19 501 1
  • 如何在没有 MANIFEST.in 文件的情况下包含 package_data?

    我怎样才能包括package data for sdist没有 MANIFEST in 文件 我的 setup py 看起来像这样 import setuptools setuptools setup name foo version 20
  • “MEIPASS”代表什么?

    PyInstaller 设置sys MEIPASS属性让应用程序知道在哪里可以找到其捆绑的资源 来源 这个答案 https stackoverflow com q 7674790 119527 我知道什么 MEIPASS does 名字是什
  • SQL 日期范围分割

    你能告诉我当日期范围重叠时分割日期范围的 SQL 吗 数据 具有日期范围和可能的其他列的示例数据 Col1 FromDate ToDate 1 1 1 1 2008 31 12 2010 2 1 1 1 2009 31 12 2012 3
  • 更改 UIButton 内的 SF 符号大小

    我声明一个这样的按钮 let menuButton UIButton 之后 我尝试更改它的参数并在 LBTATools 一个 pod 的帮助下通过以下函数设置他在视图上的位置 fileprivate func setMenuButtonUI
  • 如何使用 SimpleMembership 获取角色?

    我正在使用 SimpleMembership 开发 MVC4 应用程序 我有一个表 userInfo 其中存储用户的信息 例如姓名 电子邮件 地址 电话 角色等 当我注册用户时 数据存储在该表和webpages Membership 中 其
  • Three.js 立方体黑色但我添加了纹理?

    我尝试向使用 JS THREE JS 制作的立方体添加纹理 但是当我在浏览器中打开它时 它全黑了 这是我的代码
  • 如何使用 MongoDB compass 删除 MongoDB 集合中选定的多条记录

    我对 MongoDB 和 MongoDB Compass 非常陌生 我的客户集合中有大约 1000 条记录 如何通过 MongoDB compass 一次删除所有记录 非常感谢 您可以使用 MongoDB compass 提供的 Embed
  • C - /proc/pid/exe 上的 Lstat

    我正在尝试使用 lstat 获取 proc pid exe 文件的大小 以字节为单位 这是我的代码 int main int argc char argv struct stat sb char linkname ssize t r if