GDM-2.20.1自动登录流程分析

先观察/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);


->
登录完成!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值