「名前付きパイプを使用したプロセス間通信の概要-名前付きパイプを使用した全二重通信」、link ;を使用して作業しようとしています。特にfd_server.c
(参考のために以下に含まれています)
これが私の情報とコンパイル行です:
:〜$ cat / etc / issue Ubuntu 10.04 LTS \ n \ l :〜$ gcc --version gcc(Ubuntu 4.4.3-4ubuntu5)4.4.3 :〜$ gcc fd_server.c -o fd_server
fd_server.c
2つの名前付きパイプを作成します。1つは読み取り用、もう1つは書き込み用です。できることは、次のとおりです。1つの端末でサーバーを実行し、cat
書き込みパイプを読み取ります(スルーします)。
:〜$ ./fd_server&2> / dev / null [1] 11354 :〜$ cat / tmp / np2
もう1つは、サーバーの読み取りパイプに(echoを使用して)書き込みます。
:〜$ echo "heeellloooo"> / tmp / np1
最初のターミナルに戻ると、次のことがわかります。
:〜$ cat / tmp / np2 HEEELLLOOOO 0[1]+終了13./fd_server2> / dev / null
私がやりたいのは、一種の「インタラクティブ」(または「シェル」のような)セッションを作成することです。つまり、サーバーは通常どおり実行されますが、実行する代わりに、screenに似たものを使用したいと思いcat
ます。つまり、画面はのように呼び出すことができ、ターミナルに入力されたものがに渡され、その応答がターミナルに書き込まれる、一種のインタラクティブセッションを作成します。もちろん、今は使用できません。私の場合、プログラムには2つの別個のノードがあり、私が知る限り、1つしか参照できないためです。echo
screen /dev/ttyS0 38400
/dev/ttyS0
screen
screen
このコンテキストで(2つの別々の読み取り/書き込みパイプを使用して)この種の「対話型」セッションを実現するにはどうすればよいでしょうか。
以下のコード:
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <fullduplex.h> /* For name of the named-pipe */
#define NP1 "/tmp/np1"
#define NP2 "/tmp/np2"
#define MAX_BUF_SIZE 255
#include <stdlib.h> //exit
#include <string.h> //strlen
int main(int argc, char *argv[])
{
int rdfd, wrfd, ret_val, count, numread;
char buf[MAX_BUF_SIZE];
/* Create the first named - pipe */
ret_val = mkfifo(NP1, 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
exit (1);
}
ret_val = mkfifo(NP2, 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
exit (1);
}
/* Open the first named pipe for reading */
rdfd = open(NP1, O_RDONLY);
/* Open the second named pipe for writing */
wrfd = open(NP2, O_WRONLY);
/* Read from the first pipe */
numread = read(rdfd, buf, MAX_BUF_SIZE);
buf[numread] = '0';
fprintf(stderr, "Full Duplex Server : Read From the pipe : %sn", buf);
/* Convert to the string to upper case */
count = 0;
while (count < numread) {
buf[count] = toupper(buf[count]);
count++;
}
/*
* Write the converted string back to the second
* pipe
*/
write(wrfd, buf, strlen(buf));
}
編集:
明確にするために、非常によく似たものについて説明しているドキュメントを見つけたようですが、そこにあるスクリプトの変更です( "たとえば、次のスクリプトはデバイスを構成し、シリアルから受信したすべてのデータをコピーするためのバックグラウンドプロセスを開始します上記のプログラムのデバイスを標準出力に... ")は以下のとおりです。
# stty raw #
( ./fd_server 2>/dev/null; )&
bgPidS=$!
( cat < /tmp/np2 ; )&
bgPid=$!
# Read commands from user, send them to device
echo $(kill -0 $bgPidS 2>/dev/null ; echo $?)
while [ "$(kill -0 $bgPidS 2>/dev/null ; echo $?)" -eq "0" ] && read cmd; do
# redirect debug msgs to stderr, as here we're redirected to /tmp/np1
echo "$? - $bgPidS - $bgPid" >&2
echo "$cmd"
echo -e "\nproc: $(kill -0 $bgPidS 2>/dev/null ; echo $?)" >&2
done >/tmp/np1
echo OUT
# Terminate background read process - if they still exist
if [ "$(kill -0 $bgPid 2>/dev/null ; echo $?)" -eq "0" ] ;
then
kill $bgPid
fi
if [ "$(kill -0 $bgPidS 2>/dev/null ; echo $?)" -eq "0" ] ;
then
kill $bgPidS
fi
# stty cooked
したがって、スクリプトをsayとして保存してstarter.sh
呼び出すと、次のセッションが発生します。
$ ./starter.sh
0
i'm typing here and pressing [enter] at end
0 - 13496 - 13497
I'M TYPING HERE AND PRESSING [ENTER] AT END
0~�.N=�(�~� �����}����@������~� [garble]
proc: 0
OUT
これは私が「対話型セッション」(デバッグステートメントを無視する)と呼ぶものです-サーバーは私がコマンドを入力するのを待ちます。コマンドを受信した後に出力を提供します(この場合のように、最初のコマンドの後に終了し、スタータースクリプトも終了します)。それを除いて、入力をバッファリングせずに、文字ごとに送信したい(つまり、上記のセッションは最初のキーを押した後に終了し、1文字だけを印刷する必要があります-これは私がstty
生で役立つと思っていたものですが、そうではありません:それは両方Enterへの反応を殺すだけですCtrl- C:))
screen
引数として2つの名前付きパイプを受け入れ、それらを介して「ターミナル」または「シェル」のようなセッションを確立する既存のコマンド(シリアルデバイスに関しては似ていると思います)がすでにある場合、私はたださまよっていました。または、上記のようなスクリプトを使用するか、端末として動作する独自の「クライアント」をプログラムする必要があります。