Linux 进程名修改
/* 进程名修改 */ #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--;