PostgreSQL的 initdb 源代码分析之一
开始第一段:
int main(int argc, char *argv[]) { /* * options with no short version return a low integer, the rest return * their short version value */ static struct option long_options[] = { {"pgdata", required_argument, NULL, 'D'}, {"encoding", required_argument, NULL, 'E'}, {"locale", required_argument, NULL, 1}, {"lc-collate", required_argument, NULL, 2}, {"lc-ctype", required_argument, NULL, 3}, {"lc-monetary", required_argument, NULL, 4}, {"lc-numeric", required_argument, NULL, 5}, {"lc-time", required_argument, NULL, 6}, {"lc-messages", required_argument, NULL, 7}, {"no-locale", no_argument, NULL, 8}, {"text-search-config", required_argument, NULL, 'T'}, {"auth", required_argument, NULL, 'A'}, {"pwprompt", no_argument, NULL, 'W'}, {"pwfile", required_argument, NULL, 9}, {"username", required_argument, NULL, 'U'}, {"help", no_argument, NULL, '?'}, {"version", no_argument, NULL, 'V'}, {"debug", no_argument, NULL, 'd'}, {"show", no_argument, NULL, 's'}, {"noclean", no_argument, NULL, 'n'}, {"xlogdir", required_argument, NULL, 'X'}, {NULL, 0, NULL, 0} }; int c,i,ret; int option_index; char *effective_user; char *pgdenv; /* PGDATA value gotten from and sent to * environment */ char bin_dir[MAXPGPATH]; char *pg_data_native; int user_enc; #ifdef WIN32 char *restrict_env; #endif static const char *subdirs[] = { "global", "pg_xlog", "pg_xlog/archive_status", "pg_clog", "pg_notify", "pg_serial", "pg_subtrans", "pg_twophase", "pg_multixact/members", "pg_multixact/offsets", "base", "base/1", "pg_tblspc", "pg_stat_tmp" }; progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb")); ......
}
上述程序部分运行后,get_progname的返回值是:
progname ----------initdb
而我传递给 get_progname的参数 argv[0] 是 : /home/pgsql/project/bin/initdb
再来看 set_pglocale_pgservice函数:
此时传递的第一个参数是: /home/pgsql/project/bin/initdb 传递的第二个参数是:initdb-9.1
由于 set_pglocale_pgservice 也会被postgres进程所调用,所以需要第二个参数来明确调用者。
/* * set_pglocale_pgservice * * Set application-specific locale and service directory * * This function takes the value of argv[0] rather than a full path. * * (You may be wondering why this is in exec.c. It requires this module's * services and doesn't introduce any new dependencies, so this seems as * good as anyplace.) */ void set_pglocale_pgservice(const char *argv0, const char *app) { char path[MAXPGPATH]; char my_exec_path[MAXPGPATH]; char env_path[MAXPGPATH + sizeof("PGSYSCONFDIR=")]; /* longer than * PGLOCALEDIR */ /* don't set LC_ALL in the backend */ if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0) setlocale(LC_ALL, ""); if (find_my_exec(argv0, my_exec_path) < 0) return; #ifdef ENABLE_NLS get_locale_path(my_exec_path, path); bindtextdomain(app, path); textdomain(app); if (getenv("PGLOCALEDIR") == NULL) { /* set for libpq to use */ snprintf(env_path, sizeof(env_path), "PGLOCALEDIR=%s", path); canonicalize_path(env_path + 12); putenv(strdup(env_path)); } #endif if (getenv("PGSYSCONFDIR") == NULL) { get_etc_path(my_exec_path, path); /* set for libpq to use */ snprintf(env_path, sizeof(env_path), "PGSYSCONFDIR=%s", path); canonicalize_path(env_path + 13); putenv(strdup(env_path)); } }
实际上,运行时,得到的
my_exec_path : /home/pgsql/project/bin/initdb
env_path : PGSYSCONFDIR=/home/pgsql/project/etc