掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28482

Gtk+のgtk_init_check()関数が失敗する理由
投稿者---h3X(2006/10/14 22:03:38)


環境はLinux, gccです.

現在,「新着メールチェックプログラム」をC言語で開発しています.

簡単な仕様は,まずこのプログラムは起動時にデーモンとして起動され,
パソコンの電源を切るまでデーモンとして動き続けます.
起動のさせ方は,Linuxでお馴染のサービス起動スクリプトを書き,他のデーモンと同様に起動させます.
起動後は,定期的にメールサーバに接続し「STAT」を送信し,そのレスポンスから新着メールがあることが分れば,
Gtk+の関数を用いて作成したウィンドウをポップアップで表示し,ユーザーに新着メールがあることを知らせます.

このプログラムでは,なんらかのエラーが発生した場合syslog()によりエラーメッセージを/var/log/messageに出力するようにしています.

プログラムが完成していざパソコンを起動してみると,サービスの起動は問題なく行なえているのですが,
get_init_check()関数が失敗して,パソコンを立ち上げた時点でプロセスが終了してしまいます.

以下に関連性のあるであろう個所のプログラムを示します.

int main(int argc, char **argv)
{
    init_log();

    init_signal();

    init_daemon();

    init_gtk(argc, argv);

    main_loop();

    /* never reach here */
    return 0;
}

void main_loop()
{
    while (1) {

        if (check_mail() == EXIST_NEW_MAIL) {
            show_popup();
        }

        DBG(printf("sleeping...\n"));
        sleep(CHECK_INTERVAL);
    }
}

void show_popup(void)
{
    if (gtk_init_check(&gtk.argc, &gtk.argv) == FALSE) {
        putlog("gtk_init_check() error");
        exit(1);
    }

    gtk.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_signal_connect(GTK_OBJECT(gtk.window), "destroy",
                       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
    gtk_window_set_title(GTK_WINDOW(gtk.window), "camil");
    gtk_container_set_border_width (GTK_CONTAINER (gtk.window), 50);

    gtk.label = gtk_label_new("New mail exist !");
    gtk_container_add(GTK_CONTAINER(gtk.window), gtk.label);
    gtk_widget_show(gtk.label);

    gtk_widget_show(gtk.window);
    gtk_main();
}


原因が解る方いらっしゃいましたら,ご教授よろしくお願いいたします.


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:Gtk+のgtk_init_check()関数が失敗する理由 28483 h3X 2006/10/14 22:59:37


No.28483

Re:Gtk+のgtk_init_check()関数が失敗する理由
投稿者---h3X(2006/10/14 22:59:37)


すみません.追記です.

struct Gtk {
    GtkWidget *window;
    GtkWidget *label;
    int argc;
    char **argv;
};

static struct Gtk gtk;

void cleanup_exit(void)
{
    closelog();
    exit(1);
}

void init_gtk(int argc, char **argv)
{
    gtk.argc = argc;
    gtk.argv = argv;
}

void sig_catch(int signo)
{
    closelog();
    unlink(LOCK_PATH);
    exit(0);
}

void init_signal(void)
{
    if (signal(SIGTERM, sig_catch) == SIG_ERR) {
        putlog("signal(SIGTERM, sig_catch) error");
        cleanup_exit();
    }
    if (signal(SIGINT, SIG_IGN) == SIG_ERR) {
        putlog("signal(SIGINT, SIG_IGN) error");
        cleanup_exit();
    }
    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
        putlog("signal(SIGPIPE, SIG_IGN) error");
        cleanup_exit();
    }
}

void init_daemon()
{
    switch (fork()) {
        case -1:
            putlog("fork() failed");
            cleanup_exit();
            break;
        case 0:
            break;
        default:
            exit(0);
            break;
    }

    if (setsid() == -1) {
        putlog("fork() failed");
        cleanup_exit();
    }

    if (chdir("/") == -1) {
        putlog("chdir() error");
        cleanup_exit();
    }

    if ( (close(0) == -1) || (close(1) == -1) || (close(2) == -1)) {
        putlog("close() error");
        cleanup_exit();
    }
}







この投稿にコメントする

削除パスワード

No.28484

Re:Gtk+のgtk_init_check()関数が失敗する理由
投稿者---yoh2(2006/10/14 23:24:32)


