永結同心

wedding

(旁邊那個跳出來的攝影大哥,你時間點抓的真好)

雖然今年是孤鸞年,但我今年還是接到了幾個紅色炸彈,每次想紅包上的賀詞該寫些什麼,最後我好像都會老掉牙的寫下「永結同心」四個字。沒有特別的理由,可能就單單覺得兩個人在一起,彼此能同心合一地走到最後是一件很美的事情吧。

上禮拜參加高中同學的婚禮,又再之前參加了國防役同梯的婚禮。格外有感覺的是,這兩對看彼此的眼神總帶有一種真切、篤定、與溫暖,可能在一起的時間不是特別長,又或者是已經愛情長跑了好多年,那兩人眼神透露出的就好像是一種對於未來的期盼,還有對於彼此的信任感。

看到這樣的新人,心中總會很雀躍的。

我想起托爾斯泰說:「選擇你所喜愛的,愛你所選擇的」。希望這兩對新人能長長久久,也許應該這樣說,祝福你們「永結同心」吧!

Posted in Murmuring | Leave a comment

[工商服務] 只聽音樂不說話

只聽音樂不說話

Posted in Uncategorized | Leave a comment

一個 boost::exception 的例子

因為覺得 dprintf 出現的次數實在太多了,我會希望在 exception 就可以包好 __FILE__ 跟 __LINE__,又可以把 std::wstring 包在 exception 一起丟出去,在 catch 的時候再印出來就好。

所以試著寫了這樣一個例子,結果寫的四不像,跟原本想的東西完全部不同了,而且我對於那個 BUFSIZ 相當不滿啊。其實原本希望可以用 ##__VA_ARGS__ 這種 macro 直接吃進來變成一個 boost::any[],然後再想辦法轉成 boost::format 可以用的格式,中間還可以透過 BOOST_FOREACH 來玩的,不過我徹底失敗了,所以最後的成果大家笑笑就好了。 Continue reading

Posted in C++, Programming | Tagged , , | 4 Comments

Fago 與憐憫

在讀《赤朽葉家的傳說》最後幾章時,無來由想起幾個禮拜前交大學員團契的大家討論著「恩賜」這件事情,誰應該是「憐憫」恩賜的,誰又是「教導」恩賜的。這幾種恩賜當中,其實我似乎特別少感覺到「憐憫」恩賜的人出現在我身旁。也許因為我是家中長男的緣故,說是被訓練得獨立自主也好,又或者說是天生好強也好,好像許許多多時候,我都非得一個人披荊斬棘地斬斷一切阻擋在我面前的事物,然後故作堅強的扮演著不同的角色。

「憐憫」這件事情好像一直都離我很遠,即便如此,我還是私下為他做了幾個定義,像是:總能細膩地看見彼此的不同、給予支持、願意陪伴、不刻意強化自己的脆弱。寫下「自己」的時候,好像有什麼東西悶悶的在心中響著,我可能是這樣詮釋著的,我那種「憐憫」是沒有自己的,不是因為自己的不滿足而稱之為憐憫,不是因為自己的需要而發出不平之鳴,而是因為看見別人的痛苦,而催生出一種陪伴與難過的情緒。

就好像櫻庭一樹所寫的

「那妳知道密克羅馬尼亞島上有個部族的語言裡,沒有『悲傷』這個字嗎?」
「是嗎?我不知道耶。」
「最接近『悲傷』的是『FAGO』這個單字,那是指看到別人痛苦,會心生同情,自己也跟著難受起來的意思。可是他們卻沒有表現自己心中痛楚的單字,因為沒這個必要。你不覺得那是個善良的民族嗎?瞳子,妳想想看,他們盡管具有悲憫他人的概念,卻沒有悲憫自己的想法喔。一般人總是沉浸在自己的悲痛裡,我們也一樣,都只顧著自己不是嗎?」
「嗯……」

也許憐憫是一種特別的事情,是期望自己能真正的感同身受,是在那個當下渴望人的需要能夠被滿足,是渴望傾聽或者任何事情能換取一些對於別人的幫助、醫治或者平靜。而自己的悲傷、想法,可能都不是那麼重要了。

