简体   繁体   中英

How do i open a new terminal window using fork()?

In my program I call the function fork() and then I want the child process that fork creates to open a new terminal window. This is the code I have right now:

        /*
     * Shows user info from local pwfile.
     *  
     * Usage: userinfo username
     */

    #define _XOPEN_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "pwdblib.h"   /* include header declarations for pwdblib.c */
     #include <pwd.h>
     #include <unistd.h>
    #define _XOPEN_SOURCE       /* See feature_test_macros(7) */
    #include <unistd.h>



    /* Define some constants. */
    #define USERNAME_SIZE (32)
    #define NOUSER (-1)


    int print_info(const char *username)
    {
      struct pwdb_passwd *p = pwdb_getpwnam(username);
      if (p != NULL) {
        printf("Name: %s\n", p->pw_name);
        printf("Passwd: %s\n", p->pw_passwd);
        printf("Uid: %u\n", p->pw_uid);
        printf("Gid: %u\n", p->pw_gid);
        printf("Real name: %s\n", p->pw_gecos);
        printf("Home dir: %s\n",p->pw_dir);
        printf("Shell: %s\n", p->pw_shell);
        return 0;
      } else {
        return NOUSER;
      }
    }

    int user_authentication(const char *username , const char *password){

    struct pwdb_passwd *pw_entry; 
    char *salt = malloc(2);     // Allocate 2 bytes of memory for the salt variable
    int pwdcmp; // return value after comparison
    char *pwdcrypt; //the hashed password
    pw_entry = pwdb_getpwnam(username); // get struct line for username in pwfile

    if(pw_entry != NULL){       //If the structure exist
    memcpy(salt, pw_entry->pw_passwd, 2); // Take the 2 first bits of password will be in salt
    pwdcrypt = crypt(password, salt); // Hashed value

    pwdcmp = strcmp(pwdcrypt , pw_entry->pw_passwd);  // Compare the passwords

    if(pwdcmp == 0){    // if passwords are correct return 1
        return 1;
    } else{
    return -1;      // passwords are incorrect
    }

    }

    }

    void read_username(char *username)
    {
      printf("login: ");
      fgets(username, USERNAME_SIZE, stdin);

      /* remove the newline included by getline() */
      username[strlen(username) - 1] = '\0';
    }

    int main(int argc, char **argv)
    {
      char username[USERNAME_SIZE];
      char *inputpwd;
    int login = 0;
      int pwd_failed;       // Failed login counter
      int pwd_age;  // age of password counter

      struct pwdb_passwd *pw_entry;

     /*/ Until successful login, run this loop */

        while(login == 0){
        signal(2, SIG_IGN);
      /* 
       * Write "login: " and read user input. Copies the username to the
       * username variable.
       */
      read_username(username);





     /* Displays a propt to password, reads in the password */
      inputpwd = getpass("Password: ");


     /*/ Gets the structure of specifik username */
        pw_entry = pwdb_getpwnam(username); 

    /*/ Return the  age & failed passwords counter*/
    pwd_age = pw_entry->pw_age;
    pwd_failed = pw_entry->pw_failed;


     /* Check authentication, successful terminates program by login = 1 else 
     * run the program again
     */
        if(user_authentication(username , inputpwd) == 1 && pwd_failed > -1){
            printf("User authenticated successfully\n");

            if(pwd_age > 2){
                printf("Time to change password\n");
            }
            pwd_failed = 0;     // successful login resets failed                   atempts
            pwd_age++;
            pw_entry->pw_age = pwd_age;     //Update age in file
            pwdb_update_user(pw_entry);     
            login = 1;
        pid_t pid;
        int status;

        pid = fork();

        if (pid==0) {
            /* This is the child process. Run an xterm window */
           execl("/usr/bin/xterm", "xterm", "-e", "yourprogram", NULL);

            /* if child returns we must inform parent.
             * Always exit a child process with _exit() and not return() or exit().
             */
            _exit(-1);
        } else if (pid < 0) { /* Fork failed */
            printf("Fork faild\n");
            status = -1;
        } else {
            /* This is parent process. Wait for child to complete */
            if (waitpid(pid, &status, 0) != pid) {
            status = -1;
            }
        }
        }   
        else if(user_authentication(username, inputpwd) == -1){
            pwd_failed++;       //increase counter by 1 of failedlogins
            pw_entry->pw_failed = pwd_failed;   //update failed counter in file 

            if(pwd_failed > 1){
                pwd_failed = -1;


            }
            printf("\nWrong password: %s\n", username);  
            pwdb_update_user(pw_entry); 
        return 0;   
        }

        else{
            printf("Unknown user or incorrect password\n");
        return 0;
        }

        //pw_entry->pw_age = pwd_age;       //Update age in file
        //pw_entry->pw_failed = pwd_failed; //update failed counter in file

        pwdb_update_user(pw_entry);     //Update actual file

    /* Show user info from our local pwfile. */
      if (print_info(username) == NOUSER) {
          /* if there are no user with that usename... */
        printf("\nFound no user with name: %s\n", username);   
        return 0;
    }}}

What I want to happen is for the new terminal window to run a function, which I've implemented myself. I'm not very sure on how to go about this, anyone got some ideas or directions to help?

EDIT: I have edited the question now so that the entire program is visible. Below is what the program should be able to do. I have no idea how to go any further...

  • After a successful authentication of a user, your program should fork and start a terminal window with the user's preferred shell. The parent process should just wait until the child exits and then show the "login:" prompt again.
  • Before starting the terminal window, the child process should set the right real and effective user of the process, and the right real and effective group.
execl("/usr/bin/xterm", "xterm", "-e", "yourprogram", NULL);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM