2013/11/27(Wed)
○[386BSD(の子孫)ソースコードシリーズ (334)][な阪関無] sys/cdefs.hとは何ですか? (その12)
@前回まで
続きです(あらすじになってないがもう書くのめんどくさい)。
@__SCCSID() マクロ
前回までに UCB/CSRGが SCCS を使ってバージョン管理を行い、ソースとバイナリにバージョン履歴メタデータを埋め込んでたことを説明しました。
んでNetBSDでは __RCSID()の導入と同じ理由、つまり
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
を書くのがめんどくさいから
#include <sys/cdefs.h>
__SCCSID("@(#)abort.c 8.1 (Berkeley) 6/4/93");
とマクロで書けるようにしようと、表題のマクロを導入したわけです。
…しましたが、実際にソースコードで使用してるところは
淫夢皆無です。
やるやる詐欺 コミットメッセージ。
add __SCCSID() and __SCCSID2() macros for userland, and __KERNEL_SCCSID() for the kernel. They're not used yet, but will be shortly.
この時点ではすでに UCB/CSRG は解散しており、ソースコードリポジトリを継承したのはおそらく、開発者だった魔球先生こと Marshall Kirk McKusick先生らが関わる直系の子孫、BSD/OSですがそっちはプロプラエタリでソースは公開されていないわけで。
もし NetBSD と BSD/OS でソースをシェアできる状況だったのであれば、NetBSD の sys/cdefs.h では
#define __RCSID(_s) __IDSTRING(.ident, _s)
#define __SCCSID(_s)
一方 BSD/OS の sys/cdefs.h では
#define __RCSID(_s)
#define __SCCSID(_s) __IDSTRING(.ident, _s)
とすることでどっちの履歴をバイナリに埋めるかを選択できたわけなんだけどね、獲らぬ狸のなんとやら。
しかも__SCCSID2()まで導入してるんだけど、これ全く説明が無いし書いた本人 *1にしか理由は説明できなさげ、もしかして 3rd Party全てに__SCCSID[0-9]+()するつもりだったんだろうか…
というわけで、とっとと消せばいいと思います(他人事)。
@BSD/OSの最期
余談ですが、BSD/OS のコードの諸権利を有する BSDi社 *2はその後 WindRiver社に買収され、BSD/OSのコードをFreeBSDにフィードバックするような宣言もしてたのですが、結局 BSD/OSの開発中止だかんね、ビジネスは厳しいね。
そのWindRiver社も最近 Intel社に買収されましたな、Intel社にはここは太っ腹でBSD/OSのコードをリポジトリごとジャンジャンバリバリ大開放して頂きたく *3。
ちなみに BSDi社自体は iXsystems社と名前を変えまだ生き残ってるし、魔球先生は FreeBSD の開発者やったり 2013年ベイスターズで1勝してますが。
@__COPYRIGHT() マクロ
Cソースには皆さん見慣れた著作権者表示がファイルの先頭にありますな、例えばこれ。
$ head -n 5 /usr/src/bin/kill/kill.c
/* $NetBSD: kill.c,v 1.27 2011/08/29 14:51:18 joerg Exp $ */
/*
* Copyright (c) 1988, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
そして実はバイナリにもこの著作権者表示は埋め込まれてます。
#include <sys/cdefs.h>
#if !defined(lint) && !defined(SHELL)
__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
これも実装は__RCSID()みたいにバイナリに文字列を埋め込むマクロで、異なるのは
- __COPYRIGHT() は .copyright セクション
- __RCSID(), __SCCSID() は .ident セクション
に埋め込むかの違いだけで、実装はどっちも前回説明した __IDSTRING()及び __SECTIONSTRING()マクロです。
4.4BSDの頃の実装は ここにある通り
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
となってて、SCCSID/RCSIDと同様に最適化で消えちゃうってのも同じです。
注意深い人は NetBSD と 4.4BSD のソースコード見比べて気づくかと思われますが、どっちも先頭「@(#)」ではじまってる SCCS の what(1) でしか扱えない形式で、RCS ident(1)では拾えないことに気づきました?
$ uname -sr
NetBSD 6.1_STABLE
$ what kill
/bin/kill
Copyright (c) 1988, 1993, 1994 The Regents of the University of California. All rights reserved.
$ ident /bin/kill | grep Copyright | wc -l
0
はい what(1) では著作権表示は表示できるんですが ident(1) では出ません。
4.4BSDからNetBSDになって、バージョン管理がSCCSからCVSになったことは前回説明しましたが、ここだけはSCCSのまま放置されてるわけで直した方がいいと思うんだけどね。
そもそもSCCSもRCSもキーワード置換機能に著作権表示があるわけでなくて、これ単純にwhat(1)で引っかけれるよう4.4BSDの頃は「%Z%」キーワード入れただけだと思う。
static char copyright[] =
"%Z% Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
というわけで別にSCCSでないとダメってわけじゃないんで、綺麗な解決策としては copyright(1) とか作ればいいんじゃないかな(適当)、単純にELFから.copyrightを読むツールなんて簡単に作れるわけで。
@BSDライセンスの第2項と __COPYRIGHT() マクロ
そもそもBSDLにはバイナリフォームの場合からも著作権者情報を復元できないとアカン条項ありますやね。
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
なのでこの著作権者情報のメタデータ部分をソースやバイナリから削除したりするとライセンス違反です。
ただし全てのファイルの著作権者情報を出してるわけではないです、binやusr.binなどのアプリケーションについては通常 main 文のあるファイルのみで宣言してます。
/*
* Source code revision control identifiers appear after any copyright
* text. Use the appropriate macros from <sys/cdefs.h>. Usually only one
* source file per program contains a __COPYRIGHT() section.
* Historic Berkeley code may also have an __SCCSID() section.
* Only one instance of each of these macros can occur in each file.
* Don't use newlines in the identifiers.
*/
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
コーディングガイドにもそう書いてありますな。
コーディングガイド的には libc なんかの場合は __COPYRIGHT() は入れないっぽいのですが、なぜか hcreate.cでは宣言されてて、まるで(hcreate.cの作者である) cgd@ ひとりが libc の著作権者かのような状態でワロタ。
$ what /lib/libc.so.12.181
/lib/libc.so.12.181
Copyright (c) 2001 Christopher G. Demetriou. All rights reserved.
そもそもそれすら入れてないくせにBSDLなアプリだって山ほどあります。
$ objdump -s -j .copyright /usr/bin/iconv
/usr/bin/iconv: file format elf64-x86-64
objdump: section '.copyright' mentioned in a -j option, but not found in any input file
はい、Citrus関係のやつ入れ忘れとりますな。つーかこれはコーディングガイドに書いてないのと 新井が悪い。
@もしかして無い場合は自分で入れないとライセンス違反?
んでここでひとつ疑問がわきます、最初からこの__COPYRIGHT()マクロで著作権者情報埋め込んでないものを利用する場合、さっきの
Redistributions in binary form must reproduce the above copyright notice
を厳密に解釈すると、自分で埋め込んどかないとライセンスに抵触するような気がしてきますね、はい。ワイ専門家じゃないので法律的な判断はできかねますがこれどうなんですかね(チラッチラッ。
ワイの心情的にはコードに入れ忘れた権利者が悪いので、あくまで最初に書いた通りソースの__COPYRIGHT()の部分を消したり実行ファイルから.copyrightセクション削ったりしなければいいんじゃね?と思うし、そもそも1-clause BSDLでバイナリ条項削っても問題ないような気がするんだけど。
@次回予告
また今回も__KERNEL_RCSID(), __KERNEL_SCCSID(), __KERNEL_COPYRIGHT() マクロ残ってしまったので、その説明と他未定。