简体   繁体   English

如何使用fork()打开新的终端窗口?

[英]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. 在我的程序中,我调用了fork()函数,然后希望fork创建的子进程打开一个新的终端窗口。 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. 在成功验证用户身份之后,您的程序应使用用户的首选shell派生并启动一个终端窗口。 The parent process should just wait until the child exits and then show the "login:" prompt again. 父进程应仅等待子进程退出,然后再次显示“ login:”提示。
  • 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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