Commit d730b301 authored by Léo Grange's avatar Léo Grange
Browse files

add some termios flags and ioctls to get/set termios struct

parent 8ee82f35
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -64,9 +64,77 @@ struct termios {
#define ECHOCTL		(1<<9)


/**
 * Flags for input mode (c_iflag field)
 */
#define BRKINT		(1<<0)
#define ICRNL		(1<<1)
#define IGNBRK		(1<<2)
#define IGNCR		(1<<3)
#define IGNPAR		(1<<4)
#define INLCR		(1<<5)
#define INPCK		(1<<6)
#define ISTRIP		(1<<7)
#define IXANY		(1<<8)
#define IXOFF		(1<<9)
#define IXON		(1<<10)
#define PARMRK		(1<<11)


/**
 * Baud rate (internaly set in c_cflag lower byte)
 */
#define BAUD_MASK	(0xFF<<0)
#define B0			0x00
#define B50			0x01
#define B75			0x02
#define B110		0x03
#define B134		0x04
#define B150		0x05
#define B200		0x06
#define B300		0x07
#define B600		0x08
#define B1200		0x09
#define B1800		0x0A
#define B2400		0x0B
#define B4800		0x0C
#define B9600		0x0D
#define B19200		0x0E
#define B38400		0x0F
// TODO non-POSIX, faster baud rates


/**
 * Flags for control modes (c_cflag field)
 */
#define CLOCAL		(1<<8)
#define CSIZE		(3<<9)
#define CS5			(0<<9)
#define CS6			(1<<9)
#define CS7			(2<<9)
#define CS8			(3<<9)
#define CSTOPB		(1<<11)
#define HUPCL		(1<<12)
#define PARENB		(1<<13)
#define PARODD		(1<<14)


/**
 * Flags for output mode (c_oflag field)
 * Everything is defined as XSI extension by POSIX, and not implemented.
 */
#define OPOST		(1<<0)


// IOCTL namespace
#define TTYCTL			IOCTL_NAMESPACE('T', 'T')

/**
 * Get/set the termios struct of a TTY (same as Linux ioctls)
 */
#define TCGETS			IOCTL_R( TTYCTL, 0x0008, const struct termios *)
#define TCSETS			IOCTL_W( TTYCTL, 0x0009, struct termios *)

/**
 * Get/set the window size if available.
 */
+7 −9
Original line number Diff line number Diff line
@@ -16,9 +16,9 @@ static const struct termios _tty_default_termios = {
		0,		// VTIME
	},

	.c_iflag = 0,
	.c_iflag = ICRNL | IGNBRK | IGNPAR,
	.c_oflag = 0,
	.c_cflag = 0,
	.c_cflag = CLOCAL | CS8 | B9600,
	.c_lflag = ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | ECHOCTL
};

@@ -27,25 +27,23 @@ int tty_ioctl(struct tty *tty, int cmd, void *data) {
	switch(cmd) {
		case TIOCGWINSZ:
			return tty_getwinsize(tty, data);
			break;
		case TIOCSWINSZ:
			return tty_setwinsize(tty, data);
			break;
		case TIOCSCTTY:
			return tty_setctty(tty, (int)data);
			break;
		case TIOCNOTTY:
			return tty_noctty(tty);
			break;
		case TIOCGPGRP:
			return tty_getpgrp(tty, data);
			break;
		case TIOCSPGRP:
			return tty_setpgrp(tty, data);
			break;
		case TIOCGSID:
			return tty_getsid(tty, data);
			break;
		case TCGETS:
			*(struct termios*)data = tty->termios;
			return 0;
		case TCSETS:
			return tty_set_termios(tty, data);
		default:
			return -EFAULT;
	}
+18 −0
Original line number Diff line number Diff line
@@ -62,6 +62,14 @@ struct tty_ops {
	int (*ioctl_setwinsize)(struct tty *tty, const struct winsize *size);
	int (*ioctl_getwinsize)(struct tty *tty, struct winsize *size);

	/**
	 * Called when termios value should be changed.
	 * If non-null, this callback should check and *set* the accepted value
	 * in tty->termios before returning.
	 * Partially accepted change behavior is implementation defined.
	 */
	int (*set_termios)(struct tty *tty, const struct termios *queried);

	// last chance to flush output from a TTY (e.g. after a oops)
	int (*force_flush)(struct tty *tty);
};
@@ -154,6 +162,16 @@ extern inline int tty_getsid(struct tty *tty, pid_t *sid) {
}


extern inline int tty_set_termios(struct tty *tty, const struct termios *ios)
{
	if(tty->ops->set_termios != NULL) {
		return tty->ops->set_termios(tty, ios);
	}
	tty->termios = *ios;
	return 0;
}


/**
 * Used to dispatch tty-level ioctls using tty->ops and tty data.
 * return special value -EFAULT if ioctl is not tty-level command