这个文件接口实现没什么好说的,作用是实现修改进程名称,目的是显示argv[0]和地址,端口号。
代码路径: https://github.com/antirez/redis/blob/2.8/src/setproctitle.c
细节点:
1. environ和argv的内存布局:
基本所有的修改进程名称的处理,目标都是修改这两个指针指向的内存内容,先看这两块内存的布局图,了解了这两个指针指向的内容,基本对修改进程名称的原理也就行处了。参考[1][2]:
[1]:
the stack of a C program on an i386 machine looks like the following (going up from low addresses):
...
local variables of main
saved registers of main
return address of main
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
[2]
2. clearenv()的使用:
这个函数简单的描述就是 [3]上写的:
The clearenv() function clears the environment of all name-value pairs and sets the value of the external variable environ to NULL.
redis的实现上,先使用oldenv保存environ指向的地址,然后调用clearenv后,environ为NULL,但oldenv指向的内容依然有效(这个很重要,environ原来指向的内容并没有清空),这时再把oldenv解析,调用setenv函数。
疑问:
1. spt_copyenv和set_copyargs具体起什么作用?我感觉只是简单的复制。
2. 程序中复制一份新的program_invocation_name的内容,是避免原地址的数据被修改和跨平台使用吗?
这两个问题已得到解答,应该是重新分配空间,把原指针指向新的地址,这样当对argv[0]执行了snprintf后,即使新的内容长度超过了原有argv[0]的长度,原有的指针指向的内容也是有效的。