gtk_init_check()の代わりにgtk_init_with_args()を用いて、エラーの内容を取得してみましょう。

ぱっと見、考えられる理由として、

1. デーモンとして起動しているとのことですので、DISPLAYが正しく設定されていないのではないでしょうか?
2. この作りだと、メール到着の度にGTK+を初期化するような気が。

を挙げておきます。


この投稿にコメントする

削除パスワード

No.28486

Re:Gtk+のgtk_init_check()関数が失敗する理由
投稿者---h3X(2006/10/15 12:58:00)


ご返信ありがとうございます.

>gtk_init_check()の代わりにgtk_init_with_args()を用いて、エラーの内容を取得してみましょう。

早速 gtk_init_with_args() 関数を用いてエラーを突き止めようと思い,
この関数の仕様をWebで検索したのですが,

http://developer.gnome.org/doc/API/2.0/gtk/gtk-General.html#gtk-init-with-args

というサイトに辿り着いたぐらいで,日本語で引数の意味等を解説しているサイトを見つけることができません.
英語で説明されているため,引数に何を与えてやればいいのか,ほとんど理解できません.

なにぶんGTK+に関しては全くの無知でして,ただポップアップのウィンドウを表示させたいがために,
その場しのぎでWebを参考にしコーディングしました.

どこか日本語でこの関数の仕様について説明してあるサイトを御存じでしたら,
お教えいただければ助かります.

よろしくお願いいたします.


この投稿にコメントする

削除パスワード

No.28487

Re:Gtk+のgtk_init_check()関数が失敗する理由
投稿者---yoh2(2006/10/15 14:47:41)


>http://developer.gnome.org/doc/API/2.0/gtk/gtk-General.html#gtk-init-with-args
>
>というサイトに辿り着いたぐらいで,日本語で引数の意味等を解説しているサイトを見つけることができません.
>英語で説明されているため,引数に何を与えてやればいいのか,ほとんど理解できません.

うーん。辞書片手に頑張ってくれとしか言いようが……
私が探した時も、日本語の解説サイトが見付かりませんでしたし。
書籍ならいくつかあった気がしますが、GTK+1.x時代のものしかないかも。


ついでに、このプログラムの仕様について、いくつか気になった点がありますので列挙します。
デーモンとして起動して、メールチェックを行うプログラムにfetchmailというものが
ありますが、それは1の問題だけ解決できればよいわけで。
他の問題も解決済みでしたらごめんなさい。

1. 誰宛のメールのチェックを行うのですか?
まあ、設定ファイルに書かれたユーザーについてチェックすればいいのかな?

2. どのXサーバを使いますか?
これが未設定、またはGTK+初期化時に設定したXサーバが未起動のため、
gtk_init_check()が失敗しているのではないかと睨んでいます。

3. そのXサーバを誰が使っているか判別する方法は?
ユーザーhogeがXサーバを使っている時にユーザーfugaq宛のメール到着を通知されても困りますよね。
でも、1、2の問題は設定ファイルなどで解決できるとして、これはちょっと解決方法が思い当たりません。
というのも、Xサーバそのものはログインして使うような性質のものではありませんから。
# gdmあたりがうまいこと管理してくれてるのかな?
# gdmは使わないのでよく分かりませんが。


この投稿にコメントする

削除パスワード

No.28488

Re:Gtk+のgtk_init_check()関数が失敗する理由
投稿者---yoh2(2006/10/15 15:06:21)


>英語で説明されているため,引数に何を与えてやればいいのか,ほとんど理解できません.
人にgtk_init_with_args()を使えと言っておきながら、実は自分でも使ったことがなかったり。

とりあえず以下のプログラムで動作することを確認しました。が、合ってるかどうかはよく分かってません。
#include <stdio.h>
#include <gtk/gtk.h>

int main(int argc, char **argv)
{
        GError *error = NULL; /* NULLを代入しておく必要あり */
        if (gtk_init_with_args(&argc, &argv, "", NULL, NULL, &error) == FALSE) {
                printf("%s\n", error->message);
                g_error_free(error);

                return 1;
        }

        return 0;
}


$ ./a.out
(何も表示されず)

$ DISPLAY='' ./a.out
cannot open display: (null)


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