read(2) blocking behaviour changes when pts is closed resulting in read() returning error: -1 (EIO)“no...
How could empty set be unique if it could be vacuously false
Why isn't my calculation that we should be able to see the sun well beyond the observable universe valid?
Can the pre-order traversal of two different trees be the same even though they are different?
Did the CIA blow up a Siberian pipeline in 1982?
Syntax and semantics of XDV commands (XeTeX)
Is "Busen" just the area between the breasts?
Why is "Congress shall have power to enforce this article by appropriate legislation" necessary?
Is there a term for the belief that "if it's legal, it's moral"?
Drawing a second weapon as part of an attack?
What does this Swiss black on yellow rectangular traffic sign with a symbol looking like a dart mean?
Rejecting an offer after accepting it just 10 days from date of joining
Too early in the morning to have SODA?
What is "industrial ethernet"?
How much steel armor can you wear and still be able to swim?
Why is oilcloth made with linseed oil?
Cut the gold chain
Where should a runway for a spaceplane be located?
How did the Vostok ejection seat safely eject an astronaut from a sealed space capsule?
Do I have to explain the mechanical superiority of the player-character within the fiction of the game?
Second 100 amp breaker inside existing 200 amp residential panel for new detached garage
Can you use one creature for both convoke and delve for Hogaak?
How can I prevent a user from copying files on another hard drive?
Methodology: Writing unit tests for another developer
Is there a difference between an NFC and RFID chip?
read(2) blocking behaviour changes when pts is closed resulting in read() returning error: -1 (EIO)
“no coprocess” error when using readdocumentation on ptmx and pts
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
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
.
Here is an lstat on the symlink and some extra information, note that the st_mode is unchanged before and after successful and unsuccessful reads.
‘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
read pseudoterminal pts
add a comment |
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
.
Here is an lstat on the symlink and some extra information, note that the st_mode is unchanged before and after successful and unsuccessful reads.
‘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
read pseudoterminal pts
add a comment |
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
.
Here is an lstat on the symlink and some extra information, note that the st_mode is unchanged before and after successful and unsuccessful reads.
‘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
read pseudoterminal 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
.
Here is an lstat on the symlink and some extra information, note that the st_mode is unchanged before and after successful and unsuccessful reads.
‘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
read pseudoterminal pts
read pseudoterminal pts
edited Nov 2 '18 at 2:06
mosvy
14k21547
14k21547
asked Oct 31 '18 at 4:48
SupernovahSupernovah
1135
1135
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It's very simple: you should open and keep open a handle to the slave side of the pty in the program handling the master side.
After you got the name with ptsname(3)
, open(2)
it.
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 that3
iscomms_in->ptmx / masterfd
.
ioctl(TCGETS)
is tcgetattr(3)
, which is also called from isatty(3)
and ptsname(3)
. It's defined in /usr/include/asm-generic/ioctls.h
. As to the SND*
, strace
could be a little smarter; you're not going to do sound/oss operations on a pseudo-terminal.
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
There is no point in making your program needlessly unportable. Use posix_openpt(3)
instead.
slavepathLen = strlen(slavepathPtr);
slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1));
strcpy(slavePath, slavepathPtr);
That's what strdup(3)
is for ;-)
And you should also handle your read()
being interrupted by a signal, unless you're absolutely sure you (and all the library functions you call) set all the signal handlers with SA_RESTART
.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
Required, but never shown
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
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It's very simple: you should open and keep open a handle to the slave side of the pty in the program handling the master side.
After you got the name with ptsname(3)
, open(2)
it.
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 that3
iscomms_in->ptmx / masterfd
.
ioctl(TCGETS)
is tcgetattr(3)
, which is also called from isatty(3)
and ptsname(3)
. It's defined in /usr/include/asm-generic/ioctls.h
. As to the SND*
, strace
could be a little smarter; you're not going to do sound/oss operations on a pseudo-terminal.
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
There is no point in making your program needlessly unportable. Use posix_openpt(3)
instead.
slavepathLen = strlen(slavepathPtr);
slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1));
strcpy(slavePath, slavepathPtr);
That's what strdup(3)
is for ;-)
And you should also handle your read()
being interrupted by a signal, unless you're absolutely sure you (and all the library functions you call) set all the signal handlers with SA_RESTART
.
add a comment |
It's very simple: you should open and keep open a handle to the slave side of the pty in the program handling the master side.
After you got the name with ptsname(3)
, open(2)
it.
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 that3
iscomms_in->ptmx / masterfd
.
ioctl(TCGETS)
is tcgetattr(3)
, which is also called from isatty(3)
and ptsname(3)
. It's defined in /usr/include/asm-generic/ioctls.h
. As to the SND*
, strace
could be a little smarter; you're not going to do sound/oss operations on a pseudo-terminal.
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
There is no point in making your program needlessly unportable. Use posix_openpt(3)
instead.
slavepathLen = strlen(slavepathPtr);
slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1));
strcpy(slavePath, slavepathPtr);
That's what strdup(3)
is for ;-)
And you should also handle your read()
being interrupted by a signal, unless you're absolutely sure you (and all the library functions you call) set all the signal handlers with SA_RESTART
.
add a comment |
It's very simple: you should open and keep open a handle to the slave side of the pty in the program handling the master side.
After you got the name with ptsname(3)
, open(2)
it.
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 that3
iscomms_in->ptmx / masterfd
.
ioctl(TCGETS)
is tcgetattr(3)
, which is also called from isatty(3)
and ptsname(3)
. It's defined in /usr/include/asm-generic/ioctls.h
. As to the SND*
, strace
could be a little smarter; you're not going to do sound/oss operations on a pseudo-terminal.
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
There is no point in making your program needlessly unportable. Use posix_openpt(3)
instead.
slavepathLen = strlen(slavepathPtr);
slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1));
strcpy(slavePath, slavepathPtr);
That's what strdup(3)
is for ;-)
And you should also handle your read()
being interrupted by a signal, unless you're absolutely sure you (and all the library functions you call) set all the signal handlers with SA_RESTART
.
It's very simple: you should open and keep open a handle to the slave side of the pty in the program handling the master side.
After you got the name with ptsname(3)
, open(2)
it.
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 that3
iscomms_in->ptmx / masterfd
.
ioctl(TCGETS)
is tcgetattr(3)
, which is also called from isatty(3)
and ptsname(3)
. It's defined in /usr/include/asm-generic/ioctls.h
. As to the SND*
, strace
could be a little smarter; you're not going to do sound/oss operations on a pseudo-terminal.
int32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
There is no point in making your program needlessly unportable. Use posix_openpt(3)
instead.
slavepathLen = strlen(slavepathPtr);
slavePath = (char *) malloc(sizeof(char) * (slavepathLen + 1));
strcpy(slavePath, slavepathPtr);
That's what strdup(3)
is for ;-)
And you should also handle your read()
being interrupted by a signal, unless you're absolutely sure you (and all the library functions you call) set all the signal handlers with SA_RESTART
.
edited 1 hour ago
answered Oct 31 '18 at 19:24
mosvymosvy
14k21547
14k21547
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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
Required, but never shown
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
Required, but never shown
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
Required, but never shown
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
Required, but never shown
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
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown