先观察/daemon/gdm-daemon-config-keys.h中代码:
/* BEGIN LEGACY KEYS */
#define GDM_KEY_CHOOSER "daemon/Chooser=" LIBEXECDIR "/gdmchooser"
#define GDM_KEY_AUTOMATIC_LOGIN_ENABLE "daemon/AutomaticLoginEnable=false"
#define GDM_KEY_AUTOMATIC_LOGIN "daemon/AutomaticLogin="
说明是根据这个头文件来定义custom.conf中对应的自动登录配置。
gdm.c开始调用。
gdm.c
int main (int argc, char *argv[])
CODE:
/* Init XDMCP if applicable */
if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP) && ! gdm_wait_for_go) {
gdm_xdmcp_init ();
}
create_connections ();
/* make sure things (currently /tmp/.ICE-unix and /tmp/.X11-unix)
* are sane */
gdm_ensure_sanity () ;
/* Make us a unique global cookie to authenticate */
gdm_make_global_cookie ();
/* Start static X servers */
gdm_start_first_unborn_local (0 /* delay */); // 登录开始
/* Accept remote connections */
if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP) && ! gdm_wait_for_go) {
g_debug ("Accepting XDMCP connections...");
gdm_xdmcp_run ();
}
/* We always exit via exit (), and sadly we need to g_main_quit ()
* at times not knowing if it's this main or a recursive one we're
* quitting.
*/
while (1)
{
g_main_loop_run (main_loop);
g_debug ("main: Exited main loop");
}
return EXIT_SUCCESS; /* Not reached */ // 登录完成!
->
gdm.c
static void gdm_start_first_unborn_local (int delay);
->
display.c
gboolean gdm_display_manage (GdmDisplay *d);
->
display.c
void gdm_slave_start (GdmDisplay *d); // 通过"/sbin/runlevel"得到运行级别
->
slave.c
static void gdm_slave_run (GdmDisplay *display);
CODE: // 判断是否自动登录,并获得登录账户
const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN);
const char *timedlogin = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN);
if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) &&
! ve_string_empty (automaticlogin)) {
g_free (ParsedAutomaticLogin);
ParsedAutomaticLogin = gdm_slave_parse_enriched_login (display,
automaticlogin);
}
if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) &&
! ve_string_empty (timedlogin)) {
g_free (ParsedTimedLogin);
ParsedTimedLogin = gdm_slave_parse_enriched_login (display,
timedlogin);
}
CODE: // 如果为自动登录直接调用gdm_slave_session_start ()函数
if ( ! d->handled) {
/* yay, we now wait for the server to die */
while (d->servpid > 0) {
pause ();
}
gdm_slave_quick_exit (DISPLAY_REMANAGE);
} else if (d->use_chooser) {
/* this usually doesn't return */
gdm_slave_chooser (); /* Run the chooser */
return;
} else if (d->type == TYPE_STATIC &&
gdm_first_login &&
! ve_string_empty (ParsedAutomaticLogin) &&
strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) {
gdm_first_login = FALSE;
d->logged_in = TRUE;
gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin);
if (setup_automatic_session (d, ParsedAutomaticLogin)) {
gdm_slave_session_start ();
}
gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
d->logged_in = FALSE;
gdm_slave_send_string (GDM_SOP_LOGIN, "");
logged_in_uid = -1;
logged_in_gid = -1;
gdm_debug ("gdm_slave_run: Automatic login done");
if (remanage_asap) {
gdm_slave_quick_exit (DISPLAY_REMANAGE);
}
/* return to gdm_slave_start so that the server
* can be reinitted and all that kind of fun stuff. */
return;
}
->
slave.c
static void gdm_slave_session_start (void);// 获取用户ID,组ID。
CODE: // 通过 $HOME/.dmrc 设定用户语言,键盘,以及Session。
if G_LIKELY (home_dir_ok) {
/* Sanity check on ~user/.dmrc */
usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid,
home_dir, ".dmrc", TRUE, FALSE,
gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM));
} else {
usrcfgok = FALSE;
}
if G_LIKELY (usrcfgok) {
gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess);
} else {
/* This won't get displayed if the .dmrc file simply doesn't
* exist since we pass absentok=TRUE when we call gdm_file_check
*/
gdm_errorgui_error_box (d,
GTK_MESSAGE_WARNING,
_("User's $HOME/.dmrc file is being ignored. "
"This prevents the default session "
"and language from being saved. File "
"should be owned by user and have 644 "
"permissions. User's $HOME directory "
"must be owned by user and not writable "
"by other users."));
usrsess = g_strdup ("");
usrlang = g_strdup ("");
}
CODE: // 调用登录子函数。
switch (pid) {
case -1:
gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start");
case 0:
{
const char *lang;
gboolean has_language;
has_language = (language != NULL) && (language[0] != '\0');
if ((gdm_system_locale != NULL) && (!has_language)) {
lang = gdm_system_locale;
} else {
lang = language;
}
if G_LIKELY (logfilefd >= 0) {
VE_IGNORE_EINTR (close (logpipe[0]));
}
/* Never returns */
session_child_run (pwent,
logpipe[1],
failsafe,
home_dir,
home_dir_ok,
#ifdef WITH_CONSOLE_KIT
ck_session_cookie,
#endif
session,
save_session,
lang,
gnome_session,
usrcfgok,
savesess,
savelang);
g_assert_not_reached ();
}
->
slave.c
static void session_child_run (struct passwd *pwent,
int logfd,
gboolean failsafe,
const char *home_dir,
gboolean home_dir_ok,
#ifdef WITH_CONSOLE_KIT
const char *ck_session_cookie,
#endif
const char *session,
const char *save_session,
const char *language,
const char *gnome_session,
gboolean usrcfgok,
gboolean savesess,
gboolean savelang)
CODE: // session最终设定
/* Prepare user session */
g_setenv ("XAUTHORITY", d->userauth, TRUE);
g_setenv ("DISPLAY", d->name, TRUE);
if (d->windowpath)
g_setenv ("WINDOWPATH", d->windowpath, TRUE);
g_setenv ("LOGNAME", pwent->pw_name, TRUE);
g_setenv ("USER", pwent->pw_name, TRUE);
g_setenv ("USERNAME", pwent->pw_name, TRUE);
g_setenv ("HOME", home_dir, TRUE);
#ifdef WITH_CONSOLE_KIT
if (ck_session_cookie != NULL) {
g_setenv ("XDG_SESSION_COOKIE", ck_session_cookie, TRUE);
}
#endif
g_setenv ("PWD", home_dir, TRUE);
g_setenv ("GDMSESSION", session, TRUE);
g_setenv ("DESKTOP_SESSION", session, TRUE);
g_setenv ("SHELL", pwent->pw_shell, TRUE);
CODE: // 语言最终设定
if ( ! ve_string_empty (language)) {
g_setenv ("LANG", language, TRUE);
g_setenv ("GDM_LANG", language, TRUE);
}
/* just in case there is some weirdness going on */
VE_IGNORE_EINTR (g_chdir (home_dir));
if (usrcfgok && home_dir_ok)
gdm_daemon_config_set_user_session_lang (savesess, savelang, home_dir, save_session, language);
->
登录完成!
/* BEGIN LEGACY KEYS */
#define GDM_KEY_CHOOSER "daemon/Chooser=" LIBEXECDIR "/gdmchooser"
#define GDM_KEY_AUTOMATIC_LOGIN_ENABLE "daemon/AutomaticLoginEnable=false"
#define GDM_KEY_AUTOMATIC_LOGIN "daemon/AutomaticLogin="
说明是根据这个头文件来定义custom.conf中对应的自动登录配置。
gdm.c开始调用。
gdm.c
int main (int argc, char *argv[])
CODE:
/* Init XDMCP if applicable */
if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP) && ! gdm_wait_for_go) {
gdm_xdmcp_init ();
}
create_connections ();
/* make sure things (currently /tmp/.ICE-unix and /tmp/.X11-unix)
* are sane */
gdm_ensure_sanity () ;
/* Make us a unique global cookie to authenticate */
gdm_make_global_cookie ();
/* Start static X servers */
gdm_start_first_unborn_local (0 /* delay */); // 登录开始
/* Accept remote connections */
if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP) && ! gdm_wait_for_go) {
g_debug ("Accepting XDMCP connections...");
gdm_xdmcp_run ();
}
/* We always exit via exit (), and sadly we need to g_main_quit ()
* at times not knowing if it's this main or a recursive one we're
* quitting.
*/
while (1)
{
g_main_loop_run (main_loop);
g_debug ("main: Exited main loop");
}
return EXIT_SUCCESS; /* Not reached */ // 登录完成!
->
gdm.c
static void gdm_start_first_unborn_local (int delay);
->
display.c
gboolean gdm_display_manage (GdmDisplay *d);
->
display.c
void gdm_slave_start (GdmDisplay *d); // 通过"/sbin/runlevel"得到运行级别
->
slave.c
static void gdm_slave_run (GdmDisplay *display);
CODE: // 判断是否自动登录,并获得登录账户
const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN);
const char *timedlogin = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN);
if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) &&
! ve_string_empty (automaticlogin)) {
g_free (ParsedAutomaticLogin);
ParsedAutomaticLogin = gdm_slave_parse_enriched_login (display,
automaticlogin);
}
if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) &&
! ve_string_empty (timedlogin)) {
g_free (ParsedTimedLogin);
ParsedTimedLogin = gdm_slave_parse_enriched_login (display,
timedlogin);
}
CODE: // 如果为自动登录直接调用gdm_slave_session_start ()函数
if ( ! d->handled) {
/* yay, we now wait for the server to die */
while (d->servpid > 0) {
pause ();
}
gdm_slave_quick_exit (DISPLAY_REMANAGE);
} else if (d->use_chooser) {
/* this usually doesn't return */
gdm_slave_chooser (); /* Run the chooser */
return;
} else if (d->type == TYPE_STATIC &&
gdm_first_login &&
! ve_string_empty (ParsedAutomaticLogin) &&
strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) {
gdm_first_login = FALSE;
d->logged_in = TRUE;
gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin);
if (setup_automatic_session (d, ParsedAutomaticLogin)) {
gdm_slave_session_start ();
}
gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
d->logged_in = FALSE;
gdm_slave_send_string (GDM_SOP_LOGIN, "");
logged_in_uid = -1;
logged_in_gid = -1;
gdm_debug ("gdm_slave_run: Automatic login done");
if (remanage_asap) {
gdm_slave_quick_exit (DISPLAY_REMANAGE);
}
/* return to gdm_slave_start so that the server
* can be reinitted and all that kind of fun stuff. */
return;
}
->
slave.c
static void gdm_slave_session_start (void);// 获取用户ID,组ID。
CODE: // 通过 $HOME/.dmrc 设定用户语言,键盘,以及Session。
if G_LIKELY (home_dir_ok) {
/* Sanity check on ~user/.dmrc */
usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid,
home_dir, ".dmrc", TRUE, FALSE,
gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM));
} else {
usrcfgok = FALSE;
}
if G_LIKELY (usrcfgok) {
gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess);
} else {
/* This won't get displayed if the .dmrc file simply doesn't
* exist since we pass absentok=TRUE when we call gdm_file_check
*/
gdm_errorgui_error_box (d,
GTK_MESSAGE_WARNING,
_("User's $HOME/.dmrc file is being ignored. "
"This prevents the default session "
"and language from being saved. File "
"should be owned by user and have 644 "
"permissions. User's $HOME directory "
"must be owned by user and not writable "
"by other users."));
usrsess = g_strdup ("");
usrlang = g_strdup ("");
}
CODE: // 调用登录子函数。
switch (pid) {
case -1:
gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start");
case 0:
{
const char *lang;
gboolean has_language;
has_language = (language != NULL) && (language[0] != '\0');
if ((gdm_system_locale != NULL) && (!has_language)) {
lang = gdm_system_locale;
} else {
lang = language;
}
if G_LIKELY (logfilefd >= 0) {
VE_IGNORE_EINTR (close (logpipe[0]));
}
/* Never returns */
session_child_run (pwent,
logpipe[1],
failsafe,
home_dir,
home_dir_ok,
#ifdef WITH_CONSOLE_KIT
ck_session_cookie,
#endif
session,
save_session,
lang,
gnome_session,
usrcfgok,
savesess,
savelang);
g_assert_not_reached ();
}
->
slave.c
static void session_child_run (struct passwd *pwent,
int logfd,
gboolean failsafe,
const char *home_dir,
gboolean home_dir_ok,
#ifdef WITH_CONSOLE_KIT
const char *ck_session_cookie,
#endif
const char *session,
const char *save_session,
const char *language,
const char *gnome_session,
gboolean usrcfgok,
gboolean savesess,
gboolean savelang)
CODE: // session最终设定
/* Prepare user session */
g_setenv ("XAUTHORITY", d->userauth, TRUE);
g_setenv ("DISPLAY", d->name, TRUE);
if (d->windowpath)
g_setenv ("WINDOWPATH", d->windowpath, TRUE);
g_setenv ("LOGNAME", pwent->pw_name, TRUE);
g_setenv ("USER", pwent->pw_name, TRUE);
g_setenv ("USERNAME", pwent->pw_name, TRUE);
g_setenv ("HOME", home_dir, TRUE);
#ifdef WITH_CONSOLE_KIT
if (ck_session_cookie != NULL) {
g_setenv ("XDG_SESSION_COOKIE", ck_session_cookie, TRUE);
}
#endif
g_setenv ("PWD", home_dir, TRUE);
g_setenv ("GDMSESSION", session, TRUE);
g_setenv ("DESKTOP_SESSION", session, TRUE);
g_setenv ("SHELL", pwent->pw_shell, TRUE);
CODE: // 语言最终设定
if ( ! ve_string_empty (language)) {
g_setenv ("LANG", language, TRUE);
g_setenv ("GDM_LANG", language, TRUE);
}
/* just in case there is some weirdness going on */
VE_IGNORE_EINTR (g_chdir (home_dir));
if (usrcfgok && home_dir_ok)
gdm_daemon_config_set_user_session_lang (savesess, savelang, home_dir, save_session, language);
->
登录完成!