Skip to content

Instantly share code, notes, and snippets.

@Julio-Guerra
Last active June 1, 2016 11:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Julio-Guerra/b3fdefab281403073607d81cabcea04a to your computer and use it in GitHub Desktop.
Save Julio-Guerra/b3fdefab281403073607d81cabcea04a to your computer and use it in GitHub Desktop.
pty in blocking mode with buf <= rx < min
// compilation: gcc -D_GNU_SOURCE -O0 -g -ggdb test.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <termios.h>
#include <unistd.h>
#include <assert.h>
#define TEST_VMIN 5
#define TEST_RECEIVED 4
#define TEST_BUF 3
void set_ncanon(int fd, int min, int time);
void get_pty_pair(int* ptm, int* pts);
void main(void)
{
int e, pts, ptm;
get_pty_pair(&ptm, &pts);
set_ncanon(ptm, 1, 0);
set_ncanon(pts, TEST_VMIN, 0);
e = write(ptm, "anything", TEST_RECEIVED);
assert(e == TEST_RECEIVED);
char buf[TEST_BUF];
int res = read(pts, buf, sizeof (buf));
assert(e > 0);
printf("res=%d buf=%.*s\n", res, TEST_RECEIVED, buf);
}
// set fd in noncanonical mode by modifying the current
// termios settings of fd.
void set_ncanon(int fd, int min, int time)
{
struct termios tio;
tcgetattr(fd, &tio);
tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL
| IXON);
tio.c_oflag &= ~OPOST;
tio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tio.c_cflag &= ~(CSIZE | PARENB);
tio.c_cflag |= CS8;
tio.c_cc[VMIN] = min;
tio.c_cc[VTIME] = time;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &tio);
}
// another way to set fd in noncanonical mode by overwritting current
// termios settings
// void set_ncanon(int fd, int min, int time)
// {
// struct termios tio;
//
// bzero(&tio, sizeof(tio));
//
// tio.c_cflag = B38400 | CRTSCTS | CS8 | CLOCAL | CREAD;
// tio.c_iflag = IGNPAR;
// tio.c_oflag = 0;
// tio.c_lflag = 0;
// tio.c_cc[VTIME] = time;
// tio.c_cc[VMIN] = min;
//
// tcflush(fd, TCIFLUSH);
// tcsetattr(fd, TCSANOW, &tio);
// }
void get_pty_pair(int* ptm, int* pts)
{
int e;
*ptm = open("/dev/pts/ptmx", O_RDWR | O_NOCTTY | O_SYNC);
assert(*ptm > 0);
e = grantpt(*ptm);
assert(e == 0);
e = unlockpt(*ptm);
assert(e == 0);
char* pts_node = ptsname(*ptm);
assert(pts_node != NULL);
*pts = open(pts_node, O_RDWR | O_NOCTTY | O_SYNC);
assert(*pts > 0);
}
@peterhurley
Copy link

// another way to set fd in noncanonical mode by overwritting current
// termios settings
// void set_ncanon(int fd, int min, int time)
// {
// struct termios tio;
//
// bzero(&tio, sizeof(tio));

Never do this.

SUSv4 says this:

Since the termios structure may include additional members, and the standard members may include both standard and non-standard modes, the structure should never be initialized directly by the application as this may cause the terminal to behave in a non-conforming manner.

//
// tio.c_cflag = B38400 | CRTSCTS | CS8 | CLOCAL | CREAD;
// tio.c_iflag = IGNPAR;
// tio.c_oflag = 0;
// tio.c_lflag = 0;
// tio.c_cc[VTIME] = time;
// tio.c_cc[VMIN] = min;
//
// tcflush(fd, TCIFLUSH);
// tcsetattr(fd, TCSANOW, &tio);
// }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment