2014-10-30 50 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