私は私が持っているptマスターを通して安定してループを繰り返す方法を見つけようとしています。いつものようにptmxを開き、権限を与え、ロックを解除します。
* ptmx stuff */
/* get the master (ptmx) */
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
if(masterfd < 0){
perror("open");
exit(EXIT_FAILURE);
};
/* grant access to the slave */
if(grantpt(masterfd) < 0){
perror("grantpt");
exit(EXIT_FAILURE);
};
/* unlock the slave */
if(unlockpt(masterfd) < 0){
perror("unlockpt");
exit(EXIT_FAILURE);
};
comms_in->ptmx = masterfd;
次に、スレーブの名前を保存します(たとえば、sizeof(char)は常に1であることを知っています)。
/* get the path to the slave */
char * slavepathPtr;
char * slavePath;
size_t slavepathLen;
if((slavepathPtr = ptsname(masterfd)) == NULL){
perror("ptsname");
exit(EXIT_FAILURE);
}else{
slavepathLen = strlen(slavepathPtr);
slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1));
strcpy(slavePath, slavepathPtr);
};
次に、(getoptsを使用してそのプログラムへの引数として提供される)/dev/pts/number
スレーブ()への予測可能な名前のシンボリックリンクを作成し、への呼び出しを使用してその権限が安全であることを確認し、プログラムを実行し続けることができます。確認してください。シンボリックリンクをかけてスレッドを終了します。/dev/custom/predictable
access
lstat
readlink
symlink
unlink
最後に、プログラムはこのループに入ります。
ssize_t read_result;
ssize_t write_result;
while(1){
if((read_result = read(comms_in->ptmx, ptmxio_read_buffer, sizeof ptmxio_read_buffer)) <= 0){
{ /** calls thread ender routine */
pthread_mutex_lock(&COMMS_MUTEX);
comms_in->thread_statuses[PTMXIO_THREAD] = THREAD_FAILED;
pthread_mutex_unlock(&COMMS_MUTEX);
pthread_cond_signal(&SIG_PROGRAM_FINISHED);
pthread_exit((void *) comms_in);
}
}else if((write_result = write(STDOUT_FILENO, ptmxio_read_buffer, read_result)) != read_result){
{
/** same as above */
}
};
};
システムでこのプログラムを実行でき、すべてが正常です。ブロックを読んでください。cu
pts シンボリックリンクを使用またはオープンすると、内側picocom
またはカーネル側のバッファ制限のうち、下側までバイトが正常に読み取られます。問題は、スレーブがシャットダウンしたときに発生します。この時点で、読み取りはエラーテキストと共に-1
->を返し、スレッドとループを終了しないことを選択した場合、それを続けるため、多くのCPU時間を消費します。または、1つしかない場合は、バイトが利用可能になるまで読み取りが再びブロックされます。シンボリックリンクにリダイレクトする場合、バッファより少なく満たされると、読み込みはバッファを取得し、再び続行されます。 -> 。EIO
Input/output error
cu
picocom
echo -en "some text" > /dev/pts/number
-1
EIO
どうなりますか?低速の組み込みアプリケーションプロセッサで実行され、バイト損失なしで読み取りをリセットできるようにするため、CPUをあまり使用しない方法が必要です。
私はこれを呼び出すスレッドを見つけました。
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...})
そして、この3つのオプションが私のLinuxヘッダーのどこにもなかったので、何がわかりませんでした。これは/3
です。comms_in->ptmx
masterfd
以下は、シンボリックリンクのlstatといくつかの追加情報です。 st_mode は、読み込みの成功と失敗の前後に変更されないままです。
‘ptmxio_thread’ failed read (-1) on /dev/pts/13 /dev/pts/13: Input/output error
‘ptmxio_thread’ ptsNum (from ioctl) 13
‘ptmxio_thread’ st_dev: 6, st_ino: 451, st_mode: 0000A1FF, st_nlink: 1
‘ptmxio_thread’ st_uid: 000003E8, st_gid: 000003E8, st_rdev: 0, st_size: 11
‘ptmxio_thread’ st_blksize: 4096, st_blocks: 0, st_atime: 1540963806, st_mtime: 1540963798
‘ptmxio_thread’ st_ctime: 1540963798
ベストアンサー1
とても簡単です。マスターを処理するプログラムでは、スレーブのptyハンドルを開いて開いたままにする必要があります。
名前を得たらそれptsname(3)
ですopen(2)
。
私はこれを呼び出すスレッドを見つけました。
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...})
そして、この3つのオプションが私のLinuxヘッダーのどこにもなかったので、何がわかりませんでした。3
を参照してくださいcomms_in->ptmx / masterfd
。
ioctl(TCGETS)
はい、tcgetattr(3)
とも呼ばれます。とで定義されています。これは以前のバージョンのバグによるものです。isatty(3)
ptsname(3)
/usr/include/asm-generic/ioctls.h
SNDCTL*
SNDRV*
strace
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
プログラムを不必要に移植不能にすることは意味がありません。代わりに使用してくださいposix_openpt(3)
。
slavepathLen = strlen(slavepathPtr); slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1)); strcpy(slavePath, slavepathPtr);
それがstrdup(3)
目的です;-)
read()
また、信号によって妨げられることも処理する必要があります。完全にあなた(およびあなたが呼び出すすべてのライブラリ関数)がSA_RESTART
。