我想,這可能是我想像的「憐憫」吧!

啊?我應該不是這種人啦?根據大家的討論,我可能是「幫助」類型的。不過最近真的格外希望,希望每個人都能健康、快樂、平靜的生活下去。

Posted in Books, Faith, Murmuring | Tagged , , , | Leave a comment

寫在那僅有一次的 26 歲生日

6/19 也過了差不多一半,就讓我隨口聊聊幾句吧!

我對於生日的感覺並不是很強烈,可能不用一群人熱熱鬧鬧的慶祝,也不一定要很多人記得,有時候生日就這樣平平淡淡地過,也沒什麼不好的。以前在交大的時候,有貓陪我過,也有幾年跟 ckefgisc 的大家一起過,或者跟 Lab117 的朋友一起過。而這幾年的生日似乎就沒什麼好提的,兩年前的生日,自己處在一種憂傷當中,儘管歡樂如 PJ 也沒辦法影響那個時候的自己。而去年的生日,似乎就只是在公司弄 iSCSI 的工作,沒特別吃什麼,也沒特別說什麼。

這樣的生日,有時候還是會有一點難過。

只是,今年的生日好像有那麼一點不一樣,其實並不是這一天而已,而是一整年的感覺。這一年好像豐富了起來,有時候能好好的聽歌,也能好好的跟朋友出去聽演唱會,還練了一首「Wake me up when September ends」,偶爾與人分享生活上的不順遂,也開始幫忙電腦部的一點服事。

前陣子去新竹訪問 Stecko 的時候,他說我好像沒有碩士班那時候那麼憂鬱。我只是笑笑的回答著:「好像是耶」

昨天我想到國中老師問的一個問題:「你以後想要變成怎麼樣的一個人?」,那個時候我回答「其實我覺得現在還不錯,能夠繼續像現在這樣也許也不錯」,老師就側著臉看著我,也許是這樣看似「不求長進」的回答不該出現在我的口中,也許這不是他心目中的「標準答案」,不過現在想起,還饒富趣味的。

所以,我想過怎麼樣一個 26 歲呢?我可能還有很多想做的事情,也期待另外一段感情的開始,也希望工作跟家人的關係都變好。我想起國中時期的回答,稍微改變一下當時候的回答,我想 26 歲的自己該做的是「從現在的自己開始,好好喜歡現在的生活,喜歡現在的自己,喜歡身邊的人,也喜歡每一個獨特的未來」

所有的改變都慢慢地在發生,我所作的,也許就只像箴言 4:23 所說:「你要保守你的心,勝過保守一切,因為一生的果效是由心發出」,確定方向,確定目光,就放手去做,我想這前頭必定有不一樣的東西等著我的!

所以,就這樣吧!祝自己 26 歲生日快樂!Happy Birthday!

Posted in Life, Murmuring | 9 Comments

從 inet_ntoa 看 thread safe 的 API

這周 refactor 一段 code 之後,被同事說:「為什麼 log 的來源 IP 跟目的地 IP 總是一樣呢?」

char *szDestIp = inet_ntoa(destAddr);
char *szSrcIp = inet_ntoa(srcAddr);

後來仔細想了一下 inet_ntoa 的 prototype,我就明白了!如果這個 function 不必特意去 free 回傳的 pointer,那可能在內部有一個 static buffer 去保存這個值。果不期然,FreeBSD 的原始碼是這樣實作的

/*const*/ char *
inet_ntoa(struct in_addr in) {
        static char ret[18];

        strcpy(ret, "[inet_ntoa error]");
        (void) inet_ntop(AF_INET, &in, ret, sizeof ret);
        return (ret);
}

char *
inet_ntoa_r(struct in_addr in, char *buf, socklen_t size)
{
        (void) inet_ntop(AF_INET, &in, buf, size);
        return (buf);
}

到這邊我們大概就知道,inet_ntoa 並不是一個 thread safe 的 function,你可以用下面這段程式測一下會發生什麼事情。

void* thread_func (void *param)
{
    char * addr= (char *)param;
    struct in_addr val;
    inet_aton(addr, &val);

    while (1)
        printf("%s => %s\n", addr, inet_ntoa(val));

    pthread_exit(NULL);
}

