2010年5月26日 星期三

fork()、pipe()、dup2() 和 execlp() 的組合技法

Standard
對一般程式來說,管線(pipe)機制很少會用到,尤其對於在 Windows 底下的程式開發者來說,很可能前所未聞,而在 Unix-like 環境中常見的例子,就是往往在命令後面加上『|』,其意味使用『管子(pipe)』將內容導入另一個程式裡,如:『dmesg | grep ALSA』。在該例中,Shell 有趣的將 demsg 標準輸出(standard output)全數導入 grep 程式的標準輸入(standard input)中,再交由 grep 處理並找出存在 ALSA 字串的句子所在。

另一個情況,Web Server 在支援 CGI 時,也會使用到 pipe。這是最典型的例子,當 Web Server 欲執行一支外部 CGI Program 時,會利用 pipe 去模擬該 CGI 的標準輸入及輸出(Standard I/O)。以上說明當然只是大致上的做法,細節還需加上 fork() 和 dup2() 的配合,透過個範例可清楚瞭解這部份的實作。

這是一個簡單的範例:
void cgi_run(const char* filename)
{
    char buffer[1024] = { 0 };
    int len; 
    int pfd[2];
    int status;
    pid_t pid;

    /* create pipe */
    if (pipe(pfd)<0)
        return -1;

    /* fork to execute external program or scripts */
    pid = fork();
    if (pid<0) {
        return 0;
    } else if (pid==0) { /* child process */
        dup2(pfd[1], STDOUT_FILENO);
        close(pfd[0]);

        /* execute CGI */
        execlp(filename, filename, NULL);
        exit(0);
    } else { /* parent process */
        close(pfd[1]);

        /* print output from CGI */
        while((len=read(pfd[0], buffer, 1023))>0) {
            buffer[len] = '\0';
            printf("%s\n", buffer);
        }

        /* waiting for CGI */
        waitpid((pid_t)pid, &status, 0);
    }
}

此範例相當易懂,不外乎是使用 fork() 建立一個新的 Process,再去執行一支外部 CGI,而主程式會等待外部 CGI 的輸出,再用 printf() 印出來 CGI 的輸出內容。而比較令人騷不著頭緒的部份,就是 pipe() 和 dup2() 的關係,使用 pipe() 可建立一組雙向的管線,範例中是一組有兩個整數值的陣列 pfd,這是一條水管,從 pfd[0] 進入的東西會從 pfd[1] 出來,反之亦然,除此之外,它也是可以跨 Process,達成兩個程式溝通的目的。除了建立 pipe,接著利用 dup2(),可以讓管線去取代外部程式的標準輸出(standard output),然後讓主程式用管線接收。

註:pipe() 回傳的是兩個檔案描述編號(file discriptions),需要用相應的檔案函數去操控它。

2010年5月11日 星期二

SCIM Patch: Auto enable input method when getting keyboard focus for a GTK+ text entry

Standard

As you know, Apple iPad is the latest craze and brings back tablet PC marketing cause most manufactories aim to begin to produce products with touchscreen. In order to make applications work with touchscreen for tablet PC, implementing on-screen keyboard is the major issue. There are many open source solutions you can get from internet, but you may get a question, what time is better to start the on-screen keyboard? It is a good idea that enable on-screen keyboard when input box get focus, that is just like Apple iPhone, iPod, iPad and a lot smart phone.

SCIM has panel support, it can provide on-screen keyboard. So I have patched scim-bridge to support that auto enable input method when getting keyboard focus for a GTK+ text entry. If so input method is enabled, SCIM will show on-screen keyboard automatically.

Here is my patch you can get:
http://people.linux.org.tw/~fred/patches/scim-bridge-0.4.16_client-gtk-autoshow.patch