2015-03-02 149 views
0

在我的程序中,我調用函數fork(),然後我想要fork創建的子進程打開一個新的終端窗口。 這是我現在所擁有的代碼:如何使用fork()打開一個新的終端窗口?

 /* 
    * 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; 
    }}} 

我希望發生的是新的終端窗口中運行的功能,我已經實現了我自己。我不太確定如何去解決這個問題,任何人都有一些想法或方向來幫助?

編輯: 我現在編輯了這個問題,以便整個程序可見。以下是程序應該能夠做的事情。我不知道如何去任何進一步的...

  • 用戶的認證成功後,你的程序應該叉子和啓動終端 窗口用戶的首選外殼。父進程應該等到孩子 退出,然後再次顯示「login:」提示符。
  • 在啓動終端窗口之前,子進程應該設置合適的真實有效的 進程用戶以及合適的真實有效組。
+0

在什麼操作系統上? – 2015-03-02 10:51:22

+0

你可以顯示你的完整代碼...? – 2015-03-02 10:55:07

回答

1
execl("/usr/bin/xterm", "xterm", "-e", "yourprogram", NULL);