2013-03-12 411 views
2

我試圖用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

回答

5

目的是實現~[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