热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux系统编程——系统函数(调用)

一、简介系统调用:#man2#就是系统调用函数由操作系统实现并提供给外部应用程序的额编程接口(API,applicationprogrammingin

一、简介

系统调用:#man 2 #就是系统调用函数由操作系统实现并提供给外部应用程序的额编程接口(API,application programming interface)。是应用程序同系统之间数据交互的桥梁。linux中真正存在的函数并不和man 2中的系统函数名一致。我们能看到的系统调用(man 2中的)函数是linux内核函数的浅封装。如下图:

在这里插入图片描述

二、系统函数(调用)[文件IO相关]

我们接下来学习的函数严格上叫系统函数(系统调用浅封装),
只有这些函数可以驱动内核,
C语言的fputc等函数实际底层是这些系统函数的又封装。注意:虽然系统函数直接调用内核,但因为缓冲区(详见下图和表)的存在当 单字节 用read、write时没有库函数fopen、fputc拷贝快。内核会有一个4096的缓冲区。用于预读入和缓输出。使用问题:因为种种潜在的问题,例如上面的缓存问题,一般我们编程还是使用库函数,而不是直接使用系统函数。但具体的还是看场景需要。

区别系统函数库函数
缓存无用户级缓冲区有用户级缓冲区
写入内核方式直接与内核对接自身缓冲区满时才将数据推给内核

在这里插入图片描述

  1. open

作用:打开或创建文件。man 2 open //get more information
//在vim命令模式下,光标至于按K直接进入man帮助中
1.function model#include #include #include int open(const char *pathname, int flags); //默认权限打开int open(const char *pathname, int flags, mode_t mode); //指定权限,创建用2.RETURN VALUEopen(), openat(), and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appropri‐ately).3.parameter information1)const char *pathname文件名及其路径。例: ''2)int flagsO_RDONLY, O_WRONLY, or O_RDWR. // These request opening the file read-only, write-only, or read/write, respectively.O_APPEND //open appendO_CREAT //创建文件,需使用参数modeO_EXCL //判断文件是否存在O_TRUNC //截断文件大小为0,就是将文件清空O_NOBLOCK示例:O_RDONLY | O_CREAT | O_TRUNC //存在就只读打开并清空,否则创建 需mode参数3)mode_t mode //八进制的值只在flag参数设置为O_CREAT时才需要使用。4 2 1R W X示例:0666rw-rw-rw-
4.常见错误详见man 2 openDEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/open.c文件。

  1. close

作用:关闭文件描述符。man 2 close
//在vim命令模式下,光标至于按K直接进入man帮助中1.function model#include int close(int fd);2.RETURN VALUEclose() returns zero on success. On error, -1 is returned, and errno is set appropriately.3.parameter1)int fdalready open descriptor ID。DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/open.c文件。

  1. read

man 2 read
//在vim命令模式下,光标至于按K直接进入man帮助中1.NAME:read - read from a file descriptor2.SYNOPSIS#include ssize_t read(int fd, void *buf, size_t count);3.RETURN VALUE0:读到文件末尾成功:读到的字节数失败:-1,并设置errno-1: errno = EAGIN 或 EWOULDBLOCK : read在以非阻塞方式读一个设备文件(或网络文件),但是没数据。需要再次读。EINTR 被异常中断。需要重启。ECONNRESET 连接被重置,需要close(fd),移出(除)监听队列。其他:error。DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/read.c文件。

  1. write

man 2 write
//在vim命令模式下,光标至于按K直接进入man帮助中1.NAMEwrite - write to a file descriptor2.SYNOPSIS#include ssize_t write(int fd, const void *buf, size_t count);3.DESCRIPTIONwrite() writes up to count bytes from the buffer starting at buf to the file referred to by the file descriptor fd.4.RETURN VALUEOn success, the number of bytes written is returned. On error, -1 is returned, and errno is set to indicate the cause of the error.DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/write.c文件。

  1. fcntl

