作为协同处理的登录过程

问题描述:

我尝试运行login(1)过程作为我的程序的协处理。 程序应该接收登录提示并写入登录名。作为协同处理的登录过程

login过程很好地作为协处理启动。 但是在写入登录提示之前它立即退出。

程序的简化版本(写的东西等去掉):

int main(int argc, char** argv) 
{ 
    int fd1[2]; 
    int fd2[2]; 

    if((pipe(fd1) != -1) && (pipe(fd2) != -1)) 
    { 
     const pid_t child_pid = fork(); 

     if(child_pid == 0) 
     { 
      dup2(fd2[0], STDIN_FILENO); 
      dup2(fd1[1], STDOUT_FILENO); 
      close(fd1[0]); 
      close(fd1[1]); 
      close(fd2[0]); 
      close(fd2[1]); 

      execl("/bin/login", "login", (char*)NULL); 

      fprintf(stderr, "execl failed\n"); 
     } 
     else if(child_pid) 
     { 
      char buffer[1000]; 
      ssize_t len; 

      close(fd1[1]); 
      close(fd2[0]); 

      len = read(fd1[0], buffer, sizeof(buffer) - 1); 

      if(len > 0) 
       fprintf(stderr, "%zd bytes received\n", len); 
      else if(len == 0) 
       fprintf(stderr, "read return zero \n"); 
      else 
       fprintf(stderr, "read failed: %V \n", errno); 
     } 
     else 
     { 
      fprintf(stderr, "Fork failed: %V", errno); 
     } 
    } 
    else 
    { 
     fprintf(stderr, "Can not open pipes: %V", errno); 
    } 
    return 0; 
} 

当我运行程序,结果是:

~ # my_program 
read return zero 
~ # 

如果我用strace的运行它,我得到了以下结果(很多不相关的行被删除)

~ # strace -f my_program 
[pid 4028] read(3, <unfinished ...> 
[pid 4030] execve("/bin/login", ["login"], [/* 12 vars */]) = 0 
[pid 4030] ioctl(0, TCGETS or SNDCTL_TMR_TIMEBASE, 0x7bc28aec) = -1 EINVAL (Invalid argument) 
[pid 4030] exit_group(1)    = ? 
Process 4030 detached 
[pid 4028] <... read resumed> ""..., 999)   = 0 
[pid 4028] --- SIGCHLD (Child exited) @ 0 (0) --- 
[pid 4028] write(2, "read return zero \n"..., 18) = 18 

login进程使得出口af ter失败ioctl(STDIN_FILENO, TCGETS,)致电。 login似乎预计输入fd是终端或串行线路。

有什么方法可以修复我的程序吗?

login预计TTY。可能最容易与login交互的方法是通过posix_openpt分配伪终端,并传递从属文件描述符而不是管道句柄。 (但我不是这方面的专家。)

你想做什么?也许更好的方法是通过PAM进行身份验证,具体取决于您的使用情况。

+0

最初的问题是'mount.ecryptfs'。 'login'和'mount.ecryptfs'的失败方式类似。所以我选择登录的问题,因为它是众所周知的程序。但是,我会尝试伪终端.... – SKi 2012-02-24 13:39:43

如果你想以这种方式运行程序,我建议尝试系统(3),popen(3)等,而不是滚动自己的例程来做同样的事情。

+0

我没有找到合适的功能。系统和popen调用不能使用,因为需要读写。 – SKi 2012-02-27 07:41:12