發表文章

mmap

下面是一個很簡單、很一般的程式碼,內容是使用 openssl 所提供的函式去計算一個檔案的 MD5。既然這麼簡單為什麼要紀錄呢?理由有兩個:第一,紀錄一下要怎麼使用 openssl 的 library;第二是今天的重點,mmap。 一般來說,要計算一個檔案的 MD5,勢必要把整個檔案讀到記憶體當中(或是分批讀入,但勢必整個檔案都要吃進來),所以標準的程序應該是 open --> read --> md5 --> close。而在 read 這一步還需要額外準備一份記憶體空間給它。但如果使用 mmap 的話就可以直接少了 read 這一步了。 # include <stdio.h> # include <stdlib.h> # include <string.h> # include <unistd.h> # include <fcntl.h> # include <sys/mman.h> # include <sys/types.h> # include <sys/stat.h> # include <openssl/md5.h> long util_getFileSize ( char * ); void util_md5File ( char *, unsigned char * ); static long util_getFdSize ( int ); int main ( int argc, char *argv[] ) { int fileFd = 0; long fileSize = 0; unsigned char md5sum[MD5_DIGEST_LENGTH]; int i = 0; if( argc != 2 ) { printf( "Usage: md5 <file>\n" ); return 0; } ...

memcpy vs. memmove

這個事件是在工作中時間發生的案例。先看看下面的例子: # include < stdio.h > # include < stdlib.h > # include < string.h > int main () { int a[100]; int i = 0; int index = 5; for ( i = 0 ; i < 100 ; i++ ) { a[i] = i; } memcpy ( &(a[index]), &(a[(index + 1)]), sizeof ( int ) * ( 100 - index - 1 ) ); for ( i = 0 ; i < 100 ; i++ ) { printf ( " %d " , a[i] ); if ( ( i % 10 ) == 9 ) { printf ( " \n " ); } } printf ( " \n " ); return 0; } 好了,請問上面這段程式碼在寫什麼呢? 其實很簡單,這只是一個 array shift 的動作,將 index 後面的元素全部往前搬動一格。這樣寫會有什麼問題呢?我在我自己的電腦上什麼問題都沒有發生啊? 邏輯上很 OK ,但 問題出在 memcpy 這隻函式上面 。一般人可能會認為, memcpy 是直接做 sequential 的拷貝動作,也就是程式會先把把 i+1 的元素拷貝到 i ,然後才會把 i+2 的元素拷貝到 i+1。很直覺,但是上面這個想法是誰說的? 來讀讀看 manual 吧! The memcpy() function copies n bytes from memory area src to memory area dest.  The memory areas must not overlap . ...

SIGTTIN

看名字倒是挺容易發現這是一種 Signal。先來說說故事好了。最近接了一個撰寫 protocol 的案子,為了測試方便,我幫程式加了一個簡單的 command line interface。作法很簡單,我在程式裏面的 fd 處理地方多加了一個 stdin 的 callback function,然後在函式裏面進行處理。 問題來了,當我們把程式移交給客戶的時候,客戶將這隻 daemon 以背景的模式運行,結果程式就不會動了??為什麼?? 答案就在標題中。 從 http://www.lindevdoc.org/wiki/SIGTTIN 看到的資料如下: The SIGTTIN signal is sent to a process when it attempts to read from the terminal but is not in the foreground group . By default, this signal causes the receiving process to temporarily stop ; the system will automatically reactivate it (with the SIGCONT signal) when its group gets into foreground. However, this signal can be blocked, ignored or caught. 英文很簡單就不多加說明了,可以用 man 7 signal 來觀看相關資料。

為什麼我不太傳福音?