man 2 fcntl
#
#直接修改已打开文件描述符的flags(O_RDONLY, O_WRONLY等)
1.NAMEfcntl - manipulate file descriptor2.SYNOPSIS#include #include int fcntl(int fd, int cmd, ... /* arg */ );3.DESCRIPTIONfcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd.4.parameterF_GETFL:获取文件状态,//当设置此项时不需要再设置argF_SETFL:设置文件状态//当设置此项时需要设置arg,arg为open的flags参数列表中的值//arg的设置涉及位图的概念,位图的每位都是二进制位,相应的每位对应一个flag,位图中标识1为生效,0为不生效。详见下图。//int flgs=fcntl(fd,F_GETFL);//flgs |= O_NONBLOCK;//fcntl(fd,F_SETFL,flgs);
DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/fcntl.c文件。

在这里插入图片描述

  1. lseek

man 2 lseek
1.NAMElseek - reposition read/write file offset2.SYNOPSIS#include #include off_t lseek(int fd, off_t offset, int whence);3.parameterfd //文件描述符offset //偏移量whence //起始偏移位置 SEEK_SET、SEEK_CUR、SEEK_END
4.RETURN VALUEerror : -1success : 较起始位置偏移量
5.应用场景1)对同一文件描述符的“读”、“写”,使用的是同一偏移量.DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/lseek.c文件。2)使用lseek获取文件大小,DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/lseek_getfilesize.c文件。3)使用lseek拓展文件大小,要想让实际大小变为拓展后的大小必须要进行一次I\O操作。DEMO:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/lseek_expendfilesize.c文件。//拓展:函数truncate 直接拓展文件大小。 详情 man 2 truncate

  1. ioctl
    嵌入式相关,忽略。
  2. stat

man 2 stat //有example1.NAMEstat - get file status
2.SYNOPSISint stat(const char *pathname, struct stat *statbuf);
3.parameterpathname:路径statbuf:结构体struct statstruct stat {dev_t st_dev; /* ID of device containing file */ino_t st_ino; /* Inode number */mode_t st_mode; /* File type and mode */nlink_t st_nlink; /* Number of hard links */uid_t st_uid; /* User ID of owner */gid_t st_gid; /* Group ID of owner */dev_t st_rdev; /* Device ID (if special file) */off_t st_size; /* Total size, in bytes */blksize_t st_blksize; /* Block size for filesystem I/O */blkcnt_t st_blocks; /* Number of 512B blocks allocated *//* Since Linux 2.6, the kernel supports nanosecondprecision for the following timestamp fields.For the details before Linux 2.6, see NOTES. */struct timespec st_atim; /* Time of last access */struct timespec st_mtim; /* Time of last modification */struct timespec st_ctim; /* Time of last status change */#define st_atime st_atim.tv_sec /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec};
4.RETURN VALUEOn success, zero is returned. On error, -1 is returned, and errno is set appropriately.
5.应用1)获取文件大小statbuf.st_size2)获取文件类型st_mode使用宏函数判断文件类型,statbuf.st_mode。穿透符号链接:stat:会。lstat:不会例子:一个软连接,stat会直接获取软连接的原始文件,而lstat获取的是软连接自身。3)获取文件权限statbuf.st_mode.

文件由两字节构成,位图如下:
在这里插入图片描述

  1. access

man 2 access //用法看这个
1.NAMEaccess, faccessat - check user's permissions for a file2.SYNOPSIS#include int access(const char *pathname, int mode);

  1. chmod

man 2 chmod //查看详情1.NAMEchmod, fchmod, fchmodat - change permissions of a file2.SYNOPSIS#include int chmod(const char *pathname, mode_t mode);

  1. truncate

man 2 truncate //1.NAMEtruncate, ftruncate - truncate a file to a specified length2.SYNOPSIS#include #include int truncate(const char *path, off_t length);

  1. link

man 2 link //1.NAMElink, linkat - make a new name for a file就是创建文件硬链接。2.SYNOPSIS#include int link(const char *oldpath, const char *newpath);

  1. unlink

