You are not logged in.

#1 2011-09-25 16:06:02

ying
Member
From: Austria
Registered: 2010-03-02
Posts: 110

Starting Desktop Environment in a forkpty - hanger

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

#2 2011-09-27 08:02:07

ying
Member
From: Austria
Registered: 2010-03-02
Posts: 110

Re: Starting Desktop Environment in a forkpty - hanger

For those who are interested: http://www.c-plusplus.de/forum/p2124180#2124180

Offline

Board footer

Powered by FluxBB