アカウント名:
パスワード:
GNUのyesコマンドと対照的なのがOpenBSDのyesコマンドのソース [openbsd.org]。
ご覧のとおり見たまんまで、まったく捻りなし。
特徴的なのが、実行開始時にpledgeというシステムコールを発効しているところ。これを行うことで、それ以降のシステムコールの実行を標準入出力関連のものだけに制限している。もしyesに脆弱性があっても、それを利用した悪さができにくいようになっている。
改善というのは高性能化だけではない、ってことですな。
楽しいね。この単純なプログラムでさえ、システムコールを制限しようとする姿勢が。
FreeBSDはどうなんだろう、と思ってみたらちょっと長くて [openbsd.org]読んでない。
リンクミスった。FreeBSDのは こっち。 [github.com] ちなみにやってることはOpenBSD + バッファ使った性能向上かなあ。斜め読みというか、斜め見した感じ。
ちなみにminix 2.0.4のyesは以下。yes[n++]= '\n';ってなんでやってるんだろう。argv[1]って最後に終端はいるよね?
/* yes 1.4 - print 'y' or argv[1] continuously. Author: Kees J. Bot * 15 Apr 1989 */#include #include #include #include
int main(int argc, char **argv){ char *yes; static char y
|yes[n++]= '\n';ってなんでやってるんだろう。|argv[1]って最後に終端はいるよね?
その終端がヌルターミネータだから改行を追加しているのでは。
ヌルターミネータを上書きして大丈夫なのかと一瞬思ったが、writeで長さ指定してた。
yes[n++]= '\n';ってなんでやってるんだろう。
これがないと出力が改行なし ("yyyyy...") になっちゃいますね。
なるほど。意味がわかったでござる。
tmiura氏のNULL Terminatorの話も、説明されてわかった。\0 を \nで上書きしていると。writeだから\0はいらないわけね。
plegdeは良いと思うけれど、同じ意味のfor(;;) puts()が繰り返されるのが嫌だな。私はV7の三項演算子使ったやつの方が好き。
最適化されない気がする。引数が処理中に書き換わる可能性がゼロじゃないと。
argc>1の評価はmain()の呼出毎に不変だから現代のコンパイラなら最適化されるよ。
main(argc, argv)char **argv;{ char *p = argc>1? argv[1]: "y";
for (;;) printf("%s\n", p);}
みたいな感じに解釈されると思う。
OpenBSDを-O付きでコンパイルする奴は素人
ど素人の質問で恐縮だけど、現代のコンパイラはそのサンプルコードのprintf()が行っている文字列代入も最初の一回しか行わないよう最適化してくれるの?
上のコードをgcc -O3でコンパイルするとこんな風に最適化される
main(argc, argv)char **argv;{ if (argc>1) { for (;;) puts(argv[1]); } else { for (;;) { puts("y"); puts("y"); } }}
printf自体が無駄だと判断してputsに置き換えてるみたい
「printf()が行っている文字列代入」って何のことだろう。sprintf系ならそう表現するのも分からなくはないが、fprintfやprintfは書式指定を解釈して出力先のストリームに書き込む動作だから、引数を除けば出力先のストリームが持つバッファリング処理でしかどこかに格納される事はないよ。
printfによる書式の処理が一回だけになるのか、って意味なら、ライブラリが静的リンクでリンク時最適化が掛かればワンチャンあるかも程度でほぼ期待できないかと。
printfをインラインにしてくれるstdio.hとかあるんだろうか。あればもうちょい期待出来るが・・・あるのか?
おお、printfの中身までちゃんとバラすんだ。どういう方法でライブラリ関数を展開しているんだろう。
OpenBSD って if や for の後が単文なら {} つけない流儀?
Kernel source file style guide (KNF) [openbsd.org]
No braces are used for control statements with zero or only a single statement unless that statement is more than a single line, in which case they are permitted.
OpenBSDカーネルのコーディングスタイルではそのように決まっているので、ユーザランドもそれに倣っていると思われます。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
ソースを見ろ -- ある4桁UID
対照的なのが (スコア:5, 興味深い)
GNUのyesコマンドと対照的なのがOpenBSDのyesコマンドのソース [openbsd.org]。
ご覧のとおり見たまんまで、まったく捻りなし。
特徴的なのが、実行開始時にpledgeというシステムコールを発効しているところ。
これを行うことで、それ以降のシステムコールの実行を標準入出力関連のものだけに制限している。
もしyesに脆弱性があっても、それを利用した悪さができにくいようになっている。
改善というのは高性能化だけではない、ってことですな。
Re: (スコア:0)
楽しいね。
この単純なプログラムでさえ、システムコールを制限しようとする姿勢が。
FreeBSDはどうなんだろう、と思ってみたらちょっと長くて [openbsd.org]読んでない。
Re: (スコア:0)
リンクミスった。
FreeBSDのは こっち。 [github.com]
ちなみにやってることはOpenBSD + バッファ使った性能向上かなあ。
斜め読みというか、斜め見した感じ。
ちなみにminix 2.0.4のyesは以下。
yes[n++]= '\n';ってなんでやってるんだろう。
argv[1]って最後に終端はいるよね?
/* yes 1.4 - print 'y' or argv[1] continuously. Author: Kees J. Bot
* 15 Apr 1989
*/
#include
#include
#include
#include
int main(int argc, char **argv)
{
char *yes;
static char y
Re:対照的なのが (スコア:2)
|yes[n++]= '\n';ってなんでやってるんだろう。
|argv[1]って最後に終端はいるよね?
その終端がヌルターミネータだから改行を追加しているのでは。
ヌルターミネータを上書きして大丈夫なのかと一瞬思ったが、writeで長さ指定してた。
Re:対照的なのが (スコア:2)
これがないと出力が改行なし ("yyyyy...") になっちゃいますね。
Re: (スコア:0)
なるほど。
意味がわかったでござる。
tmiura氏のNULL Terminatorの話も、説明されてわかった。
\0 を \nで上書きしていると。
writeだから\0はいらないわけね。
Re: (スコア:0)
plegdeは良いと思うけれど、同じ意味のfor(;;) puts()が繰り返されるのが嫌だな。
私はV7の三項演算子使ったやつの方が好き。
Re:対照的なのが (スコア:2)
Re: (スコア:0)
最適化されない気がする。引数が処理中に書き換わる可能性がゼロじゃないと。
Re: (スコア:0)
argc>1の評価はmain()の呼出毎に不変だから現代のコンパイラなら最適化されるよ。
main(argc, argv)
char **argv;
{
char *p = argc>1? argv[1]: "y";
for (;;)
printf("%s\n", p);
}
みたいな感じに解釈されると思う。
Re: (スコア:0)
OpenBSDを-O付きでコンパイルする奴は素人
Re: (スコア:0)
ど素人の質問で恐縮だけど、現代のコンパイラはそのサンプルコードのprintf()が行っている文字列代入も最初の一回しか行わないよう最適化してくれるの?
Re:対照的なのが (スコア:1)
上のコードをgcc -O3でコンパイルするとこんな風に最適化される
main(argc, argv)
char **argv;
{
if (argc>1) {
for (;;)
puts(argv[1]);
} else {
for (;;) {
puts("y");
puts("y");
}
}
}
printf自体が無駄だと判断してputsに置き換えてるみたい
Re: (スコア:0)
「printf()が行っている文字列代入」って何のことだろう。
sprintf系ならそう表現するのも分からなくはないが、
fprintfやprintfは書式指定を解釈して出力先のストリームに書き込む動作だから、
引数を除けば出力先のストリームが持つバッファリング処理でしかどこかに格納される事はないよ。
printfによる書式の処理が一回だけになるのか、って意味なら、
ライブラリが静的リンクでリンク時最適化が掛かればワンチャンあるかも程度でほぼ期待できないかと。
printfをインラインにしてくれるstdio.hとかあるんだろうか。あればもうちょい期待出来るが・・・あるのか?
Re: (スコア:0)
おお、printfの中身までちゃんとバラすんだ。
どういう方法でライブラリ関数を展開しているんだろう。
Re: (スコア:0)
OpenBSD って if や for の後が単文なら {} つけない流儀?
Re:対照的なのが (スコア:2)
Kernel source file style guide (KNF) [openbsd.org]
No braces are used for control statements with zero or only a single statement unless that statement is more than a single line, in which case they are permitted.
OpenBSDカーネルのコーディングスタイルではそのように決まっているので、ユーザランドもそれに倣っていると思われます。