/* 进程名修改 */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
/*
知识补充:
Linux C中environ 变量是一个char** 类型,存储着系统的环境变量。
因为environ是一个全局的外部变量,所以切记使用前要用extern关键字进行声明,然后在使用。
unistd.h头文件中声明了这个变量,所以也可以将unistd.h进行include,这个时候就不用再对environ进行extern声明了(应为unistd.h中已经声明了),
要注意的问题是,在unistd.h中声明environ的地方使用了条件编译,编译的条件就是#ifdef __USE_GNU,LinuxC中默认没有定义这个宏,
所以要在#include <unistd.h>之前加上#define __USE_GNU
*/
extern char** environ;
/*
知识补充:
在linux上修改进程名需要设置argv[1]为NULL,并且拷贝进程名到argv[0]指向的内存空间上。
然而argv[0]的内存空间可能不够存放新的进程名,幸运的是Linux存储argv[] and environ[]用的是一块连续内存。
因此我们可以分配一块新内存拷贝environ[],之后我们就可以安全的拷贝进程名到argv[0]上了。
*/
static char* gtc_os_argv_last;
int gtc_init_setproctitle(char* argv[])
{
int ret = 0;
/*
设计说明:
初始化是为了保证修改进程名的安全,
gtc_os_argv_last变量实际上是指向当前进程可以修改进程名的最大长度
*/
unsigned char * p;
size_t size;
unsigned int i;
size = 0;
// 计算环境变量的长度
for (i = 0; environ[i]; i++) {
size += strlen(environ[i]) + 1;
}
// 创建内存,用来保存当前进程的环境变量
p = calloc(1, size);
if (NULL == p)
{
ret = -1;
return ret;
}
// 从命令行参数开始计数
gtc_os_argv_last = argv[0];
for (i = 0; argv[i]; i++) {
// 遍历命令行参数
if (gtc_os_argv_last == argv[i]) {
// gtc_os_argv_last指向下一个命令行参数
gtc_os_argv_last = argv[i] + strlen(argv[i]) + 1;
}
}
// 遍历环境变量
for (i = 0; environ[i]; i++) {
if (gtc_os_argv_last == environ[i]) {
size = strlen(environ[i]) + 1;
gtc_os_argv_last = environ[i] + size;
strncpy((char*)p, environ[i], size);
// 修改environ的元素指向,原来environ的元素可能会被 gtc_setproctitle 函数破坏
environ[i] = (char*)p;
p += size;
}
}
// 保留最后一个字节为'\0'
gtc_os_argv_last--;
return ret;
}
void gtc_setproctitle(const char* title, char* argv[])
{
argv[1] = NULL;
// 修改进程名
strncpy(argv[0], title, gtc_os_argv_last - argv[0]);
}
int main(int argc, char* argv[])
{
const char* title = "Blue bird";
// 初始化
gtc_init_setproctitle(argv);
// 等待输入
printf("Please enter a character to change the process name.\n");
getchar();
// 修改进程名
gtc_setproctitle(title, argv);
printf("The process name has changed, please observe.\n");
getchar();
return 0;
}
![]()
![]()
![]()
/*
知识补充:
ngx_os_argv, environ 是一个字符串数组,数组元素是字符串指针
这两个变量的元素指向的内存空间是连续的
ngx_os_argv, environ 这两个变量的内存空间不是连续的
*/
ngx_os_argv_last = ngx_os_argv[0];
for (i = 0; ngx_os_argv[i]; i++) {
if (ngx_os_argv_last == ngx_os_argv[i]) {
ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1;
}
}
for (i = 0; environ[i]; i++) {
if (ngx_os_argv_last == environ[i]) {
size = ngx_strlen(environ[i]) + 1;
ngx_os_argv_last = environ[i] + size;
ngx_cpystrn(p, (u_char *) environ[i], size);
environ[i] = (char *) p;
p += size;
}
}
// 保存最后一个字符,存放'\0'
ngx_os_argv_last--;