プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

daemonについて このエントリーをはてなブックマークに追加

Rubyのconfigure.inには以下のように、*BSD以外は強制的にdaemon(3)がないと判定させる
あやしげなロジックがある。


dnl Checks for libraries.
AS_CASE(["$target_os"],[*bsd*|dragonfly*],[],[ac_cv_func_daemon=no])


gitで履歴をしらべると、元々Mac OS X だけが腐ってる扱いだったのだが、
後に一般化されている。困ったことに理由はまったく記載されていない。
それをいったら元々のMacOS X が腐ってるという扱いにした理由も書いてないんだけど。


さて、本当かどうか分からないがある人から、Linuxのdaemon(3)は本来二回
forkが必要なところを一回しかforkしてないので腐ってる。それが原因ではないか
と教えて貰った

https://www.codeblog.org/blog/akr/200511.html

ほー。こんな話があったのか。しらなんだ。


ちなみにLinuxのカーネルのソースコード読める人は以下のあたりを読むと良い

kernel/sys.c

SYSCALL_DEFINE0(setsid)
{
struct task_struct *group_leader = current->group_leader;
struct pid *sid = task_pid(group_leader);
pid_t session = pid_vnr(sid);
int err = -EPERM;

write_lock_irq(&tasklist_lock);
/* Fail if I am already a session leader */
if (group_leader->signal->leader)
goto out;

/* Fail if a process group id already exists that equals the
* proposed session id.
*/
if (pid_task(sid, PIDTYPE_PGID))
goto out;

group_leader->signal->leader = 1;
__set_special_pids(sid);

proc_clear_tty(group_leader);

err = session;
out:
write_unlock_irq(&tasklist_lock);
if (err > 0)
proc_sid_connector(group_leader);
return err;
}


drivers/char/tty_io.c

static int tty_open(struct inode *inode, struct file *filp)
{
(snip)
mutex_lock(&tty_mutex);
tty_lock();
spin_lock_irq(¤t->sighand->siglock);
if (!noctty &&
current->signal->leader &&
!current->signal->tty &&
tty->session == NULL)
__proc_set_tty(current, tty);
spin_unlock_irq(¤t->sighand->siglock);
tty_unlock();
mutex_unlock(&tty_mutex);
return 0;
}



ためしに、Solarisのlibcのdaemonを見てみると・・・・
おお、たしかに二回forkしとる。

http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/daemon.c


42 int
43 daemon(int nochdir, int noclose)
44 {
45 int retv, fd;
46
47 /*
48 * By the first fork+setsid, we disconnect from our current controlling
49 * terminal and become a session group leader.
50 */
51 retv = fork();
52 if (retv == -1)
53 return (-1);
54 if (retv != 0)
55 _exit(EXIT_SUCCESS);
56 if (setsid() == -1)
57 return (-1);
58 /*
59 * By forking again without calling setsid again, we make certain
60 * that we are not the session group leader and can never reacquire
61 * a controlling terminal.
62 */
63 retv = fork();
64 if (retv == -1)
65 return (-1);
66 if (retv != 0)
67 _exit(EXIT_SUCCESS);
68
69 if (nochdir == 0)
70 (void) chdir("/");
71
72 if (noclose == 0) {
73 /*
74 * Missing the PRIV_FILE_READ privilege may be one of the
75 * reasons that prevent the opening of /dev/null to succeed.
76 */
77 if ((fd = open("/dev/null", O_RDWR)) == -1)
78 return (-1);
79
80 /*
81 * Also, if any of the descriptor redirects fails we should
82 * return with error to signal to the caller that his request
83 * cannot be fulfilled properly. It is up to the caller to
84 * do the cleanup.
85 */
86 if ((fd != STDIN_FILENO) && (dup2(fd, STDIN_FILENO) < 0)) {
87 (void) close(fd);
88 return (-1);
89 }
90 if ((fd != STDOUT_FILENO) && (dup2(fd, STDOUT_FILENO) < 0)) {
91 (void) close(fd);
92 return (-1);
93 }
94 if ((fd != STDERR_FILENO) && (dup2(fd, STDERR_FILENO) < 0)) {
95 (void) close(fd);
96 return (-1);
97 }
98
99 if (fd > STDERR_FILENO)
100 (void) close(fd);
101 }
102 return (0);
103 }



・・・しかしだ。cross referenceでサーチしていて分かったのだが、OpenSolarisの場合付属コマンドが
*BSDからもってきたdaemon()を自分で抱えてるケースがいっぱいあって、libcだけ真面目に二回
forkしていても現実的には全然安心できないというのがトホホである。

そういうわけで、Linuxのlibcのdaemonはいまいちイケテないってことと、SolarisのlibcはまともだけどSolarisの
ユーザランドのコマンドはまともとは限らないって事が分かった。

だから何って感じだが
関連記事


linux | 【2011-01-21(Fri) 19:12:38】 | Trackback:(0) | Comments:(0)
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。