1、库函数和系统调用函数

Linux上可以用C语言的文件操作函数(fopen   fread   fwrite   fclose   fseek)(库函数)

但是Linux系统有自己的文件操作函数(open   read   write   close   lseek   stat)(系统调用函数)

库函数:把功能进行封装,封装成库函数,用不同的语言库就不一样。(eg:libc pritf函数,libstdc,stl),在用户态调用,在用户态执行,但是有些库函数需要转系统调用函数。

系统调用:操作系统内核代码提供给用户的接口,调用在用户态,执行在内核态。

应用程序既可以用库函数,也可以用系统调用函数。

2、Linux文件操作函数

在Linux上查看函数的说明文档用man命令

man   1    ls   查看命令

man   2   open   查看系统调用

man   3   fopen   查看库函数

(1)文件操作函数头文件

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

(2)open函数,打开文件

int open(const char *filename, int flags, mode_t mode);返回值:小于0出错(一般为-1),大于等于零为文件描述符fd

filename:文件名(路径)

flags打开方式,有O_RDONLY(只读), O_WRONLY(只写), O_RDWR(读写),O_APPEND(追加),O_CREAT(创建,如果文件存在无作用,如果不存在就创建新文件,如果不设置该方式没有文件返回失败),组合使用O_RDWR|O_CREAT

mode:创建文件时指定文件的权限。

(3)read函数,读数据

int read(int fd, void *buf, size_t count);

fd:文件描述符,由open返回值指定

buf:指定读取数据存储的起始地址,逻辑地址

count:一次读取的字节数(小于缓冲区大下)

返回值:大于0表示读取的字节数,等于0表示读取完,小于0表示读取失败 (一般为-1)

(4)write函数,写入数据

int   write(int  fd,  const  void  *buf, size_t count);

fd:文件描述符,由open返回值指定;

buf:写入数据的起始地址。

count:写入数据的长度,字节数。ssize_t有符号整数;size_t无符号整数

返回值:大于表示写入的字节数,0表示没有写入任何数据,小于0表示写入失败。(一般为-1)

(5)lseek函数,移动文件指针

int lseek(int fd, int size, int flag); 

fd:文件描述符

size:移动偏移量,移动大小

flag:移动标记,移动读写偏移量。SEEK_SET文件开始位置,SEEK_CUR表示指针当前位置,SEEK_END文件结束位置

返回值:大于等于0表示离文件开始处的偏移量,小于0表示写入失败。(一般为-1)

附:该函数可用于扩容,比如 lseek(fd,100,SEEK_END);表示扩容100个字节,但是要执行一次写操作扩容才生效。

(6)close函数,关闭打开的文件

int   close(int   fd);

fd:指定文件描述符

返回值:-1出错,0成功。

(7)stat函数,获取文件属性函数

int stat(const char *path, struct stat *buf); //path文件路径;buf传出参数,获取的文件信息就在buf里面

int fstat(int fd, struct stat *buf); //fd文件描述符

int lstat(const char *path, struct stat *buf); //lstat和stat的区别只在于符号链接文件,lstat读取符号链接文件,stat读取符号链接对应的源文件

返回值:成功返回0;失败返回-1

eg:创建一个文件a.txt,写入hello  world,再读出hello   world。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
	int fd = open("./a.txt",O_RDWR|O_CREAT,0664);//open后文件指针都在起始位置
	assert(fd!=-1);

	char buff[128]="hello world";
	write(fd,buff,strlen(buff));

	lseek(fd,0,SEEK_SET);//从起始位置移动0个字节,移到文件开始

	char readbuff[128]={0};
	read(fd,readbuff,127);

	printf("readbuff: %s\n",readbuff);
	close(fd);

	exit(0);

}

每一个系统调用函数都有一个系统调用号。

当我们调用一个函数的时候会发生几件事:

1、触发0X80中断,中断处理程序在内核中执行,通过中断陷入内核。

内核中有一个系统调用表,用于系统中断处理程序,作为跳转表。

在系统调用表中可以找到系统调用函数,系统调用函数接收参数,操作系统底层实现函数内容。

2、保存当前进程运行状态

3、将系统调用号保存到eax寄存器中,eax寄存器是一个通用寄存器。

4、系统返回的值由eax寄存器带回。

linux直接调用lua中函数_#include