int main()
{
    pthread_t thr1, thr2;
    pthread_create(&thr1, NULL, thread_func, (void *)"127.0.0.1");
    pthread_create(&thr2, NULL, thread_func, (void *)"127.0.0.2");

    while(1) {
        sleep (1);
    }

    return 0;
}

輸出大概會像

127.0.0.2 => 127.0.0.1
127.0.0.1 => 127.0.0.2
127.0.0.1 => [inet_ntoa error]
127.0.0.2 => 127.0.0.2

所以,直接使用 inet_ntoa 在 reentrant 上可能會發生問題,如果你必須面對這些問題,最好的方式就是使用 inet_ntoa_r 這個 reentrant 的版本,或者直接使用 inet_ntop。

而這難道非得要踩到地雷,或者從 API 的細節才能窺知這一切嗎?其實並不完全是,當你發現回傳的是一個 char *,又沒有要求你特別 free 他,你是不是就該猜測他是回傳 function 內部的一個 static buffer 了呢?所以,舉凡 ctime, asctime 都不保證是 thread safe 的,這是我們 programmer 該留意的細節。

所以,也許我們以後需要更小心的去寫程式,在選擇 API 時也必須留意更多細節,以免未來踩到更多地雷……。

Posted in C++, Programming | Tagged , , | 2 Comments

以 boost::posix_time 處理時間字串

其實標題並不是那麼準確,這點我們之後再談。

其實起源很簡單,我們常常需要從各式各樣的時間字串轉成 time_t 或者 struct tm,要不然還可能是 FILETIME 跟 SYSTEMTIME 之類的結構。個人覺得 parsing 時間是一件難搞的事情,尤其是當你還要考慮 timezone 的影響,一切都變得不是那麼簡單了。

首先我必須要說,在 Windows 中沒有 strptime(3) 這樣還算好用的東西可以用,所以我又把腦袋動到 boost 上面去了。

我的目標是正確的處理「Sat, 28 Mar 2009 20:18:32 +0800」這樣的字串,然後把他轉成 time_t。我們會分兩個部份處理,首先我們先處理「Sat, 28 Mar 2009 20:18:32」這個部份,因為目前的 %q 只能處理輸出部份,請參考 Date Time Formatter/Parser Objects

    using namespace boost::posix_time;
    using namespace boost;
    using namespace std;

    std::string strDateTime = "Sat, 28 Mar 2009 20:18:32 +0800";
    std::string format = "%a, %d %b %Y %H:%M:%S";

    ptime pt(not_a_date_time);

    time_input_facet * input_facet = new time_input_facet(format);

    stringstream ss(strDateTime);
    ss.imbue(locale(ss.getloc(), input_facet ));

    ss >> pt;

這樣的確很簡單吧,只要按照文件寫的把 format 寫好,boost 就能幫你從 stringstream 的字串轉成 posix_time。

而 timezone 的部份就需要噁心一點的作法了。

    std::string strHour, strMinute;
    ss >> setw(3) >> strHour >> setw(2) >> strMinute;

    time_duration td(lexical_cast< int >(strHour), lexical_cast < int > (strMinute), 0);
    pt -= td;

我利用 setw 分別把 timezone 的小時與分抓出來,並轉成 time_duration,讓 posix_time 能直接減掉 timezone 的 offset 成為 GMT time,之後再做點手腳就可以變成 time_t 了。

嚴格來說,我想我是透過 time_input_facet 來處理字串的,希望這點小技巧對於需要 parsing 時間字串的人能有所幫助。

p.s: 其實這篇三個禮拜前就準備好了,只是一直拖到現在才把他丟出來 XD

Posted in C++, Programming | Tagged , , | 1 Comment

2009 三月末雜感

我實在搞不清楚,為什麼十里坡老闆娘會記得我每次都點青椒牛肉。

我覺得某部份的我應該不太喜歡改變,下了決定之後就會一直維持下去,像是跑步、閱讀、樂器,甚至感情也是這樣。最明顯的,我吃飯、喝飲料都是如此,對面的燒臘店該買招牌飯、五十嵐該點蜂蜜綠茶、有茶氏該點葡萄柚清茶。我想我的 mantee 就會這樣跟我說:「不要堅持這種無謂的東西啊」。不過我就是很在意這些枝微末節的小事,然後被許許多多的限制卡住,然後讓自己繞著圈圈跑,像隻追著自己尾巴的狗。

