2016-06-15 21 views
1

を離れることなく、「ティー」stdoutとファイルの両方に標準入力からteeコマンドをコピーデータを実装します。 teespliceシステムコールを利用することで、カーネル空間からデータを残すことなくこの機能を実装することができます。 Windowsでteeコマンドを実装するために必要な機能は、データがカーネルスペースを離れることはありませんか?、Linuxではカーネル空間

teeコマンドは、コピーデータがユーザ空間で、私はカーネル空間を残してデータのないファイルストリームを分割する方法を学ぶことに特に興味readopen、およびwriteとの些細な実装がありますが。

+0

「Unix」と「Linux」が混乱していると思います。 ['tee(2)'](http://linux.die.net/man/2/tee)と['splice(2)'](http://linux.die.net/man/2/)スプライス)システムコールはLinux固有のもので、他のUnix版では利用できません。たとえば、Mac OS Xには、マニュアルのセクション2またはセクション3(システムコールまたはライブラリ関数)に 'tee 'も' splice'もありません。通常の 'read'、' write'、 'open'、' close'システムコールで 'tee'(コマンド)を実装します。それについては何も面白くない。それらの、またはそれらの直接のアナログは、Windows上でうまく動作します。 –

+0

OKコメントに基づいて質問を更新しました。私はシステムコールの実例であるので、私はそのコマンドについて言及しました。 – twinlakes

答えて

2

この質問の前提は誤りです。 teeコマンドは、tee()またはsplice()システムコールに依存せず、ゼロコピーではありません。

open file for writing; 
while (read some data from stdin) { 
    write the data to stdout; 
    write the data to the file; 
} 

関与する唯一のシステムコールがopen()read()があり、かつwrite()、およびこれらの呼び出しのWindowsバージョンは、基本的にUNIXのバージョンと同じです:本質的として実装されています。

+0

わかりやすく私の質問を更新しました。この質問は、具体的にはLinuxシステムコールに関する知識をWindowsに移すことに関するものです。コマンド自体は、説明を簡単にするためにのみ使用されています。 – twinlakes

+0

これらの呼び出しをどのように使用するかの例を挙げる必要があります。 'tee'コマンドはそれらを使用することはできません(そして使用することもできません)。同等のWindows呼び出しは、' tee'と 'splice'の正確なアプリケーションに依存する可能性があります。 – duskwuff

+0

'tee'コマンドを' tee'関数で実装できないのはなぜですか?stdinをstdoutとファイル[s]に分割するのはなぜですか? ?カーネルスペースを残さずにファイル記述子を分割したいだけです。 – twinlakes

1

んが、このような機能は、Windowsに組み込まれていないが、それはティーのようなカーネルモードのデバイスドライバを書くために、原理的には可能なはずです。もちろん、は基本的にと同じ方法で、ユーザーモードの実装と同じように動作します。ソースからデータを受け取り、宛先に書き込みます。あなたは、より効率的な読み込み操作を発行するのではなく、teeデバイスに送信される出力としてデータを受け取ることができます。ユーザー/カーネルモードの移行を避けることもできますが、それでもわかりませんどのくらいのパフォーマンスを改善するか

私の推測では、それはおそらく労力価値がないだろうが、おそらくエッジケースがあるということです。

それは疑似ハンドルではなく、本当のハンドルを使用していますように私は、Windowsの古いバージョンのI/Oも、カーネルドライバがコンソールに対処することができたか否かはわかりません。しかし、コンソールI/Oが遅いので、いずれかのエンドポイントがコンソールであれば、ユーザーモードの実装にとどまることもあります。このシナリオではボトルネックにはなりません。

スプライス状カーネルモードデバイスドライバは、また、可能であるべきです。これはおそらく、わずかに異なるAPIを使用していても、ユーザーモードのバージョンとまったく同じ方法で実装されるでしょう。いずれの場合も

、カーネルモードドライバを使用すると、おそらく、それが簡単に効率的に異なるプロセスからの同時ティーおよび/またはスプライスの多くを処理するためになるだろう。ユーザーモードでは、スレッドごとに別々のスレッド、または個別のプロセスで処理する可能性があります。

+0

ありがとうございます。これを達成するためにどのような関数/ APIを研究すべきですか? – twinlakes

+0

「Windowsドライバの使い方」(https://msdn.microsoft.com/en-us/library/windows/hardware/ff554690(v=vs.85).aspx)から始めたいと思うでしょう。 ZwWriteFileを使ってデータを転送先に転送するだけで、ハンドルがソースアプリケーションのコンテキストで開いている場合、DispatchWriteから呼び出すことができるはずです。別のアプリケーションからハンドルを取得する必要がある場合は、ZwDuplicateObjectが役に立ちます。おそらくOBJ_KERNEL_HANDLEオプションが必要です。 (免責事項:私はいくつかのWindowsカーネルモードのプログラミングを行ってきましたが、私は専門家ではありません)。 –

関連する問題