From: Tanaka Akira Date: 2011-10-24T18:43:39+09:00 Subject: [ruby-dev:44690] Re: [ruby-trunk - Bug #5475][Open] r33507以降SolarisでPTYが使えない 2011年10月24日16:56 Naohisa Goto : > Bug #5475: r33507以降SolarisでPTYが使えない > http://redmine.ruby-lang.org/issues/5475 > デバッガで追ってみると、ext/pty/pty.c:296 の grantpt(masterfd) が -1 となり、 > errno は EACCES (Solaris10では13) でした。 > そして、r33507で新規に導入された ext/pty/pty.c:294 の rb_fd_set_cloexec(masterfd); で masterfd に FD_CLOEXEC フラグを設定しているのが原因のようです。 > > Solarisでは、grantpt(3) 内部で /usr/lib/pt_chmod という setuid root されたヘルパープログラムを呼んでデバイスファイルのパーミッション設定を行っていますが、FD_CLOEXECをptyのmasterfdに設定すると、ヘルパープログラムを呼ぶ際に自動でcloseされてしまうため、ヘルパープログラムにclose済みのファイルデスクリプタが渡され、エラーになるのだろうと推測します。 なるほど。 とりあえずワークアランドとして以下のようにすると避けられるでしょうか。 そのうち Solaris の grandpt() が FD_CLOEXEC をつけてあっても動くように 変わるんじゃないかという気もしますが。 Index: ext/pty/pty.c =================================================================== --- ext/pty/pty.c (revision 33517) +++ ext/pty/pty.c (working copy) @@ -290,10 +290,18 @@ get_device_once(int *master, int *slave, dfl.sa_flags = 0; sigemptyset(&dfl.sa_mask); +#if defined(sun) + /* Solaris 10 needs FD_CLOEXEC bit clear to work with grantpt(). [ruby-dev:44688] */ + if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error; + if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error; + if (grantpt(masterfd) == -1) goto grantpt_error; + rb_fd_set_cloexec(masterfd); +#else if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error; rb_fd_set_cloexec(masterfd); if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error; if (grantpt(masterfd) == -1) goto grantpt_error; +#endif if (sigaction(SIGCHLD, &old, NULL) == -1) goto error; if (unlockpt(masterfd) == -1) goto error; if ((slavedevice = ptsname(masterfd)) == NULL) goto error; -- [田中 哲][たなか あきら][Tanaka Akira]