2012-02-24 9 views
2

私はプログラムのコプロセッサとして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; 
} 

私はプログラムを実行すると、結果は次のとおりです。私はstraceのとそれを実行した場合

~ # my_program 
read return zero 
~ # 

、私が得ました以下の結果(無関係な行が削除されている)

~ # 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プロセスは、exit af terはioctl(STDIN_FILENO, TCGETS,)コールに失敗しました。 loginは、入力fdが端末またはシリアル回線であると思われます。

私のプログラムを修正する方法はありますか?

答えて

3

loginはTTYを想定しています。おそらくloginと対話できる最も簡単な方法は、posix_openpt経由で擬似端末を割り当て、パイプハンドルの代わりにスレーブのファイル記述子を渡すことです。 (しかし、私はその専門家ではありません)

何をしようとしていますか?おそらく、あなたのユースケースに応じて、PAM経由で認証を行う方がよいでしょう。

+0

元は、問題は 'mount.ecryptfs'でした。 'login'と 'mount.ecryptfs'は同じように失敗しました。だから私はよく知られているプログラムであるので、質問のログインを選択します。しかし、私は疑似端末を試してみる.... – SKi

0

このようにプログラムを実行したい場合は、同じことをする独自のルーチンをローリングするのではなく、system(3)、popen(3)などを試すことをお勧めします。

+0

私は適切な機能を見つけられませんでした。読み書きが必要であったため、システムコールやポップコールを使用することはできません。 – SKi

関連する問題