[nginx源码分析]set process title
2016-07-30 18:43
489 查看
由于linux argv和environ环境变量内存地址连续,同时argv[0]代表进程name,所以就可以尽可能的用连续的内存空间(起始地址argv[0])来设置进程name
test case如下:
testcase 根据的是nginx设置进程为master or worker process的做法,nginx的code 如下:
也是先copy environ到新的地址空间,用连续的内存空间来设置进程title
test case如下:
*/ #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <unistd.h> #define LOGDBG(fmt, args...) do {\ printf("[%s:%d]%s "fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args);\ }while(0); extern char **environ; int main(int argc, char** argv) { uint32_t i = 0; uint32_t env_size = 0; for (; environ[i];i++) { env_size += strlen(environ[i])+1;//\0 char LOGDBG("environ[i]=%s", environ[i]); } LOGDBG("env_size:%u", env_size); char* env = (char*) malloc(env_size); char* temp = env; for(i = 0; environ[i]; i++) { snprintf(temp, strlen(environ[i])+1, "%s", environ[i]); environ[i] = temp; temp += strlen(environ[i])+1; } char* last = environ[i]-1; argv[1] = NULL; snprintf(argv[0], last - argv[0], "%s", "set title"); for (i=0; environ[i];i++) { LOGDBG("environ[i]=%s", environ[i]); } sleep(10); return 0; }
testcase 根据的是nginx设置进程为master or worker process的做法,nginx的code 如下:
extern char **environ; static char *ngx_os_argv_last; ngx_int_t ngx_init_setproctitle(ngx_log_t *log) { u_char *p; size_t size; ngx_uint_t i; size = 0; //首先计算出environ需要的内存空间 for (i = 0; environ[i]; i++) { size += ngx_strlen(environ[i]) + 1; } //为environ分配内存空间 p = ngx_alloc(size, log); if (p == NULL) { return NGX_ERROR; } ngx_os_argv_last = ngx_os_argv[0]; //check连续性 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; } } //copy environ到新分配的内存 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; } } ngx_os_argv_last--; return NGX_OK; } void ngx_setproctitle(char *title) { u_char *p; #if (NGX_SOLARIS) ngx_int_t i; size_t size; #endif //先把argv数组的第二个节点置为空 ngx_os_argv[1] = NULL; //copy p = ngx_cpystrn((u_char *) ngx_os_argv[0], (u_char *) "nginx: ", ngx_os_argv_last - ngx_os_argv[0]); p = ngx_cpystrn(p, (u_char *) title, ngx_os_argv_last - (char *) p); #if (NGX_SOLARIS) size = 0; for (i = 0; i < ngx_argc; i++) { size += ngx_strlen(ngx_argv[i]) + 1; } if (size > (size_t) ((char *) p - ngx_os_argv[0])) { /* * ngx_setproctitle() is too rare operation so we use * the non-optimized copies */ p = ngx_cpystrn(p, (u_char *) " (", ngx_os_argv_last - (char *) p); for (i = 0; i < ngx_argc; i++) { p = ngx_cpystrn(p, (u_char *) ngx_argv[i], ngx_os_argv_last - (char *) p); p = ngx_cpystrn(p, (u_char *) " ", ngx_os_argv_last - (char *) p); } if (*(p - 1) == ' ') { *(p - 1) = ')'; } } #endif if (ngx_os_argv_last - (char *) p) { ngx_memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - (char *) p); } ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "setproctitle: \"%s\"", ngx_os_argv[0]); } #endif /* NGX_SETPROCTITLE_USES_ENV */
也是先copy environ到新的地址空间,用连续的内存空间来设置进程title
相关文章推荐
- PsSetCreateProcessNotifyRoutine函数和源码分析
- Nginx源码分析 - Event事件篇 - Event模块的进程初始化ngx_event_process_init
- nginx源码分析(3)- 自动脚本
- nginx源码分析(5)-方法(2)
- nginx源码分析-链表
- Nginx源码分析-进程管理之worker进程
- Nginx源码分析-进程管理之master进程
- Nginx源码分析-启动初始化过程(二)
- nginx源码分析(1)- 缘起
- Nginx源码分析-connections数组
- nginx源码分析
- Nginx源码分析-master和worker进程间的通信
- nginx源码分析(6)-模块化(1)
- nginx源码分析(11)-进程启动分析(1)
- nginx源码分析(2)- 概览
- nginx源码分析(16)-模块分析(2)
- nginx源码分析(4)-方法(1)
- nginx源码分析(9)-模块化(4)
- nginx源码分析(13)-运维与配置(1)
- Nginx源码分析-启动初始化过程(一)