使用'__progname'代替argv [0]

Leo*_*ard 17 c unix double-underscore

在我工作的C/Unix环境中,我看到一些开发人员使用__progname而不是argv[0]使用消息.这有什么好处吗?__progname和之间的区别是什么argv[0].它是便携式的吗?

Eva*_*ran 18

__progname不是标准的,因此不便携,更喜欢argv[0].我想__progname可以查找一个字符串资源来获取名称,该名称不依赖于您运行它的文件名.但是argv[0]会给你他们实际运行的名称,我觉得它更有用.

  • 考虑:execl("/ bin/sh","hot potato"," - c","echo $ 0 - Hi",(char*)0); 工作良好; argv [0]是"热土豆"; 回应"热土豆 - 嗨".这与运行的可执行文件的名称无关. (3认同)
  • 尽管之前的评论 - 我同意argv [0]更便携.并且只有少数程序像argv [0]那样混乱 - 但任何攻击者都可以这样做.关于argv [0]的关键决策是否谨慎. (2认同)

Ada*_*iss 8

使用__progname允许您argv[]在保持程序名称的同时更改阵列的内容.一些常用工具,例如在处理参数时进行getopt()修改argv[].

为了便于携带,您可以在程序启动时strcopy argv[0]进入自己的progname缓冲区.

  • @Jonathan:是的,谢谢你的澄清.我GNU我一直坚持使用一个平台.(抱歉.) (3认同)
  • GNU getopt() 与 argv 混淆;非 GNU 版本通常不这样做。 (2认同)

Vic*_*ian 6

还有一个GNU扩展,因此可以从main()外部访问程序调用名称,而无需手动保存.但是,人们可能会手动做得更好; 从而使其可移植而不是依赖于GNU扩展.不过,我在这里提供了可用文档的摘录.

在线GNU C Library手册(今天访问):

"许多没有从终端读取输入的程序被设计为在任何系统调用失败时退出.按照惯例,来自这样程序的错误消息应该从程序名称开始,没有目录.你可以在变量中找到该名称program_invocation_short_name;完整的文件名存储在变量中program_invocation_name.

  • 变量:char*program_invocation_name 此变量的值是用于调用当前进程中运行的程序的名称.它是一样的argv[0].请注意,这不一定是有用的文件名; 通常它不包含目录名称.

  • 变量:字符*program_invocation_short_name 这个变量的值是用来调用程序运行在当前进程,去掉目录名的名称.(也就是说,它与program_invocation_name减去最后一个斜线的所有内容相同,如果有的话.)

库初始化代码在调用main之前设置这两个变量.

可移植性注意:这两个变量是GNU扩展.如果希望程序与非GNU库一起使用,则必须保存argv[0]main中的值,然后自己剥离目录名称.我们添加了这些扩展,以便编写自包含错误报告子程序,而不需要主要的显式合作."


小智 5

我看到argv [0]至少存在两个潜在问题。

首先,如果execve()调用者有恶意或粗心大意,则argv [0]或argv本身可能为NULL。调用execve(“ foobar”,NULL,NULL)通常是一种简单有趣的方法,可以证明过度自信的程序员的代码不符合sig11标准。

还必须注意的是,argv不会在main()之外定义,而__progname通常被定义为可以在您的usage()函数内部甚至在调用main()之前使用的全局变量(例如非标准GCC构造函数) 。

  • 但是,“严格符合POSIX应用程序的要求,至少将一个参数传递给exec函数,从而保证当此类应用程序调用时argc为一个或更大。” 当然,没有人会故意违反POSIX!(http://www.opengroup.org/onlinepubs/000095399/functions/exec.html) (2认同)