`

linux 系统编程学习笔记一

阅读更多

文件与i/o


汇编程序的hello world
.data #section
declaration


msg:
.ascii "hello world!\n" #our dear
string
len= . - msg #length of our
dear string


.text #section
declaration
#we must export the entry


point to the ELF linker or
.global _start #loader.they conventionally
recognize _start as their
#entry point. use ld -e foo to
override the default.


_start:
#write our string to stdout
movl $len,%edx #third argument:
message length
movl $msg,%etc #second argument:
pointer to message to write
movl $1,%ebx #first argument: file
handle(stdout)
movl $4,%eax #system call number
(sys_write)
int $0x80 #call kernel
#and exit
movl $0,%ebx #first argument:exit
code
movl $1,%eax #system call number
(sys_exit)
int $0x80 #call kernel


汇编:as -o hello.c hello.s
链接:ld -o hello hello.o
运行:./hello


以上代码等同于以下c代码:
#include <stdio.h>
char msg[14]="hello world!\n";
#define len 14


int main(void){
write(1,msg,len);
_exit(0);
}


c标准I/O与unbuffered I/O函数
c标准I/O用系统调用实现
fopen(3) 调用open打开文件,返回一个文件描述符,分配一个FILE结构体
fgetc(3) 通过传入的FILE参数,检查能否从I/O缓冲区读到下一个字符,如果
能就直接读,否则就调用read(2),把文件描述符传进去,让内核读取该文件
到I/O缓冲区
fputc(3) 同上,如果i/o缓冲区已满就调用write(2),把缓冲区内容写入文件
fclose(3) 如果缓冲区有未写入,则调用write(2)写回文件,然后调用close(2)关闭文
件,释放结构体和缓冲区


open\read\write\close等系统函数为无缓冲I/O(unbuffered I/O)


文件描述符:文件描述符表中的索引
每个进程linux内核都有一个task_struct结构体来维护进程相关信息,即进程描述符


(process descriptor) 或是进程控制块(pcb process control block)
task_struct中有一个指针指向files_struct结构体,称为文件描述符表


当调用open打开一个或创建一个新文件时,内核分配一个文件描述符返回给用户,
文件描述符表中的指针指向新打开文件


程序启动会打开三个文件:
标准输入stdtin 文件描述符为0
标准输出stdout 1
标准错误输出stderr 2
在头文件unistd.h中定义
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2






open/close
open打开或创建一个文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*返回新分配的文件描述符,出错返回-1*/
/*
pathname 文件名
flag常数值
必选项
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 可读可写
可选项
O_APPEND 追加
O_CREAT 文件不存则创建
O_EXCL
O_TRUNC 如果文件已存在,且以只写或可读可写打开,则将其长度截断为0字节
*/
int open(const char *pathname,int flags);
/*mode指定文件权限,可用八进制表示,0644表示-rw-r--r--
文件的权限由open的mode参数和当前进程的umask掩码决定
*/
int open(const char *pathname,int flags,mode_t mode);


close 关闭一个打开的文件
#include <stdio.h>
/*成功返回0
fd为文件描述符
*/
int close(int fd);






read/write


read 从打开的文件或设备中读取数据
#include <unistd.h>
/*成功返回字节数,出错返回顾-1,如果在调用前已到达文件末尾,返回0*/
/*count 表示请求读取的字节数
buf 数据保存缓冲区
ssize_t 表示有符号的size_t
*/
ssize_t read(int fd,void *buf,size_t count);


write 向打开的设备或文件中定数据
#include <unistd.h>
/*返回值通常等于count*/
ssize_t write(int fd,const void *buf,size_t count);


示例代码:
从终端读数据再写回终端
#include <unistd.h>
#include <stdlib.h>


/*阻塞读终端*/
int main(void){
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;
}








运行结果:
yuezhenhua@ubuntu:/opt/sdk/tc$ gcc test40.c -o test40
yuezhenhua@ubuntu:/opt/sdk/tc$ ./test40
hello
hello
yuezhenhua@ubuntu:/opt/sdk/tc$ ./test40
hello world
hello worlyuezhenhua@ubuntu:/opt/sdk/tc$ d
d:找不到命令


执行过程:
shell进程创建test40进程,test40开始执行,shell进程睡眠等待test40退出
test40调用read时睡眠等待,直到终端设备输入换行符才从read返回,read只读取10个字符
剩余的字符仍然保存在内核的终端设备输入缓冲区中
test40进程打印并退出,这时shell进程恢复运行,从终端设备读取用户输入的命令
于是读走了终端设备输入缓冲区中剩余的字符d和换行符,把它当作一条命令解释执行


监视多个设备
while(1){
非阻塞read(设备一);
if(设备一有数据到达){
处理数据;
}
非阻塞read(设备二);
if(设备二有数据到达){
处理数据;
}
/*延迟一会儿再查询*/
sleep(n);
}
注:select(2)函数可以在阻塞的同时监视多个设备






#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#define MSG_TRY "try again\n"


/*非阻塞读终端*/
int main(void){
char buf[10];
int fd,n;
fd=open("/dev/tty",O_RDONLY|O_NONBLOCK);
if(fd<0){
perror("open file /dev/tty");
exit(1);
}
tryagain:
n=read(fd,buf,10);
if(n<0){
if(errno==EAGAIN){
sleep(1);
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;
}




#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>


#define MSG_TRY "try again\n"
#define MSG_TIMEOUT "timeout\n"


/*非阻塞读终端和等待超时*/
int main(void){
char buf[10];
int fd,n,i;
fd=open("/dev/tty",O_RDONLY|O_NONBLOCK);
if(fd<0){
perror("open file /dev/tty");
exit(1);
}
for(i=0;i<5;i++){
n=read(fd,buf,10);
if(n>=0){
break;
}
if(errno!=EAGAIN){
perror("read /dev/tty");
exit(1);
}
sleep(1);
write(STDOUT_FILENO,MSG_TRY,strlen(MSG_TRY));
}
if(i==5){
write(STDOUT_FILENO,MSG_TIMEOUT,strlen(MSG_TIMEOUT));
}else{
write(STDOUT_FILENO,buf,10);
}
close(fd);
return 10;
}

分享到:
评论

相关推荐

    linux系统编程笔记

    Linux系统编程笔记涉及到的内容广泛,涵盖了从基础的出错处理到进程管理,从内存管理到进程间通信,以及守护进程设计等多个层面的知识。下面详细说明各个部分的知识点: 1. 常见出错处理 - abort函数用于异常终止...

    Linux系统设计-Linux系统编程学习笔记

    Linux系统在科学计算、数据分析和机器学习等领域也有广泛应用。许多知名的科学计算软件都在Linux上开发和运行,Linux系统在各个领域都有广泛的应用,其强大的功能和灵活性使得它成为许多产品和服务的基础架构。

    Linux系统编程学习笔记

    ### Linux系统编程学习笔记 #### 一、IO **1.1 标准I/O (stdio)** - **fopen/fclose**: `fopen` 用于打开或创建一个文件,并返回一个指向该文件的 `FILE *` 类型的指针。`fclose` 用于关闭由 `FILE *` 指向的文件...

    Linux Shell编程学习笔记

    Linux Shell编程学习笔记

    linux 系统编程 尚观 linux内核驱动开发 笔记

    【Linux 系统编程与内核驱动开发笔记】 在深入探讨Linux系统编程和内核驱动开发之前,我们首先要理解Linux操作系统的基本概念。Linux是一种自由、开放源码的类Unix操作系统,广泛应用于服务器、桌面环境以及各种...

    Linux零基础学习笔记 Shell编程-菜鸟入门(超详细)

    Linux是开源的操作系统,它的命令行界面,尤其是Shell编程...因此,无论你是技术小白还是希望进一步提升,这份“Linux零基础学习笔记 Shell编程-菜鸟入门”都会是你宝贵的资源。祝你在学习的道路上越走越远,不断进步!

    Linux系统设计-linux系统网络编程学习笔记

    Linux系统在科学计算、数据分析和机器学习等领域也有广泛应用。许多知名的科学计算软件都在Linux上开发和运行,Linux系统在各个领域都有广泛的应用,其强大的功能和灵活性使得它成为许多产品和服务的基础架构。

    linux编程学习笔记PDF资料下载.txt

    根据提供的文件信息,我们可以推断出这是一份关于Linux编程学习笔记的PDF资料。下面将对这份资料可能涉及的关键知识点进行详细的阐述。 ### Linux编程基础知识 #### 1. Linux操作系统概述 - **定义与特点**:Linux...

    linux系统编程及网络编程笔记

    总的来说,"Linux系统编程及网络编程笔记"会详细解析上述各个方面,包括理论知识、实际示例和最佳实践,旨在帮助学习者深入理解Linux环境下的系统编程和网络编程,为开发高效、安全的系统级应用程序和网络服务打下...

    linux网络编程学习笔记

    不过由于系统的兼容性,我们一般不用这个头文件,而使用另外一个结构(struct sock addr_in) 来代替.在&lt;linux/in.h&gt;;中有 sockaddr_in 的定义 struct sockaddr_in{ unsigned short sin_family; unsigned short int ...

    Linux系统设计-linux 编程环境学习笔记,含 linux 基本命令,linux 操作系统,linux 下 C++ 编程等

    Linux系统在科学计算、数据分析和机器学习等领域也有广泛应用。许多知名的科学计算软件都在Linux上开发和运行,Linux系统在各个领域都有广泛的应用,其强大的功能和灵活性使得它成为许多产品和服务的基础架构。

    linux从做系统学习笔记

    网络管理是Linux系统的另一个亮点,这部分的学习笔记涉及网络的基础知识,如IP地址、域名、路由、网关、端口、网卡等概念。网络命令的使用,如测试网络连通性的命令,以及显示和配置网络信息的命令,都是网络管理中...

    Linux系统设计-Linux系统编程笔记

    Linux系统在科学计算、数据分析和机器学习等领域也有广泛应用。许多知名的科学计算软件都在Linux上开发和运行,Linux系统在各个领域都有广泛的应用,其强大的功能和灵活性使得它成为许多产品和服务的基础架构。

    Linux系统编程笔记1

    【Linux系统编程笔记1】 在Linux系统编程中,掌握命令行基础是至关重要的。`date`命令用于显示系统当前的时间,这在编写脚本或记录日志时非常有用。你可以通过`cat /etc/shells`来查看系统中可用的shell列表,而`...

    我的linux编程学习笔记(一).pdf

    我的linux编程学习笔记(一).pdf

    linux项目工程资料-linux系统网络编程学习笔记.zip

    Linux项目是一个开放源代码的操作系统项目,由林纳斯·托瓦兹(Linus Torvalds)于1991年首次发布。该项目以Linux内核为核心,围绕其构建了一个完整的操作系统,包括各种系统工具、库、应用程序和硬件支持。 以下是...

Global site tag (gtag.js) - Google Analytics