以一個基督徒來說,這個標題很怪。基督徒應該是一天到晚叫人要信主的才是,用基督徒的話來說,這叫作「大使命」。 太28:19 所以,你們要去,使萬民作我的門徒,奉父、子、聖靈的名給他們施洗(或作:給他們施洗,歸於父、子、聖靈的名)。 太28: 20 凡我所吩咐你們的,都教訓他們遵守,我就常與你們同在,直到世界的末了。 我不是不知道這個耶穌的吩咐,也很了解到保羅所說的:「我若不傳福音,我就有禍了。」這些經文我都知道,但我還是不太傳福音,為什麼? 因為我不知道怎麼跟人傳講福音。的確,我上過多少次傳福音的課程,的確,我也了解福音的內容。但就是愈了解,才發現,我愈不知道怎麼跟人溝通這個福音。念理工科的人總會想辦法用邏輯、理論來說服人,就因為這樣,所以我不知道怎麼傳。那身為理工人的我又怎麼能信呢?原因只有一個,那就是我信上帝。我找不到一個和非基督徒(或是說不信上帝的人)對話的平台可能。 舉例來說,現在很多同性戀者在高喊同性戀合法化,並且將性向定義為人權的一部份。為什麼基督徒要說同性戀是錯誤的行為呢?追根究底,只有一個理由,就是 神看這個是不好的 。當然,我知道有很多的人,努力的從社會、經濟、生態等各式各樣的方面來分析同性戀不好的理由,但是,對基督徒來說,這些都是其次,最重要的只有一點, 神看這是不好的 。(當然囉,也有些「基督徒」努力的找出聖經的根據說聖經並不反對同性戀,但如果跟這種人對話,起碼還有聖經當作準則可以對話,討論),我要怎麼跟不信主的人說,「因為神說同性戀是不對的,所以同性戀是不對的」? 同樣的,當我在傳福音的時候,「跟對方說,你有罪,你需要救恩」又有誰能聽的下去?「誰定我為有罪」「上帝」「我又不信祂」,那要怎麼傳呢?我不是不知道很多人用見證、詩歌的方式來傳遞福音,從張德培到現在的林書豪,可是我不喜歡這樣。為著這些在職場上有表現的基督徒感謝主,但卻不希望帶給人成功神學的錯誤觀念。那怎麼辦? 也因此,我真的認為,有人信主,這真是神蹟了。耶穌說:「 一個邪惡淫亂的世代求看神蹟,除了先知約拿的神蹟以外,再沒有神蹟給他們看。 」約拿的神蹟可以解釋成在魚腹中待了三天,象徵著主耶穌從死裡復活這樣的神蹟,但我有時候在想,未嘗不可以解釋成神親自動工,轉變尼尼微人的心思意念,離開惡道,不然,約拿傳那什麼樣的信息啊? 當然,我不是不知道,上面洋洋灑灑的寫了一...

20121208 南京堂伉儷團契福音短講:賜平安的基督

這是在伉儷團契的福音短講內容,理論上應該是逐字稿,但其實有脫稿演出以及緊張遺漏的部份。紀錄如下,希望以後能有所進步,將福音講的更清楚。 1 你平安嗎? 在眾多的聖誕詩歌裏面,最有名的一首聖誕大概是「平安夜」吧!「 平安夜,聖善夜!萬暗中,光華射,照著聖母也照著聖嬰,多少慈祥也多少天真,靜享天賜安眠,靜享天賜安眠。 」這真是一副非常安祥的畫面。可是在現在的時代,就算是在這樣一個應當歡慶聖誕節的月份,還感受的到多少平安的氣氛呢? 先不管什麼以色列和巴勒斯坦的戰爭、敘利亞的內亂這些國際間的戰事,這些感覺離我們太遠了!就回到我們自己身上好了,我們真的感覺的到平安嗎?最近我妻子懷孕,所以有時候我們兩個人會討論一些關於小孩的問題,包含了要學哪些技能啊、哪些才藝啊,哪些東西可以自己教,哪些東西要去上補習班,學區哪裡比較好,要怎麼選擇老師啊,甚至有時候討論的愈來愈遠,考慮到未來的經濟情勢,小孩應該要到哪裡發展比較好呢?歐洲那麼多國家瀕臨破產、美國也在財政懸崖上,台灣的部份似乎也好不到哪裡去,這麼多著名的公司說倒就倒,也一大堆裁員的問題。與其說是為了小孩的競爭力擔心,不如說是擔心小孩有沒有辦法在未來生存的下去,這還不包括說要擔心這個小孩會不會發生意外、生病、發燒等,天曉得這個小孩還裝在我老婆的肚子裡還沒出生呢!有時候想想,這似乎不該替我那位出生的孩子擔心,這些問題好像應該先為自己擔心吧!這麼多的擔憂,這麼多對未來的不確定性,這還能稱有平安嗎?怎麼辦呢? 平安夜、聖善夜。其實,在耶穌誕生的馬槽那裡,哪來的平靜安祥?不但有動物的吵雜聲,馬利亞和約瑟他們手忙腳亂的處理新生兒,還有幾個牧羊人跑來湊熱鬧,這是一幅多麼慌亂的景象,如稱的上是「平安夜」呢?是,這還是平安夜,不是因為景象,不是因為氣氛,乃是那位賜平安的神,耶穌基督,親自來到人間,所以我們基督徒稱這個夜晚是平安夜,而也只有這位耶穌基督可以帶給人真正的平安。 2 出人意外的平安 vs. 人的平安 耶穌說:「 我留下平安給你們;我將我的平安賜給你們。...。你們心裡不要憂愁,也不要膽怯。 」,聽起來真不錯,但如果你熟悉聖經的話,你可能會覺得這句話好像漏了點什麼。事實上,我也真的漏掉中間的那一句話,那句話是「 我所賜的(平安),不像世人所賜的。 」 ,什麼叫作不像世人所賜的,難道這和一般人認定的平安不一樣嗎?。聖經中還有另外一處經文跟這...

