【发布时间】:2014-09-25 18:07:36
【问题描述】:
我最近参加了一个演讲,其中一位演讲者说他使用了一个用 C 语言编写的 CGI 文件,该文件由网络服务器调用,但网络服务器使用不同的名称调用该文件,即 CGI 文件将运行不同的方法。
如何让一个 C 文件在被不同名称调用时执行不同的函数?另外,我如何将不同命名文件的调用重定向回这个单个文件?
这可能还是他只是自满?
【问题讨论】:
标签: c networking cgi executable
我最近参加了一个演讲,其中一位演讲者说他使用了一个用 C 语言编写的 CGI 文件,该文件由网络服务器调用,但网络服务器使用不同的名称调用该文件,即 CGI 文件将运行不同的方法。
如何让一个 C 文件在被不同名称调用时执行不同的函数?另外,我如何将不同命名文件的调用重定向回这个单个文件?
这可能还是他只是自满?
【问题讨论】:
标签: c networking cgi executable
如果您创建具有不同名称但具有相同代码库的可执行文件,则可以根据用于调用程序的可执行文件的名称采用不同的代码分支。
简单示例文件:
#include <stdio.h>
#include <string.h>
int main1(int argc, char** argv)
{
printf("Came to main1.\n");
return 0;
}
int main2(int argc, char** argv)
{
printf("Came to main2.\n");
return 0;
}
int main(int argc, char** argv)
{
// If the program was invoked using main1, go to main1
if (strstr(argv[0], "main1") != NULL )
{
return main1(argc-1, argv+1);
}
// If the program was invoked using main2, go to main2
if (strstr(argv[0], "main2") != NULL )
{
return main2(argc-1, argv+1);
}
// Don't know what to do.
return -1;
}
从文件中创建两个不同的可执行文件。
cc test-262.c -o main1
cc test-262.c -o main2
然后,使用两个不同的可执行文件调用程序:
./main1
输出:
Came to main1.
还有……
./main2
输出:
Came to main2.
【讨论】:
cp main1 main2 或链接ln -s main1 main2 就可以了。
Unix 文件系统支持硬链接和软链接的概念。要创建它们,只需键入:
ln origfile newfile
创建硬链接,或:
ln -s origfile newfile
创建软链接。
软链接只是一种特殊的文件,它包含另一个文件的路径。链接中的大多数操作都会透明地导致对目标文件的操作。
硬链接是较低级别的。实际上,所有文件都是从路径名到内容的链接。在 Unix 中,您可以将多个路径名链接到相同的内容。实际上,没有“原创”和“链接”,都是链接。当您删除一个文件时,您只是删除了一个链接,当链接计数变为零时,内容将被删除。
许多 unix 实用程序都可以做到这一点。由于正在运行的 shell 包含用于调用可执行文件的名称,因此它的处理方式与命令行的第 0 个参数一样。
【讨论】:
当 Web 服务器调用 CGI 脚本时,它会在其环境中接收大量信息以告知其调用方式,包括:
SCRIPT_NAME,从文档根目录到脚本的路径SCRIPT_FILENAME,脚本的文件系统路径(通常与argv[0]相同)REQUEST_URI,浏览器请求的路径(通常类似于SCRIPT_NAME,在没有URL重写的情况下)QUERY_STRING 和 PATH_INFO,在脚本名称之后包含 URL 参数HTTP_*,其中包含请求中传递的大部分 HTTP 标头重点是,脚本会获取很多关于它是如何被调用的信息。它可能会使用其中任何一个来做出决定。
【讨论】:
这是可能的,实际上很常见。
argv 数组中传递给main 函数的第一个元素是可执行文件的“名称”。这可以是完整路径,也可以只是路径的最后一个组成部分,或者 -- 如果可执行文件以 exec* 函数调用启动,则它可以是任意字符串。 (而且 Posix 也允许它是一个空字符串,但实际上这种情况非常罕见。)
所以没有什么可以阻止可执行文件查看argv[0](首先检查以确保argc > 0)并对其进行解析。
为可执行文件引入不同名称的最典型方法是插入具有备用名称的文件系统链接(可以是硬链接或软链接,但为了便于维护,软链接更有用。)
对于 CGI,甚至不需要检查 argv[0],因为有各种有用的环境变量,包括(至少):SCRIPT_NAME。
【讨论】: