APUE(v1)的open server是一個重要框架,可是作者有點弄得太複雜一點,從作者提出的三個prototype的function看起,先看SVR 4的版本
int send_fd(int spipefd, int fileds);
int send_err(int spipefd, int status, cont char *merrmsg);
int recv_fd(int spipefd, ssize_t (*userfunc)(int, const void*,size_t));
某種程度直觀,但是...send_err()用send_fd()實作orz,send_fd的第二個參數,不一定是file descriptor!其實可能會是error code,一個參數兩種意義,這是容易混淆的一點
接著是作者設計的protocol,實在是為了在recv_fd上判斷到底是傳來的file descriptor還是error code,另外作者設計得不好的另外一點是...他是null start,第一個char固定式null,第二個char如果是0表示正常,如果是其他就是傳遞error code
跟著看recv_fd(),裡面竟然用getmsg(),這個function出現在chapter 11,如果不熟悉,要仔細翻閱,因為限制在SVR4,底層實作read/write,實際用message queue所以可以用getmsg(),非常平台相關,要注意的是for( ; ; ),為何要是無限迴圈?實際上也是為了處理send_fd()跟send_err()的區別,如果是正常的send_fd(),很容易就如大家trace出結果。但是如果是send_err(),那會收到兩組資訊,一組是error message,在send_err()內呼叫,另外一組是send_err()呼叫send_fd()送出來的。所以for( ; ; )會執行兩次,一次會呼叫使用者給定的error handler,跟著第二組來自send_err()呼叫send_fd()的資訊才會回傳小於0的fd表示錯誤
這裡有小小的一個bug,當傳入error message的時候,*ptr會指向C字串最後一個字元\0(null)之後,但是他還是有很小的機會為0,這時候程式就會出錯,端看當時記憶體內的資料情況
沒有留言:
張貼留言