终端编程详解
终端编程详解
1. tcgetattr()
与 tcsetattr()
功能:获取或设置终端的属性(包括输入/输出模式、控制字符定义等)。
#include <termios.h>
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
参数说明:
• fd
:终端设备的文件描述符(如 /dev/tty
)。
• termios_p
:指向 termios
结构体的指针,用于存储或传递终端属性。
• optional_actions
(仅 tcsetattr
):决定何时应用新设置,可选宏:
• TCSANOW
:立即生效。
• TCSADRAIN
:等待当前输出完成后再生效。
• TCSAFLUSH
:清空输入/输出缓冲区后生效。
termios
结构体成员:
struct termios {
tcflag_t c_iflag; // 输入模式标志(如输入奇偶校验、回车处理)
tcflag_t c_oflag; // 输出模式标志(如输出映射、延迟处理)
tcflag_t c_cflag; // 控制模式标志(如波特率、数据位)
tcflag_t c_lflag; // 本地模式标志(如回显、信号处理)
cc_t c_cc[NCCS]; // 控制字符数组(如中断、停止字符)
};
返回值:
• 成功时返回 0
,失败返回 -1
并设置 errno
。
2. ioctl()
功能:执行设备相关的控制操作(如获取终端窗口大小、设置串口参数等)。
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ... /* void *arg */);
参数说明:
• fd
:终端设备的文件描述符。
• request
:控制请求码,与终端相关的常见宏:
• TIOCGWINSZ
:获取终端窗口大小(arg
指向 winsize
结构体)。
• TIOCSWINSZ
:设置终端窗口大小。
• TCGETS
:等效于 tcgetattr
。
• TCSETS
:等效于 tcsetattr
。
• arg
:可变参数,通常为指向数据结构的指针。
winsize
结构体成员:
struct winsize {
unsigned short ws_row; // 终端窗口行数
unsigned short ws_col; // 终端窗口列数
unsigned short ws_xpixel; // 水平像素(通常未使用)
unsigned short ws_ypixel; // 垂直像素(通常未使用)
};
返回值:
• 成功时返回 0
,失败返回 -1
并设置 errno
。
3. cfsetispeed()
与 cfsetospeed()
功能:设置终端的输入/输出波特率。
#include <termios.h>
int cfsetispeed(struct termios *termios_p, speed_t speed);
int cfsetospeed(struct termios *termios_p, speed_t speed);
参数说明:
• termios_p
:指向 termios
结构体的指针。
• speed
:波特率宏,如:
• B0
:挂断线路。
• B9600
:9600 波特。
• B115200
:115200 波特。
• B4000000
:自定义高速波特率(部分系统支持)。
返回值:
• 成功返回 0
,失败返回 -1
。
4. tcsendbreak()
功能:在串行线上发送 BREAK 信号(用于重置设备)。
#include <termios.h>
int tcsendbreak(int fd, int duration);
参数说明:
• fd
:终端设备的文件描述符。
• duration
:BREAK 持续时间(若为 0
,则持续至少 0.25 秒)。
返回值:
• 成功返回 0
,失败返回 -1
并设置 errno
。
5. tcdrain()
功能:阻塞进程,直到所有输出数据传递到终端。
#include <termios.h>
int tcdrain(int fd);
参数说明:
• fd
:终端设备的文件描述符。
返回值:
• 成功返回 0
,失败返回 -1
并设置 errno
。
6. tcflush()
功能:刷新终端的输入/输出队列。
#include <termios.h>
int tcflush(int fd, int queue_selector);
参数说明:
• fd
:终端设备的文件描述符。
• queue_selector
:刷新目标队列的宏:
• TCIFLUSH
:刷新输入队列。
• TCOFLUSH
:刷新输出队列。
• TCIOFLUSH
:刷新输入和输出队列。
返回值:
• 成功返回 0
,失败返回 -1
并设置 errno
。
7. tcflow()
功能:暂停或恢复终端与计算机之间的数据传输。
#include <termios.h>
int tcflow(int fd, int action);
参数说明:
• fd
:终端设备的文件描述符。
• action
:控制操作的宏:
• TCOOFF
:挂起输出。
• TCOON
:恢复输出。
• TCIOFF
:发送 STOP 字符(暂停输入)。
• TCION
:发送 START 字符(恢复输入)。
返回值:
• 成功返回 0
,失败返回 -1
并设置 errno
。
8. tcgetpgrp()
与 tcsetpgrp()
功能:获取或设置终端的前台进程组ID。
#include <termios.h>
pid_t tcgetpgrp(int fd);
int tcsetpgrp(int fd, pid_t pgrp);
参数说明:
• fd
:终端设备的文件描述符。
• pgrp
:要设置的进程组ID(仅 tcsetpgrp
需要)。
返回值:
• tcgetpgrp
返回前台进程组ID。
• tcsetpgrp
成功返回 0
,失败返回 -1
。
9. tcgetsid()
功能:获取终端的会话ID。
#include <termios.h>
pid_t tcgetsid(int fd);
参数说明:
• fd
:终端设备的文件描述符。
返回值:
• 成功返回会话ID,失败返回 (pid_t)-1
并设置 errno
。
系统调用的底层实现
上述库函数最终通过系统调用与内核交互。以 ioctl
为例,其底层通过 int 0x80
(x86)或 syscall
(x86-64)触发中断,参数通过寄存器传递:
• eax
:系统调用号(如 SYS_ioctl
)。
• ebx
:文件描述符 fd
。
• ecx
:请求码 request
。
• edx
:可变参数指针 arg
。
参考资料: