2014-10-30 80 views
4

我試圖在linux下更改正在運行的進程的名稱。在C中,我只是修改argv[0]就地,但我怎麼能從haskell做到這一點?我注意到,GHC有一種原始的名爲getProgArgv如何在Linux下更改haskell進程的名稱

foreign import ccall unsafe "getProgArgv" 
    getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO() 

但我想與和它沒有工作。此外,我知道prctl(PR_SET_NAME,"...")但只改變當前線程的名稱,並且大多數工具(如pshtop)不使用該名稱。

回答

1

好的,所以我想出了一個看似工作的醜陋黑客。它基於從here借來的想法。我們必須使用一個輔助的C文件:

#include <string.h> 
#include <sys/prctl.h> 

char *argv0 = 0; 

static void capture_argv0(int argc, char *argv[]) { 
    argv0 = argv[0]; 
} 
__attribute__((section(".init_array"))) void (*p_capture_argv0)(int, char*[]) = &capture_argv0; 

void set_prog_name(char *name) { 
    if (!argv0) return; 
    size_t len = strlen(argv0); 
    strncpy(argv0, name, len); 
    prctl(PR_SET_NAME, name); 
} 

這依賴於section(".init_array")屬性,告訴GCC登記capture_argv0爲初始化函數。這意味着它將在main之前執行。我們用它來製作argv[0]指針的副本並將其存儲爲全局變量。現在我們可以從haskell中調用set_prog_name