read(2) blocking behaviour changes when pts is closed resulting in read() returning error: -1 (EIO)
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
I'm trying to figure out how I can reliably loop a read on a pt master I have.
I open the ptmx, grant and unlock it as per usual:
* 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;
Next I save the slave's name (yes I know sizeof(char) is always 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);
;
I then create a predictably named symlink to the slave (/dev/pts/number
) in /dev/custom/predictable
(which was provided as an argument to this program using getopts) and verify that its permissions are safe using calls to access
, lstat
, readlink
, symlink
and confirm that the program can continue execution, otherwise it calls unlink
on the symlink and terminates the thread.
Finally the program ends up in this loop
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 */
;
;
On the system, I can run this program and all is swell.
The read blocks.
When the pts symlink is opened with cu
or picocom
then bytes are successfully read up to the buffer limits either on my end or the kernel's end, depending on who's lower.
The problem comes when the slave is closed.
At this point, the read returns -1
-> EIO
with error text: Input/output error
and will continue to do so, consuming a lot of cpu time if I choose to not terminate the thread and loop.
When cu
or picocom
or even just an echo -en "some text" > /dev/pts/number
, the read blocks again, until bytes are available. In the case of the redirection into the symlink, obviously if it fills less than a buffer, read just gets that one buffer and continues to return -1
-> EIO
again.
What's going on? I need a method that doesn't consume a lot of CPU as this runs on a slow embedded application processor and allows me to re-establish reads without losing bytes.
I noticed a thread making a call to this:ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, B38400 opost isig icanon echo ...)
and can't make much sense of what the 3 options are as they're not in my Linux headers anywhere.. Note that 3
is comms_in->ptmx
/ masterfd
.
read pts
add a comment |Â
up vote
0
down vote
favorite
I'm trying to figure out how I can reliably loop a read on a pt master I have.
I open the ptmx, grant and unlock it as per usual:
* 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;
Next I save the slave's name (yes I know sizeof(char) is always 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);
;
I then create a predictably named symlink to the slave (/dev/pts/number
) in /dev/custom/predictable
(which was provided as an argument to this program using getopts) and verify that its permissions are safe using calls to access
, lstat
, readlink
, symlink
and confirm that the program can continue execution, otherwise it calls unlink
on the symlink and terminates the thread.
Finally the program ends up in this loop
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 */
;
;
On the system, I can run this program and all is swell.
The read blocks.
When the pts symlink is opened with cu
or picocom
then bytes are successfully read up to the buffer limits either on my end or the kernel's end, depending on who's lower.
The problem comes when the slave is closed.
At this point, the read returns -1
-> EIO
with error text: Input/output error
and will continue to do so, consuming a lot of cpu time if I choose to not terminate the thread and loop.
When cu
or picocom
or even just an echo -en "some text" > /dev/pts/number
, the read blocks again, until bytes are available. In the case of the redirection into the symlink, obviously if it fills less than a buffer, read just gets that one buffer and continues to return -1
-> EIO
again.
What's going on? I need a method that doesn't consume a lot of CPU as this runs on a slow embedded application processor and allows me to re-establish reads without losing bytes.
I noticed a thread making a call to this:ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, B38400 opost isig icanon echo ...)
and can't make much sense of what the 3 options are as they're not in my Linux headers anywhere.. Note that 3
is comms_in->ptmx
/ masterfd
.
read pts
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm trying to figure out how I can reliably loop a read on a pt master I have.
I open the ptmx, grant and unlock it as per usual:
* 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;
Next I save the slave's name (yes I know sizeof(char) is always 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);
;
I then create a predictably named symlink to the slave (/dev/pts/number
) in /dev/custom/predictable
(which was provided as an argument to this program using getopts) and verify that its permissions are safe using calls to access
, lstat
, readlink
, symlink
and confirm that the program can continue execution, otherwise it calls unlink
on the symlink and terminates the thread.
Finally the program ends up in this loop
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 */
;
;
On the system, I can run this program and all is swell.
The read blocks.
When the pts symlink is opened with cu
or picocom
then bytes are successfully read up to the buffer limits either on my end or the kernel's end, depending on who's lower.
The problem comes when the slave is closed.
At this point, the read returns -1
-> EIO
with error text: Input/output error
and will continue to do so, consuming a lot of cpu time if I choose to not terminate the thread and loop.
When cu
or picocom
or even just an echo -en "some text" > /dev/pts/number
, the read blocks again, until bytes are available. In the case of the redirection into the symlink, obviously if it fills less than a buffer, read just gets that one buffer and continues to return -1
-> EIO
again.
What's going on? I need a method that doesn't consume a lot of CPU as this runs on a slow embedded application processor and allows me to re-establish reads without losing bytes.
I noticed a thread making a call to this:ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, B38400 opost isig icanon echo ...)
and can't make much sense of what the 3 options are as they're not in my Linux headers anywhere.. Note that 3
is comms_in->ptmx
/ masterfd
.
read pts
I'm trying to figure out how I can reliably loop a read on a pt master I have.
I open the ptmx, grant and unlock it as per usual:
* 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;
Next I save the slave's name (yes I know sizeof(char) is always 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);
;
I then create a predictably named symlink to the slave (/dev/pts/number
) in /dev/custom/predictable
(which was provided as an argument to this program using getopts) and verify that its permissions are safe using calls to access
, lstat
, readlink
, symlink
and confirm that the program can continue execution, otherwise it calls unlink
on the symlink and terminates the thread.
Finally the program ends up in this loop
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 */
;
;
On the system, I can run this program and all is swell.
The read blocks.
When the pts symlink is opened with cu
or picocom
then bytes are successfully read up to the buffer limits either on my end or the kernel's end, depending on who's lower.
The problem comes when the slave is closed.
At this point, the read returns -1
-> EIO
with error text: Input/output error
and will continue to do so, consuming a lot of cpu time if I choose to not terminate the thread and loop.
When cu
or picocom
or even just an echo -en "some text" > /dev/pts/number
, the read blocks again, until bytes are available. In the case of the redirection into the symlink, obviously if it fills less than a buffer, read just gets that one buffer and continues to return -1
-> EIO
again.
What's going on? I need a method that doesn't consume a lot of CPU as this runs on a slow embedded application processor and allows me to re-establish reads without losing bytes.
I noticed a thread making a call to this:ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, B38400 opost isig icanon echo ...)
and can't make much sense of what the 3 options are as they're not in my Linux headers anywhere.. Note that 3
is comms_in->ptmx
/ masterfd
.
read pts
read pts
asked 11 mins ago
Supernovah
1063
1063
add a comment |Â
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f478815%2fread2-blocking-behaviour-changes-when-pts-is-closed-resulting-in-read-return%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password