Solaris10でGNU Screenがコンパイルできない

Solaris10上でGNU Screenをコンパイルしようとするとエラーになる件。

$ ./configure --enable-pam --enable-locale --enable-colors256 --enable-rxvt_osc --enable-telnet --with-sys-screenrc=/etc
$ make
CPP="gcc -E " srcdir=. sh ./osdef.sh
AWK=nawk CC="gcc -g -O2" srcdir=. sh ./comm.sh
AWK=nawk srcdir=. sh ./term.sh
gcc -c -I. -I.    -g -O2 screen.c
gcc -c -I. -I.    -g -O2 ansi.c
gcc -c -I. -I.    -g -O2 fileio.c
gcc -c -I. -I.    -g -O2 mark.c
gcc -c -I. -I.    -g -O2 misc.c
misc.c: In function `xsetenv':
misc.c:619: error: too few arguments to function `setenv'
*** Error code 1
make: Fatal error: Command failed for target `misc.o'

few arguments to functionと言っているのが何でかなぁと・・・
ともあれmisc.cの619行目の定義らしいので、その辺りを見てみる。
616  # if defined(linux) || defined(__convex__) || (BSD >= 199103)
617    setenv(var, value, 1);
618  # else
619    setenv(var, value);
620  # endif /* linux || convex || BSD >= 199103 */
617行目と619行目の違いに注目。
617行目はsetenv( var, value, 1 )と3つの引数が与えられているのに対し、619行目はsetenv( var, value )と2つの引数しか与えられていない。たぶん鍵は616行目にあって、プリプロセッサが、linuxと、BSDの場合はsetenv( var, value, 1 )が、それ以外の場合はsetenv( var, value )が使われるようだ。
で、Solarisの場合、気になるもの。の Solaris 10 の setenv(3C), unsetenv(3C)によると
そういえば、昔は setenv(3C), unsetenv(3C) は、Standard C Library Functions として用意されていなかった気がしたので、ちょっと確認。
Solaris 8, Solaris 9 には、提供されていない。
Solaris 10 からみたい。
Solaris 10 の new feature として、announce あったっけ・・・
適当な source を見つけられないなぁ(´・ω・`)
という事で、もともとSolaris9まではsetenv()自体が提供されていなかったようだ。
で、
setenv(3c)/unsetenv(3c) は UNIX2003 仕様準拠により、Solaris 10 から libc によりサポートされるようになりました。
という事らしい。

tjmiuraの日記にも

どっちかっつうと、misc.cの619行目

setenv(var, value);

編集しちゃうよりは、この部分をくくってる条件マクロの方を編集するべきではないかと。

diff -ur screen-4.0.3.org/misc.c screen-4.0.3/misc.c
--- screen-4.0.3.org/misc.c 2003-12-05 22:45:41.000000000 +0900
+++ screen-4.0.3/misc.c 2008-07-21 17:55:44.950202000 +0900
@@ -613,7 +613,7 @@
*/
# endif /* NEEDSETENV */
#else /* USESETENV */
-# if defined(linux) || defined(__convex__) || (BSD >= 199103)
+# if defined(linux) || defined(__convex__) || (BSD >= 199103) || defined(__sun__)
setenv(var, value, 1);
# else
setenv(var, value);

補足すると、Solarissetenv(3C)が備わったのはSolaris10以降なので、SunOSバージョン識別は結局不要で、条件分岐としてはこれでよかった。

Solaris9以前ではputenv(3C)が使われるのでこれまで問題にならなかったわけだ。

とある。

なので、、、件のmisc.cは
616 # if defined(linux) || defined(__convex__) || (BSD >= 199103) || defined(sun)
617   setenv(var, value, 1);
618 # else
619   setenv(var, value);
620 # endif /* linux || convex || BSD >= 199103 || sun */
こう書き換えるのが正しいようだ。

最終的にmisc.cを上記のように書き換えて、
$ LDFLAGS="-m64" CPPFLAGS="-m64 -O3" CFLAGS="-m64 -O3" ./configure --prefix=/usr/local --enable-pam --enable-locale --enable-colors256 --enable-rxvt_osc --enable-telnet --with-sys-screenrc=/etc
$ gmake
# sudo gmake install
でインストールができた。(※例によって64ビット・バイナリでインストールしている。32ビット・バイナリの場合はLDFLAGS、CPPFLAGS、CFLAGSの設定は不要)