C 如何为不同的方法以不同的名称调用相同的文件?

C 如何为不同的方法以不同的名称调用相同的文件?,c,networking,cgi,executable,C,Networking,Cgi,Executable,我最近参加了一个演讲,其中一位发言者说他使用了一个用C编写的CGI文件,由Web服务器调用,但Web服务器使用不同的名称调用该文件,CGI文件将运行不同的方法 当一个C文件被不同的名称调用时,如何让它执行不同的函数?另外,我如何将对不同名称文件的调用重新定向到此单个文件 这是可能的还是他只是自鸣得意?Unix文件系统支持硬链接和软链接的概念。要创建它们,只需键入: ln origfile newfile 要创建硬链接,或: ln -s origfile newfile 创建软链接 软链接只是

我最近参加了一个演讲,其中一位发言者说他使用了一个用C编写的CGI文件,由Web服务器调用,但Web服务器使用不同的名称调用该文件,CGI文件将运行不同的方法

当一个C文件被不同的名称调用时,如何让它执行不同的函数?另外,我如何将对不同名称文件的调用重新定向到此单个文件


这是可能的还是他只是自鸣得意?

Unix文件系统支持硬链接和软链接的概念。要创建它们,只需键入:

ln origfile newfile
要创建硬链接,或:

ln -s origfile newfile
创建软链接

软链接只是一种特殊类型的文件,其中包含另一个文件的路径。链接中的大多数操作透明地导致对目标文件进行操作

硬链接级别较低。实际上,所有文件都是从路径名到内容的链接。在Unix中,可以将多个路径名链接到同一内容。实际上,没有“原创”和“链接”,所有的都是链接。当你删除一个文件时,你只是删除了一个链接,当链接数变为零时,内容就被删除了


许多unix实用程序都使用这种技巧。由于正在运行的shell包含用于为可执行文件开票的名称,因此它的处理方式与命令行的第0个参数类似。

这是可能的,而且实际上非常常见

传递给
main
函数的
argv
数组中的第一个元素是可执行文件的“名称”。这可以是完整路径,也可以只是路径的最后一个组件,或者——如果可执行文件是通过
exec*
函数调用启动的,那么它可以是任意字符串。(Posix也允许它为空字符串,但在实践中这是非常罕见的。)

因此,没有什么可以阻止可执行文件查看
argv[0]
(首先检查以确保
argc>0
)并对其进行解析

为可执行文件引入不同名称的最典型方法是插入一个具有备用名称的文件系统链接(可以是硬链接,也可以是软链接,但对于可维护性而言,软链接更有用)


对于CGI,甚至不需要检查
argv[0]
,因为有各种有用的环境变量,包括(至少):
SCRIPT\u NAME

当web服务器调用CGI脚本时,它会在其环境中接收大量信息,让它知道如何调用它,包括:

  • SCRIPT\u NAME
    ,从文档根目录到脚本的路径
  • SCRIPT\u FILENAME
    ,指向脚本的文件系统路径(通常与
    argv[0]
    相同)
  • REQUEST\u URI
    ,浏览器请求的路径(在没有URL重写的情况下,通常类似于
    SCRIPT\u NAME
  • QUERY\u STRING
    PATH\u INFO
    ,它们包含脚本名称后面的URL参数
  • HTTP.*
    ,其中包含请求中传递的大多数HTTP头

关键是,脚本获得了很多关于如何调用它的信息。它可以使用其中任何一个来做出决定。

如果您使用不同的名称但使用相同的代码库创建可执行文件,那么您可以根据用于调用程序的可执行文件的名称使用不同的代码分支

简单示例文件:

#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;
}
然后,使用两个不同的可执行文件调用程序:

/main 1
输出:

来到main1。
而且

/main 2
输出:

来到main2。

编译两次是多余和无用的。一个简单的
cp main1 main2
或链接
ln-s main1 main2
就可以了。@alk,很好的观点。其中任何一个都能很好地回答OP的问题。对于规模大、造价高的项目,您的建议肯定更有意义。
cc test-262.c -o main1
cc test-262.c -o main2