BSD 中可以用 setproctitle() system call 改变进程名,但是 Linux 没有这样的 system call. 当用 ps or top 查看时能看到改变之后的进程名。 #include stdio.h#include stdlib.h#include string.h#include unistd.h#inclu
BSD 中可以用 setproctitle() system call 改变进程名,但是 Linux 没有这样的 system call.
当用 ps or top查看时能看到改变之后的进程名。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <sys/user.h>
extern char **environ;
int main(int argc, char **argv)
{
char proc_pid_cmdline_path[PATH_MAX]; // PATH_MAX = 4096
char proctitle[PAGE_SIZE]; // PAGE_SIZE = 1UL << 12, 即 2^12 = 4k
FILE *proc_pid_cmdline = NULL; // /proc/<pid>/cmdline
pid_t pid;
int envlen, envsize, size, i;
char *tmp = NULL;
/* get file path */
pid = getpid();
sprintf(proc_pid_cmdline_path, "/proc/%d/cmdline", pid);
/* get process title(name) */
proc_pid_cmdline = fopen(proc_pid_cmdline_path, "r");
fgets(proctitle, PAGE_SIZE, proc_pid_cmdline);
fclose(proc_pid_cmdline);
printf("%s : %s\nHOME = %s\n", proc_pid_cmdline_path, proctitle, getenv("HOME"));
/* get environ list length */
envlen = -1;
while (environ[++envlen])
{
envsize += strlen(environ[envlen]);
};
/**
* size of environ list + size of argv list
* environ[0] list is just after argv[0]
*/
if (envlen > 0)
{
// printf("environ[0] - argv[0]: %d\n", environ[0] - argv[0]);
envsize = environ[envlen-1] + strlen(environ[envlen-1]) - argv[0];
}
else
{
envsize = argv[argc-1] + strlen(argv[argc-1]) - argv[0];
}
// printf("size: %d\n", size);
tmp = (char *) malloc(envsize);
/* copy environ list to a new area */
for (i = 0; environ[i]; i++)
{
size = strlen(environ[i]) + 1;
memcpy(tmp, environ[i], size);
environ[i] = tmp;
tmp = environ[i] + size;
}
/**
* now, the command line argument list can use the space of the old environ list
*/
tmp = argv[0];
memset(tmp, '\0', envsize);
snprintf(tmp, envsize - 1, "This is a new title and it should be definetely longer than initial one. Actually we can write %d bytes long string to the title. Well, it works!", envsize);
proc_pid_cmdline = fopen(proc_pid_cmdline_path, "r");
fgets(proctitle, PAGE_SIZE, proc_pid_cmdline);
fclose(proc_pid_cmdline);
printf("%s : %s\nHOME = %s\n", proc_pid_cmdline_path, proctitle, getenv("HOME"));
sleep(10);
return 0;
}
/*
$ ./a.out
/proc/11100/cmdline : ./a.out
HOME = /home/hwx
/proc/11100/cmdline : This is a new title and it should be definetely longer than initial one. Actually we can write 2763 bytes long string to the title. Well, it works!
HOME = /home/hwx
$ ps aux
hwx 11200 0.0 0.0 1972 472 pts/1 S+ 15:37 0:00 This is a new title and it should be definetely longer than initial one. Actually we can write 2763 bytes
*/
References
http://stupefydeveloper.blogspot.com/2008/10/linux-change-process-name.html
关于 command line arguments 和 environment variables 在内存中的布局见 TLPI