其實這段時間有蠻多細微,但值得紀錄的事情。像是久違的假期,去了 AsiaBSDCon 2009,英文課的點點滴滴,認識了一些新朋友,談了一些事情。不過許許多多的時間,還有記憶,那些話語片段都像轉瞬之光,僅存留在夜晚的街道中,或者是每個慢跑的喘息當中。

也許偶爾記錄下來吧。

昨天我說了一句話:「可以表達好感,但絕非討好」。結果今天上班的時候我才驚覺,幾年前有人曾說過類似的話,那個時候我不是那麼明白,如今卻從我口中重新詮釋出來,這種感覺還蠻奇妙的就是。

而今天回到家,我媽就默默的說「如果你不是去加班,是去約會就好了(默)」。也許是因為我媽好友的兒子(真繞口)要結婚了,我今天就被鋒面南下掃到,刮起陣風下起小雨了吧。媽!我還沒滿 26 歲。(雖然有同學已經結婚生小孩是沒錯啦。)

然後想買的 CD 越來越多,不過最近聽搖滾樂的比例越來越低了。有兩張 PJ 推薦的,像是艾青的同名專輯、PM2:00 樂團,還有我私心想買的 Dreams Come True,跟今天預購的楊乃文新專輯。

對!楊乃文要出新專輯了!然後六月有演唱會!!!(尖叫)

總而言之最近還不錯,只不過,我還是想有多一點時間給自己,多一點時間睡覺,多一點時間不是完成進度表上的事情。

Posted in Life, Murmuring | 2 Comments

Make love, not war

剛剛看到睡長輩http://blog.bsdchat.commake love (羞)這篇提到在 FreeBSD 下 make love 的結果改變了。

原本是這樣的

FreeBSD 6.3-RELEASE-p2 # make love
make: don’t know how to make love. Stop

現在變成

FreeBSD 7.2-PRERELEASE # make love
Not war.

原本以為 Not war. 這段 code 是在這幾年才加進去的,後來翻了一下 cvs 的紀錄發現,其實這個笑話從 1998/04/28 r1.8 就加進去了,只不過 OLD_JOKE 被定義為 0,所以一直都不會有這個效果。

+#if OLD_JOKE
+		if (strcmp(gn->name,"love") == 0)
+		    (*abortProc)("Not war.");
+		else
+#endif
+		    (*abortProc)("%s %s. Stop", msg, gn->name);

然後到了 2008/03/04,就有人說「No need to tell make to DTRT with “make love”, just do it.」,不過他最後還是補上了 WITHOUT_OLD_JOKE,讓人有機會用 CFLAGS 回到之前的狀況……。

+#ifndef WITHOUT_OLD_JOKE
 				if (strcmp(gn->name,"love") == 0)
 					(*abortProc)("Not war.");
 				else
+#endif
 					(*abortProc)("%s %s. Stop",
 					    msg, gn->name);
 				return (FALSE);

其實還蠻有意思的,原本 Make, not war 這句話是 1960 年代美國反戰(越戰)的標語,卻沒想到今天會在 FreeBSD 的原始碼得見他的蹤跡。

即使不用檢視原始碼,許多知名的 Easter egg 也帶給使用者不少樂趣。如果再進一步檢視原始碼,或許更能看見每個專案的心路歷程,又或者是工程師對於專案的看法等等。

(我去年 6/19 的 submit log 好像寫著「祝我自己生日快樂」,這或許也是一種悲傷吧 XD)

而每個專案的 version control 就這樣忠實紀錄下來每一個點點滴滴,就算人開始遺忘,那也無法抹除那曾經存在過的事實。

Posted in FreeBSD | Tagged , | 1 Comment

改變的預兆

換了髮型,換了 theme,換個時間睡覺,換個國家過一週。

現在時間,凌晨三點左右,我明天上班應該會睡死。

好像有一個週期似的,任性也有潮汐。

Posted in Murmuring | Leave a comment