如何做個好的測試工程師

你心目中的測試工程師是做什麼的?或許很多人的答案是「 按照測試文件的步驟進行,並且產出報告 」。事實上,我相信這是大部分的老闆心中所想像的畫面,無怪乎想到測試工程師的時候都直接聯想到廉價的工作(恩,聽說某家科技公司把所有的QA部門都裁了 ...)。講真的,這樣想的人,也太小看測試工程師了。下面我列出我心中對測試工程師的標準,這樣以後再有新進同事近來擔任測試工程師的時候可以拿來當作教材。話先說在前面,這只是我個人的經驗所整理出來的文章,所以難免會有缺漏,以後有想到的話再補充吧(還要加上我有動力的話 ... ) 要做出有用、明確的報告。 什麼叫作有用、明確的報告?先講一下我之前的故事(之前好像也在 Blog 提過了,不過發生過很多遍,人物也都不同)。有人找我處理電腦上的問題(這似乎是念CS的原罪),只留下一句話:「電腦無法上網了,會不會是中毒了啊?」 這是我最討厭聽到的問題! (不過已經見怪不怪了,所以還是可以控制情緒)為什麼討厭這樣的問題,因為理由太多了!!就好像跟醫生說肚子痛,可能發生的原因從脹氣、拉肚子,一直到胃癌都有可能,一句肚子痛,你是要醫生給你什麼答案。電腦無法上網,可能是電信公司的問題(我最常 推卸 的對象,真是對不起電信公司,不過這可以讓我用最短的時間結束對話)、網路設定問題、家用網路設備的問題,當然也有可能是中毒。那不公平,一般人沒有相關的專業知識啊,所以醫生要負責做檢查的工作!沒錯,醫生要負責做檢查, 在軟體產品上,做檢查的責任就是在測試工程師身上 。 我在這邊說的報告,不是那種紙本,要寫的很囉哩囉唆滿足客戶需求的那種文件(當然這個技能非常重要),而是在跟開發工程師回報的時候,要很明確的講出到底發生了什麼狀況!死亡信息(Log)有哪些?是 Kernel Panic 還是 Segmentation Fault? 請不要以一句「系統掛了」來總結所有的 Bug! 並且還要根據 Log 做出初步的判斷,不要把開機以來的幾千行 Log 看也不看就直接貼給開發工程師。 這不公平,我只是小小的測試工程師,我又搞不懂那些 Log 在寫什麼,整個產品的功能是什麼、架構如何?Well,一般來說,Log 寫的是英文吧?雖然我不否認很多開發工程師,包含我在內,Log寫的很爛,但還是可以讀吧?不了解整個產品?那你憑什麼擔任測試工程師?要重複操作,我找個國中生來就好了。測...

UDP Broadcast Socket Programming Example

今天要紀錄的程式是 UDP Broadcast Socket Programming。其實理論上只要設定 Option 就好了,根本不需要把整個程式碼放上來,但是呢?因為之前紀錄了 TCP 的 Socket Programming,因為偷懶沒有寫一個  UDP 的版本,所以就用這東西來代替吧! Server: # include < stdio.h > // for printf() and fprintf() # include < sys/socket.h > // for socket(), bind(), and connect() # include < arpa/inet.h > // for sockaddr_in and inet_ntoa() # include < stdlib.h > // for atoi() and exit() # include < string.h > // for memset() # include < unistd.h > // for close() # include < fcntl.h > // for fcntl() # include < errno.h > # include < sys/epoll.h > # define BUFSIZE 1024 // Size of receive buffer static int make_socket_non_blocking ( int sfd ) { int flags , s ; flags = fcntl ( sfd , F_GETFL , 0 ) ; if ( flags = = - 1 ) { perror ( " fcntl " ) ; return - 1 ; } ...