man 2 unlink 1.NAMEunlink, unlinkat - delete a name and possibly the file it refers to就是删除硬链接,如果硬链接数为1,那就是删除文件.2.SYNOPSIS#include int unlink(const char *pathname);
3.应用调用此函数后,只是让文件具备了被释放的条件,具体释放时机要等到所有打开该文件的进程关闭该文件,再由系统内部调度算法决定释放时间。也就是说unlink可以用来删除正在使用的文件。

  1. readlink

man 2 readlink
读取符号链接文件本身。

  1. rename

man 2 rename
重命名文件

  1. getcwd

man 2 getcwd
相当于 pwd

  1. chdir

man 2 chdir
相当于 cd

  1. opendir

man 3 opendir //库函数
打开目录文件
1.NAMEopendir, fdopendir - open a directory2.SYNOPSIS#include #include DIR *opendir(const char *name);
3.RETURN VALUEThe opendir() and fdopendir() functions return a pointer to the directory stream. On error, NULL is returned, and errno is set appropriately.

  1. closedir

man 3 closedir //库函数
1.NAMEclosedir - close a directory2.SYNOPSIS#include #include int closedir(DIR *dirp);
3.RETURN VALUEThe closedir() function returns 0 on success. On error, -1 is returned, and errno is set appropriately.

  1. readdir

man 3 readdir //库函数1.NAMEreaddir - read a directory每次读一个目录项。要全部读出来要循环。
2.SYNOPSIS#include struct dirent *readdir(DIR *dirp);
3.parameter
struct dirent {ino_t d_ino; /* Inode number */off_t d_off; /* Not an offset; see below */unsigned short d_reclen; /* Length of this record */unsigned char d_type; /* Type of file; not supportedby all filesystem types */char d_name[256]; /* Null-terminated filename */};
4.RETURN VALUEOn success, readdir() returns a pointer to a dirent structure.
5.应用可以用来实现ls的功能。DEMO实现ls -R功能:链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/myls_R.c文件。

  1. 重定向

man 2 dup2dup
dup2(fd1,fd2); //把给fd2的操作重定向给fd1上,//例如给fd2执行write(fd2,"1234",4);那么数据1234会写到fd1上 fcntl也可以实现重定向。

在这里插入图片描述

在这里插入图片描述

三、PCB进程模块和文件描述符

PCB进程控制块实际是一个结构体,
其中有一个成员为文件描述符指针,指向文件描述符表。
文件描述符表:键值对映射存放文件描述符,操作系统只暴露键,对值隐藏。键为整数(也就是我们写代码时获取的整数)。值对应一个指向文件结构体(struct file {})的指针。结构体中的信息就是一系列文件属性、IO缓冲区等信息。struct file {...文件偏移量,文件访问权限,文件打开标志,文件内核缓冲区的首地址;struct operations * f op;...};
文件描述符:内核默认有三个:标准输入 0 STDIN_FILENO标准输出 1 STDOUT_FILENO标准错误 2 STDERR_FILENO.当我们使用系统函数新增时,总是从整数3开始。依次增加,最大为1024(最大值可修改).(新打开文件描述符遵循最小可用整数规则)

在这里插入图片描述

四、阻塞和非阻塞

阻塞和非阻塞是文件的特性(属性)。产生阻塞场景:1)读设备文件(/dev/) 。 终端(Terminal)文件:/dev/tty .也就是终端的读写都是用的这个文件(默认是以阻塞状态打开的)。可以从新以非阻塞装填打开该文件进行输入输出。(详见下面Demo)阻塞是一直持续等待输入,否则不输出。非阻塞就是等两秒看有没有输入,有的话输入,没有的话歇会再看。最优解:你有输入时就告诉我,然后我输出。(这样效率最高)2)读网络文件。(读常规文件无阻塞概念)DEMO:利用系统输入输出文件/dev/tty,去实现非阻塞输入输出,链接地址:git@github.com:Panor520/LinuxCode.git中LinuxCode/systemfunctions/tty.c文件。


推荐阅读
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • python限制递归次数(python最大公约数递归)
    本文目录一览:1、python为什么要进行递归限制 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
author-avatar
83984246_42dbe6
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有