You are not logged in.
Hi all
The X Server is already running with root privileges. Then a forkpty is called and in that process privileges will be changed to user ones. After that xinit is executed and the DE is starting. Everything is working fine, except that applications running in that DE hang up after a time(30-45min). When this starts, almost all further started application are not usable. What is the problem? How do terminal emulators do that? I looked at some sources and they all use PTYs!
Here is my Code
bool Core::LoginUser(QString Username, QString Session) {
// Create a new Process within a pseudo terminal, so child processes get also killed.
int masterfd;
pid_t pid = forkpty(&masterfd, 0, 0, 0);
if(pid < 0)
return false;
if(pid == 0)
{
// TODO: QObject::tr() -> cerr
// TODO: Hide the Cursor
struct passwd *pw = getpwnam(Username.toAscii());
endpwent();
if(pw == 0)
_exit(1);
if (pw->pw_shell[0] == '\0') {
setusershell();
strcpy(pw->pw_shell, getusershell());
endusershell();
}
// Fill the Environment Variable
const int Num_Of_Variables = 9; // Number of env. variables + 1
char** child_env = static_cast<char**>(malloc(sizeof(char*)*Num_Of_Variables));
int n = 0;
char* term = getenv("TERM");
if(term) child_env[n++]=StrConcat("TERM=", term);
child_env[n++]=StrConcat("HOME=", pw->pw_dir);
child_env[n++]=StrConcat("SHELL=", pw->pw_shell);
child_env[n++]=StrConcat("USER=", pw->pw_name);
child_env[n++]=StrConcat("LOGNAME=", pw->pw_name);
// TODO: Get this from the config
child_env[n++]=StrConcat("PATH=", "PATH=/bin:/usr/bin:/usr/local/bin");
child_env[n++]=StrConcat("DISPLAY=", MainXServer::DisplayName.toAscii());
child_env[n++]=StrConcat("XAUTHORITY=", QString(QString(pw->pw_dir) + "/.Xauthority").toAscii());
child_env[n++]=0;
if((initgroups(pw->pw_name, pw->pw_gid) != 0) || (setgid(pw->pw_gid) != 0) || (setuid(pw->pw_uid) != 0)) {
cerr << "could not switch user id" << endl;
_exit(1);
}
// Run the session login script
if (!RunScript("/etc/mldm.d/session_login.sh", child_env))
cerr << QObject::tr("Failed to exec session_login.sh script!").toAscii().data() << endl;
// Change Session and Username Variable
DBus::registerSession(MainXServer::DisplayNum, MainXServer::VTNum, Session, Username);
// Set the XServer command
// TODO: get the loginCommand from the config
// TODO: Start xinit scripts in /etc/X11/xinit.d.....
QString LoginCommand = "/login.sh"; //"exec /bin/bash -login ~/.xinitrc %session";
LoginCommand.replace("%session", Session);
// Change current directory of current process
if (chdir(pw->pw_dir) < 0) {
cerr << "Failed to change directory to users home folder!" << endl;
_exit(1);
}
// Execute command
execle(pw->pw_shell, pw->pw_shell, "-c", LoginCommand.toAscii().data(), NULL, child_env);
// TODO: Display error on gui
cerr << "could not execute login command" << endl;
_exit(1);
}
// Wait until user is logging out (login process terminates)
int status;
// TODO: Change to pid
waitpid(pid, &status, 0);
// Close the pseudo terminal
close(masterfd);
// Change Session and Username Variable
DBus::registerSession(MainXServer::DisplayNum, MainXServer::VTNum, "MLDM");
// Check the return status of the process
if (WIFEXITED(status) && WEXITSTATUS(status)) {
// TODO: show this in gui
// Failed to execute login command
return false;
} else {
// TODO:
// Run Stop Script
return true;
}
}Thx in advance!
Last edited by ying (2011-09-25 16:07:57)
Offline
For those who are interested: http://www.c-plusplus.de/forum/p2124180#2124180
Offline