C Unix的线程安全路径比较或规范化函数?

C Unix的线程安全路径比较或规范化函数?,c,unix,C,Unix,我见过一些古老的代码,它们通过执行以下伪代码简化了Unix路径以进行比较: 剥离最后一个路径组件以获取仅目录部分:/foo/bar->/foo 获取cwd并记住原始路径 chdir/foo getcwd并记住返回调用方 旧原始路径 是否有一个标准的Unix系统函数可以在没有线程不安全的当前目录操作的情况下执行所有这些操作 互斥可以减少代码序列的线程不安全性,但这并不理想(您必须知道,使用getcwd或其他依赖于进程cwd的函数的所有其他代码,包括系统和供应商代码,都使用相同的互斥来保护)。哦

我见过一些古老的代码,它们通过执行以下伪代码简化了Unix路径以进行比较:

  • 剥离最后一个路径组件以获取仅目录部分:/foo/bar->/foo
  • 获取cwd并记住原始路径
  • chdir/foo
  • getcwd并记住返回调用方
  • 旧原始路径
是否有一个标准的Unix系统函数可以在没有线程不安全的当前目录操作的情况下执行所有这些操作


互斥可以减少代码序列的线程不安全性,但这并不理想(您必须知道,使用getcwd或其他依赖于进程cwd的函数的所有其他代码,包括系统和供应商代码,都使用相同的互斥来保护)。

哦,天哪,执行您提到的操作不可能是线程安全的,因为它实际上是chdir的,这会混淆其他线程。我必须查找您想要的字符串操作部分,但它也不可能剥离软链接或执行任何其他需要向操作系统询问文件信息的操作,而不会有一点线程不安全

相关职位:

尝试转换相对文件路径,然后将其作为字符串进行比较:

#include<stdio.h>
#include<dirent.h>
#include<fcntl.h>
#include<sys/param.h>
int main( int argc, char **argv )
{
  char buffer[MAXPATHLEN+1];
  if( argc <= 1 ) return 0;
  DIR*d = opendir( argv[1] );
  if( !d ) return 0;
  int dfd = dirfd(d);
  if( !dfd ) return 0;
  int result = fcntl( dfd, F_GETPATH, buffer );
  if( result == -1 ) return 0;
  fprintf( stdout, "path='%s'\n", buffer );
  return 0;
}
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
字符缓冲区[MAXPATHLEN+1];

如果(argc哦,亲爱的,执行您提到的操作不可能是线程安全的,因为它实际上是chdir的,这会混淆任何其他线程。我必须查找您想要的字符串操作部分,但它也不可能剥离软链接或做任何其他需要向操作系统请求文件信息的事情没有一点线程不安全的离子

相关职位:

尝试转换相对文件路径,然后将其作为字符串进行比较:

#include<stdio.h>
#include<dirent.h>
#include<fcntl.h>
#include<sys/param.h>
int main( int argc, char **argv )
{
  char buffer[MAXPATHLEN+1];
  if( argc <= 1 ) return 0;
  DIR*d = opendir( argv[1] );
  if( !d ) return 0;
  int dfd = dirfd(d);
  if( !dfd ) return 0;
  int result = fcntl( dfd, F_GETPATH, buffer );
  if( result == -1 ) return 0;
  fprintf( stdout, "path='%s'\n", buffer );
  return 0;
}
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
字符缓冲区[MAXPATHLEN+1];
如果(argc尝试
realpath()
规范化文件名()

如果您的系统支持它(它可能支持),我建议调用
realpath(pathname,NULL)
;这将
malloc
规范化文件名的缓冲区,并将其作为返回值传回。您必须确保
free()
指针。另一种方法是传入一个输出缓冲区,这样会有缓冲区溢出的风险

canonicalize\u file\u name()
是一个Gnu扩展名,相当于
realpath(pathname,NULL)

尝试
realpath()
规范化\u file\u name()

如果您的系统支持它(它可能支持),我建议调用
realpath(pathname,NULL)
;这将
malloc
规范化文件名的缓冲区,并将其作为返回值传回。您必须确保
free()
指针。另一种方法是传入一个输出缓冲区,这样会有缓冲区溢出的风险

canonicalize\u file\u name()
是一个Gnu扩展名,相当于
realpath(pathname,NULL)

Unix目录中没有“规范”路径。一个文件/目录可能有多个硬链接/装载点

最接近文件/目录标识的是其inode。

Unix目录中没有“规范”路径。文件/目录可能有多个硬链接/装入点

与文件/目录的标识最接近的是它的inode。

怎么办

由于它在您提供的缓冲区中返回其结果,因此线程安全不应该是一个问题。

怎么办


由于它在您提供的缓冲区中返回其结果,因此线程安全不应该是一个问题。

我知道它不是线程安全的。如果存在这样一个函数,我确信它必须是一个系统调用,可以以更直接、更理智的方式进行查找。看起来像是其他人为此发布了一个快捷方式,但我怀疑它是在幕后进行此操作的:-)我知道它不是线程安全的。如果存在这样一个函数,我肯定它必须是一个系统调用,可以以更直接、更理智的方式进行查找。看起来像是其他人为此发布了一个快捷方式,但我怀疑它是在幕后实现的:-)我曾经知道realpath()并忘记了它。原因是它没有用处(因此不值得纪念的是)它在某些平台上也不是线程安全的(基本上使用了所描述的busted chdir'ing机制)。嗯。我确实在我们的代码中看到了对该函数的调用。也许它现在在我们关心的所有平台上都是线程安全的(几年前肯定不是这种情况,但我不记得具体细节)。我曾经知道realpath()并忘记了它。它没有用处(因此也不值得纪念)的原因是它在某些平台上也不是线程安全的(基本上使用了所描述的busted chdir'ing机制)。嗯。我确实在我们的代码中看到了对该函数的调用。也许它现在在我们关心的所有平台上都是线程安全的(几年前肯定不是这种情况,但我不记得具体细节)。请注意,在
PATH_MAX
太大而无法
malloc()的系统上,传入输出缓冲区只会有缓冲区溢出的风险
或完全无界。请注意,在
PATH\u MAX
太大而无法
malloc()
或完全无界的系统上,传入输出缓冲区只会有缓冲区溢出的风险。