0

concurrency: file appending

ans: ssh มันจะเขียนไฟล์ .ssh/known_hosts2
ถ้า ssh หลายๆ process ไปหลายๆ เครื่องเป็นครั้งแรกพร้อมๆ กัน, มันจะเขียนไฟล์ known_hosts ทับกัน จนเจ๊ง มั้ยวะ
veer: โอว
ans: ผมลอง strace ssh version 2.9 ไม่เห็นมัน lock file known_hosts2 เลย.
veer: อ่อ

ans: แต่มัน open append mode
แล้วก็มัน เขียนแต่ละบรรทัด ด้วย write() ในครั้งเดียว
ถ้า write() ในครั้งเดียว ก็เป็น atomic อยู่แล้ว
ans: ก็ไม่เจ๊ง
ans: แต่อาจเกิดการเขียน key ซ้ำกัน พร้อมๆ กัน ทำให้มี บรรทัดซ้ำใน known_hosts ได้ (race condition?)
ans: แต่รู้สึกว่า append mode ใน windows จะไม่ใช่ real append, คือ แค่เปิดไฟล์ปกติแล้วเลื่อน cursor ไปท้ายสุด. ถ้าไม่ใช่ real append ก็ทำให้เกิดการเขียนทับกันได้, ถึงแม้ write() จะเป็น atomic ก็ตาม.
veer: โอว
veer: ผมเอาไปใส่ blog นะครับ
ans: yes

4

แก้ปัญหา C++ บน x86-64

ปัญหา C++ เบา x86-64 ก็คงจะมีได้หลายๆ อย่างแต่ที่ผมเจอคือ

(unsigned int)string.find(“…”) == string::npos()

พอเอา (unsigned int) ออกก็ใช้ได้เลย :-P. กว่าจะเจอแทบแย่ เจอ method ยาว แบบ 300 บรรทัด มี if มี while ซ้อนๆ กันงงๆ หน่อย.

0

gtest + autotools (2)

จาก 3 ตอนที่แล้ว

  1. googletest + autotools
  2. สร้าง library เพื่อ test unit
  3. make check

ทำให้มีโครงๆ แบบเกือบใช้ gtest ได้อยู่แล้ว เหลือแต่แก้ Makefile.am นิดๆ หน่อย + กับเขียน sample1.cpp อีก

แก้ Makefile.am เป็นแบบนี้:

INCLUDES = -I$(top_srcdir)
AM_CPPFLAGS = $(GTEST_CPPFLAGS) # คราวก่อนลืมใส่ include path เลยเติมซะ
AM_LDFLAGS = $(GTEST_LDFLAGS) -lgtest_main # link กับ libgtest_main ที่จะไปเรียก test case ทั้งหมดให้
TESTS = sample1
check_PROGRAMS = sample1
sample1_SOURCES = sample1.cpp
sample1_LDADD = $(top_srcdir)/toto/libtiti.la $(GTEST_LIBS)

อันนี้คือ sample1.cpp

#include
#include

TEST(TitiTest, Happy)
{
EXPECT_EQ(1, 1);
}

เสร็จแล้ว ก็คงมั่วๆ บ้างขออภัย

0

make check

เวลาใช้ autotools คำสั่งที่ผมใช้บ่อยมักจะเป็น ./configure, make และ make install ที่มักจะต้องใช้เวลาเอาโปรแกรมมาติดตั้ง.

make check ไม่ค่อยได้เรียก มาเจอแรกๆ ก็ใน libthai. เห็นใน libthai กับ gtest สร้าง folder ขึ้นมาใส่โปรแกรมสำหรับ test เลยผมก็ทำบ้าง. สร้าง test ขึ้นมาแล้วก็เอา Makefile.am ไปใส่ พร้อมกับ sample1.cpp. ที่สำคัญคือต้องแก้ configure.in และ Makefile.am ใน top folder ด้วย ให้สร้าง/เรียก test/Makefile

ใน test/Makefile.am ผมเขียนแบบนี้ (ส่วนมากเป็นท่าที่ลอก libthai มา)

TESTS = sample1 #อันนี้บอกว่า test อะไรบ้าง

# ข้างล่างนี้บอกว่าสร้าง test case อย่างไร
check_PROGRAMS = sample1
sample1_SOURCES = sample1.cpp
sample1_LDADD = $(top_srcdir)/toto/libtit.la # บอกว่าจะ test กับ library อะไร

ใน sample1.cpp ผมเขียนว่า:

int main()
{
return 0;
}

เวลาเรียก make check ก็ผ่านหมด ถ้า return 1 ก็จะ fail แทน

1

สร้าง library เพื่อ test unit

ทีแรกโปรแกรมที่ผมใช้ link กับกลายเป็น executable file ไฟล์เดียวเลย อาจจะทำให้เขียน test unit ยาก (อีกนัยหนึ่งคือผมทำไม่เป็นนั่นเอง) ผมเลยจะสร้างส่วนหนึ่งเป็น library ก่อน.

สมมุติว่าเดิมมี executable file ชื่อ toto (ตั้งตามอ.อานนท์)

Makefile.am ก็จะหน้าตาประมาณ
INCLUDES = -I$(top_srcdir)
bin_PROGRAMS = toto
toto_SOURCES = toto_shell.cpp titi.cpp tata.cpp

แต่ผมก็จะแยก titi tata ออกมาเป็น libtiti ก็จะเขียนแบบนี้

INCLUDES = -I$(top_srcdir)

# เพื่อสร้าง library
lib_LTLIBRARIES = libtiti.la
libtiti_la_SOURCEs = tit.cpp tata.cpp

bin_PROGRAMS = toto
toto_SOURCES = toto_shell.cpp
toto_LDADD = libtiti.la # บอกว่าใช้ toto ไป link กับ libtiti

เท่านี้ก็แยกกันได้แล้ว แต่ก็ไม่ได้เขียนถึง *.h เลย … เวลา make install แล้วใช้ได้จริง หรือเปล่าก็ไม่รู้ อาจจะต้องทำอะไรต่ออะไรอีก. แน่นอนที่เขียนไปคงมีอะไรมั่วมากมาย. แต่ว่าตอนต่อไปผมก็คงยังไม่ลอง install อยู่ดี แต่เน้นทำ test unit ก่อน คงเขียนเรื่อง make check ^_^.

1

googletest + autotools

ผมอยากลองใช้ googletest ที่เอาไว้ทำ unit test สำหรับ C++ ก่อนหน้าที่จะลองเล่นได้มีปัญหาที่มาดักหน้าคือ จะแก้ configure.in (configure.ac) อย่างไรให้ใช้ gtest ได้.

ท่าง่ายแบบใช้ pkg-config ก็ใช้กับกรณีนี้ไม่ได้ด้วย. พยายามจะใช้ AC_CHECK_LIB แต่ก็ยากเกินไปอ้าง method ของ C++ ไม่รู้ทำไง :-P. แต่ดูไปดูมาก็เจอว่ามี gtest-config พอจะไช้แทน pkg-config ได้ แต่ว่าถ้าใช้แต่ gtest-config ก็ดูท่าจะเขียน configure.in ยาวอีก.

แต่หาไปหามาสักพักก็พบ gtest.m4 เป็นตัวช่วยสำคัญที่ทำสั่ง GTEST_LIB_CHECK ใน configure.in ได้เลย แต่ว่าจะเอา gtest.m4 มาใส่ใน aclocal.m4 ได้อย่างไร ผมก็ลืมไปแล้ว ไม่ได้ใช้นาน หรือว่าผมไม่เคยทำเป็นเลย ไม่ค่อยแน่ใจ. แต่หาไปหามาก็พบว่าสั่ง aclocal -I $HOME/gtest-1.1.0/m4 ได้เลย ^_^ (ผมเอา gtest ไว้ใน $HOME อะนะครับ).

พอเรียก configure แล้วก็ได้ข้อความประมาณนี้ออกมา

checking for gtest-config… /home/veer/bin/gtest-config
checking for Google Test… yes

น่าจะใช้ได้แล้วมั้ง ต่อไปก็แก้ Makefile.am แล้วก็เขียน test case (ที่จะลองต่อไป)

0

Changelog และชื่อ contributor

ทีแรกว่าจะเขียนเรื่อง alignment แบบใช้ space น้อยๆ แต่มันยาวต้องวาดภาพอีกเลยเอาไว้ก่อน. เข้าไปดูเรื่อง Changelog อยากดูว่าต้องเขียนแบบไหน ก็พบข้อผิดพลาดของผมอย่างหนึ่ง ที่ผิดไปจาก GNU Coding Standards. แน่นอนใครๆ ไม่จำเป็นต้องทำตาม GNU Coding Standards, แต่ว่าผมพยายามจะทำ.

เวลามีคน contribute เข้ามาใน program ที่ผมดูแลอยู่ เขามักจะไม่ได้เขียน Changelog มาให้ด้วย. ผมก็เลยต้องมาเขียนให้. ปกติผมจะทำแบบนี้

2008-04-04 Vee Satayamas <v_________@gmail.com>

* titi.c: do something by Who <who@where___.com>

พอมาอ่าน http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html ก็พบเลยว่าไม่ถูกแล้ว. ควรชื่อ contributor ขึ้นไปข้างบนเลยแบบข้างล่างนี้

2008-04-04 Who <who___@where___.com>

* titi.c: do something

รู้ style ที่ถูกแล้ว ช่วงนี้ project ที่ผม maintain ไม่ค่อยมีใคร contribute อะไรมาเท่าไหร่เลย :-P. ของเดิมอาจจะใช้ดีอยู่แล้ว? หรือไม่ก็อาจจะห่วยจนชาวบ้านเลิกใช้ไปแล้ว … ก็เลยยังไม่ได้ลองสักที.