[nginx源码分析]set process title

来源:互联网 发布:navicat输入sql语句 编辑:程序博客网 时间:2024/06/06 17:10

由于linux argv和environ环境变量内存地址连续,同时argv[0]代表进程name,所以就可以尽可能的用连续的内存空间(起始地址argv[0])来设置进程name
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_tngx_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;}voidngx_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

0 0
原创粉丝点击