나는 내가 가지고 있는 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 시간을 소비하게 됩니다. 또는 하나만 있는 경우 바이트 를 사용할 수 있을 때까지 읽기가 다시 차단됩니다. 심볼릭 링크로 리디렉션하는 경우 버퍼보다 적게 채워지면 읽기는 버퍼를 가져오고 다시 계속 진행됩니다. -> .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
.