标题可能听起来有点奇怪,ps aux
我看到了:
root 20953 0.0 0.0 9528 1280 ? Ss Apr28 0:07 sendmail: accepting connections
其中“接受连接”就像是sendmail进程的标题。它不是一个参数,因为cat /proc/20953/cmdline
返回sendmail: accepting connections
(空格而不是0x00):
# cat /proc/20953/cmdline |hexdump -C
00000000 73 65 6e 64 6d 61 69 6c 3a 20 61 63 63 65 70 74 |sendmail: accept|
00000010 69 6e 67 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 |ing connections|
0000001f
/ proc fs中的参数用空字节分隔:
# cat /proc/26511/cmdline |hexdump -C
00000000 2f 62 69 6e 2f 62 61 73 68 00 2f 77 65 62 72 6f |/bin/bash./webro|
00000010 6f 74 2f 70 72 6f 72 61 69 6c 2f 73 63 72 69 70 |ot/prorail/scrip|
00000020 74 73 2f 73 79 6e 63 6c 6f 6f 70 2e 73 68 00 |ts/syncloop.sh.|
0000002f
因此,当我在C中执行fork()时,如何设置此进程信息,以便我可以识别哪个进程是什么?
答案 0 :(得分:4)
sendmail有多种方式,具体取决于系统中的sendmail / conf.c中的system.see setproctitle:
#define SPT_NONE 0 /* don't use it at all */
#define SPT_REUSEARGV 1 /* cover argv with title information */
#define SPT_BUILTIN 2 /* use libc builtin */
#define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */
#define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */
#define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */
#define SPT_SCO 6 /* write kernel u. area */
#define SPT_CHANGEARGV 7 /* write our own strings into argv[] */
有关详细信息,请参阅conf.c中的setproctitle例程。
答案 1 :(得分:0)
我找到答案here虽然问题不是同一个问题。所有积分都应转到Chris Jester-Young
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
strcpy(argv[0], "Hello, world!");
sleep(10);
return 0;
}
答案 2 :(得分:0)
在本文中:setproctitle() in Linux作者解释了如何更改流程标题。我猜setproctitle是available in BSD,所以他试图为linux实现它。以下是the function
的lxc library我还没有测试过。我还没有检查它是否使用了库中的其他函数,因此代码可能不完整。随意测试并留下冥想。
/*
* Sets the process title to the specified title. Note that this may fail if
* the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
*/
int setproctitle(char *title)
{
static char *proctitle = NULL;
char buf[2048], *tmp;
FILE *f;
int i, len, ret = 0;
/* We don't really need to know all of this stuff, but unfortunately
* PR_SET_MM_MAP requires us to set it all at once, so we have to
* figure it out anyway.
*/
unsigned long start_data, end_data, start_brk, start_code, end_code,
start_stack, arg_start, arg_end, env_start, env_end,
brk_val;
struct prctl_mm_map prctl_map;
f = fopen_cloexec("/proc/self/stat", "r");
if (!f) {
return -1;
}
tmp = fgets(buf, sizeof(buf), f);
fclose(f);
if (!tmp) {
return -1;
}
/* Skip the first 25 fields, column 26-28 are start_code, end_code,
* and start_stack */
tmp = strchr(buf, ' ');
for (i = 0; i < 24; i++) {
if (!tmp)
return -1;
tmp = strchr(tmp+1, ' ');
}
if (!tmp)
return -1;
i = sscanf(tmp, "%lu %lu %lu", &start_code, &end_code, &start_stack);
if (i != 3)
return -1;
/* Skip the next 19 fields, column 45-51 are start_data to arg_end */
for (i = 0; i < 19; i++) {
if (!tmp)
return -1;
tmp = strchr(tmp+1, ' ');
}
if (!tmp)
return -1;
i = sscanf(tmp, "%lu %lu %lu %*u %*u %lu %lu",
&start_data,
&end_data,
&start_brk,
&env_start,
&env_end);
if (i != 5)
return -1;
/* Include the null byte here, because in the calculations below we
* want to have room for it. */
len = strlen(title) + 1;
proctitle = realloc(proctitle, len);
if (!proctitle)
return -1;
arg_start = (unsigned long) proctitle;
arg_end = arg_start + len;
brk_val = syscall(__NR_brk, 0);
prctl_map = (struct prctl_mm_map) {
.start_code = start_code,
.end_code = end_code,
.start_stack = start_stack,
.start_data = start_data,
.end_data = end_data,
.start_brk = start_brk,
.brk = brk_val,
.arg_start = arg_start,
.arg_end = arg_end,
.env_start = env_start,
.env_end = env_end,
.auxv = NULL,
.auxv_size = 0,
.exe_fd = -1,
};
ret = prctl(PR_SET_MM, PR_SET_MM_MAP, (long) &prctl_map, sizeof(prctl_map), 0);
if (ret == 0)
strcpy((char*)arg_start, title);
else
INFO("setting cmdline failed - %s", strerror(errno));
return ret;
}