ssize_t read(int fildes, void *buf, size_t nbyte);
返回值:
> 0: 實際讀到的字節數
= 0: 讀完數據(讀文件, 管道, socket末尾-->對端關閉, 對端未關閉會一直等待)
-1: 異常:
errno == EINTR被信號中斷, 重啟或者退出
errno == EAGAIN或者EWOULDBLOCK以非阻塞方式讀, 並且沒有數據
其他值: 出現錯誤perror eixt
ssize_t write(int fildes, const void *buf, size_t nbyte);
返回值: 返回實際寫出的字節數, 0表示什么也沒有寫
阻塞讀終端
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
// 阻塞讀終端
int main(int argc, char const *argv[])
{
char buf[10];
int n;
n = read(STDIN_FILENO, buf, 10);
if (n < 0) {
perror("read STDIN_FILENO");
exit(1);
}
write(STDOUT_FILENO, buf, n);
return 0;
}
非阻塞讀終端
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define MSG_TRY "try again\n"
// 非阻塞讀終端
int main(int argc, char const *argv[])
{
char buf[10];
int fd, n;
// /dev/tty --> 當前打開的終端設備
fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);
if (fd < 0) {
perror("open /dev/tty");
exit(1);
}
tryagain:
n = read(fd, buf, 10);
if (n < 0) {
// 如果write為非阻塞, 但是沒有數據可讀, 此時全局變量errno被設置為EAGAIN
if (errno == EAGAIN) {
sleep(3);
write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
goto tryagain;
}
perror("read /dev/tty");
exit(1);
}
write(STDOUT_FILENO, buf, n);
close(fd);
return 0;
}
阻塞和非阻塞是文件的屬性
默認非阻塞: 普通文件
默認阻塞: 終端設備, 管道, 套接字
