Mandriva Linux 2009.1でGNU screenのRPMパッケージが再ビルドできない件とその対処(後半)
「Mandriva Linux 2009.1でGNU screenのRPMパッケージが再ビルドできない件とその対処(前半)」の続き。
C言語のprintf()関数のフォーマット引数に関する実験
まずはソースを用意。ファイル名: nofmtargtest.c
#include <stdio.h> #include <stdlib.h> /* * gcc -Wall -Wformat -Werror=format-security nofmtargtest.c -o nofmtargtest && echo OK || echo NG * gcc -Wall nofmtargtest.c -o nofmtargtest */ int main (int argc, char *argv[]) { char str[] = "Hello, Work!!\n"; printf ("FooBar\n"); /* OK */ printf (str); /* NG */ return EXIT_SUCCESS; }
これをコンパイルしようとすると
gcc -Wall -Wformat -Werror=format-security nofmtargtest.c -o nofmtargtest && echo OK || echo NG nofmtargtest.c: In function ‘main’: nofmtargtest.c:12: error: フォーマットは非文字列リテラルで、且つフォーマット引数を持ちません NG
となる。1つ目のprintf()は直接ダブルクォートされた文字列(リテラル)を指定しているので問題はないが、次の行がダメになっている。
そこで試しに後ろにNULLを付けてみることにした。
ファイル名: nullfmtargtest.c
#include <stdio.h> #include <stdlib.h> /* * gcc -Wall -Wformat -Werror=format-security nullfmtargtest.c -o nullfmtargtest && echo OK || echo NG */ int main (int argc, char *argv[]) { char str[] = "Hello, Work!!\n"; printf ("FooBar\n"); /* OK */ printf (str, NULL); /* OK */ return EXIT_SUCCESS; }
今度はビルドができた。
gcc -Wall -Wformat -Werror=format-security nullfmtargtest.c -o nullfmtargtest && echo OK || echo NG OK $ ./nullfmtargtest FooBar Hello, Work!!
ソースへの修正
GNU screenのソースに対しては、screen.c中の「, strnomem);」という文字列を「, strnomem, NULL);」に全置換することで解決した。同様に幾つかのソースファイルでも置換が必要となった(要領は全て同じ)。対象の.specファイルではconfigureスクリプトの実行後にPerlを用いて幾つかの置換処理を行っていたため、それにならって
perl -pi -e 's|, strnomem\);|, strnomem, NULL\);|' screen.c fileio.c misc.c resize.c socket.c window.c termcap.c process.c perl -pi -e 's|, \*cmdv\);|, \*cmdv, NULL\);|' fileio.c display.c perl -pi -e 's|, str\);|, str, NULL\);|' ansi.c perl -pi -e 's|LockEnd\);|LockEnd, NULL\);|' attacher.c
を後ろに付け加えた。
作成したパッケージは別館の配布ページに公開している。
(2014/10/12)配布ページは削除済み。
使用したバージョン:
- GCC 4.3.2