2010年8月10日16:21 Tanaka Akira <akr / fsij.org>:
>
> freebsd8(16:07:56)% cat z.rb
> require 'pty'
> PTY.getpty('sleep 1') do |r, w, pid|
>  p pid
>  w.print("a")
>  Process.wait pid
> end
> puts :fin

C にしてさらに単純化するとこうですかね。

freebsd8(23:26:18)% cat t.c
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
  int m, s;
  char *slavedev;
  pid_t pid;
  int status;

  if ((m = posix_openpt(O_RDWR|O_NOCTTY)) == -1) {
perror("posix_openpt"); exit(1); }
  if (grantpt(m) == -1) { perror("grantpt"); exit(1); }
  if (unlockpt(m) == -1) { perror("unlockpt"); exit(1); }
  if ((slavedev = ptsname(m)) == NULL) { perror("ptsname"); exit(1); }
  if ((s = open(slavedev, O_RDWR|O_NOCTTY, 0)) == -1) {
perror("open(slavedev)"); exit(1); }

  pid = fork();
  if (pid == -1) { perror("fork"); exit(1); }
  if (pid == 0) {
    sleep(1);
    exit(0);
  }
  if (close(s) == -1) { perror("close"); exit(1); }

  if (write(m, "a", 1) == -1) { perror("write"); exit(1); }

  fprintf(stderr, "pid=%d\n", (int)pid);
  if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); exit(1); }

  return 0;
}
freebsd8(23:26:22)% gcc -Wall t.c
freebsd8(23:28:02)% time ./a.out
pid=68602
^C
./a.out  0.00s user 0.00s system 0% cpu 19.719 total


^C する前に ps した結果:
freebsd8(23:28:08)% ps u68602
USER   PID %CPU %MEM   VSZ   RSS  TT  STAT STARTED      TIME COMMAND
akr  68602  0.0  0.1  1536   664   3  SE+  11:28PM   0:00.00 ./a.out

やっぱ E ですが、E って具体的にはどういう状況なのかなぁ。

しかし、setsid しなくても再現するなら

% ./ruby -rpty -e '
m, s = PTY.open
pid = spawn("sleep 1")
s.close
m.write "a"
Process.wait pid
'

で発症してもおかしくないと思うんですが再現しない...
-- 
[田中 哲][たなか あきら][Tanaka Akira]