将Unix移植到Windows-使用pwd.h

问题描述:

我试图用MinGW编译libUnihan代码,但遇到了需要移植的函数。该函数的目的是获得规范的路径表示。它使用pwd.h(这是POSIX,MinGW不是),所以它可以通过检索包含pw_dirpasswd结构来说明使用'〜'来表示主目录。我确实发现了一些信息here,以及一个端口realpathhere,但是我仍然完全不知道如何处理这个问题。使用MinGW,我仍然有一个主目录,代表~,位于/home/nate,但由于它不是POSIX,因此我没有pwd.h来帮助我找到此主目录的位置。将Unix移植到Windows-使用pwd.h

问:如何将以下功能移植到MinGW上以正常工作?

/** 
* Return the canonicalized absolute pathname. 
* 
* It works exactly the same with realpath(3), except this function can handle the path with ~, 
* where realpath cannot. 
* 
* @param path The path to be resolved. 
* @param resolved_path Buffer for holding the resolved_path. 
* @return resolved path, NULL is the resolution is not sucessful. 
*/ 
gchar* 
truepath(const gchar *path, gchar *resolved_path){ 
    gchar workingPath[PATH_MAX]; 
    gchar fullPath[PATH_MAX]; 
    gchar *result=NULL; 
    g_strlcpy(workingPath,path,PATH_MAX); 

//  printf("*** path=%s \n",path); 

    if (workingPath[0] != '~'){ 
     result = realpath(workingPath, resolved_path); 
    }else{ 
     gchar *firstSlash, *suffix, *homeDirStr; 
     struct passwd *pw; 

     // initialize variables 
     firstSlash = suffix = homeDirStr = NULL; 

    firstSlash = strchr(workingPath, DIRECTORY_SEPARATOR); 
     if (firstSlash == NULL) 
      suffix = ""; 
     else 
     { 
      *firstSlash = 0; // so userName is null terminated 
      suffix = firstSlash + 1; 
     } 

     if (workingPath[1] == '\0') 
      pw = getpwuid(getuid()); 
     else 
      pw = getpwnam(&workingPath[1]); 

     if (pw != NULL) 
      homeDirStr = pw->pw_dir; 

     if (homeDirStr != NULL){ 
     gint ret=g_sprintf(fullPath, "%s%c%s", homeDirStr, DIRECTORY_SEPARATOR, suffix); 
     if (ret>0){ 
     result = realpath(fullPath, resolved_path); 
     } 

    } 
    } 
    return result; 
} 
+0

请注意,'〜'本身意味着'$ HOME'环境变量的值,对于当前用户而言,通常但不一定与'〜user'相同。后者是密码文件中的信息。 – 2013-03-13 00:34:10

目的是实现~[username]/重新映射逻辑。这种代码在Linux/UNIX环境中很有意义,但最常见的用途是引用用户自己的主目录。

为了方便起见,我只是增加对常见情况的支持 - 即当前用户,并且不打算支持更一般的情况 - 让它在这种情况下出现明显错误而失败。

获取当前用户主目录的功能是SHGetFolderPath

#include <windows.h> 

char homeDirStr[MAX_PATH]; 
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, homeDirStr))) { 
    // Do something with the path 
} else { 
    // Do something else 
} 

在用户的查找失败的情况下,你贴的代码不会尝试替换字符串,但只是返回NULL,所以你可以效仿这一点。

+0

抛出一些编译错误;我通过什么而不是CSIDL_PERSONAL? – 2013-03-13 00:49:38

+0

对于那个变量IIRC,这应该也是'#include '。返回的路径是一个Windows路径,我认为需要转换(不是在Windows系统上检查它是否可用) – Petesh 2013-03-13 00:53:17

+0

除非我缺少一些东西,'realpath'也不在mingw中。 – Petesh 2013-03-13 01:23:03