文件I/O之ioctl函数

ioctl函数是I/O操作的杂物箱。不能用其他函数表示的I/O操作通常都能用ioctl表示。终端I/O是ioctl的最大使用方面。ioctl函数通过对文件描述符发送特定的命令来控制文件描述符所代表的设备。#include<unistd.h>/*SystemV*/#include<sys/ioctl.h>/*BSDandLinux*/#include<stropts.h>/*XSISTREAMS*/intioctl(intfiledes,intrequest,...);返回值:若出错则返回-1,若成功则返回其他值对于ISOC原型,它用省略号表示其余参数。但是,通常只有另外一个参数,它常常是指向一个变量或结构的指针。在此原型中,我们表示的只是ioctl函数本身所要求的头文件。通常,还要求另外的设备专用头文件。例如,除POSIX.1所说明的基本操作之外,终端I/O的ioctl命令都需要头文件<termios.h>每个设备驱动程序都可以定义它自己专用的一组ioctl命令。系统则为不同种类的设备提供通用的ioctl命令。 本篇博文内容摘自...
代码星球 代码星球·2021-02-21

文件I/O之fcntl函数

fcntl函数可以改变已打开的文件的性质。#include<fcntl.h>intfcntl(intfiledes,intcmd,.../*intarg*/);返回值:若成功则依赖于cmd,若出错则返回-1在本节的各实例中,第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但是在说明记录锁时,第三个参数则是指向一个结构的指针。fcntl函数有5种功能:(1)复制一个现有的描述符(cmd=F_DUPFD)。(2)获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)。(3)获得/设置文件状态标志(cmd=F_GETFL或F_SETFL)。(4)获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)。(5)获得/设置记录锁(cmd=F_GETLK、F_SETLK或F_SETLKW)。我们先说明这10种cmd值得前7种(后3种,在谈记录锁时说明)。我们将涉及与进程表项中各文件描述符相关联的文件描述符标志,以及每个文件表项中的文件状态标志。F_DUPFD       &n...
代码星球 代码星球·2021-02-21

文件I/O之sync、fsync和fdatasync函数

传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行。当将数据写入文件时,内核通常先将数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后等待其到达队首时,才进行实际的I/O操作。这种输出方式被称为延迟写(delayedwrite)。延迟写减少了磁盘读写次数,但是却降低了文件内容的更新速度,使得欲写到文件中的数据在一段时间内并没有写到磁盘上。当系统发生故障时,这种延迟写可能造成文件更新内容的丢失。为了保证磁盘实际文件系统与缓冲区高速缓存中内容的一致性,UNIX系统提供了sync、fsync和fdatasync三个函数。#include<unistd.h>intfsync(intfiledes);intfdatasync(intfiledes);返回值:若成功则返回0,若出错则返回-1voidsync(void);sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。通常称为updata...

文件I/O(不带缓冲)之dup和dup2函数

下面两个函数都可用来复制一个现有的文件描述符:#include<unistd.h>intdup(intfiledes);intdup2(intfiledes,intfiledes2);两函数的返回值:若成功则返回新的文件描述符,若出错则返回-1由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用filedes2参数指定新描述符的数值。如果filedes2已经打开,则先将其关闭。如若filedes等于filedes2,则dup2返回filedes2,而不关闭它。这些函数返回的新文件描述符与参数filedes共享同一个文件表项。图3-3显示了这种情况。在此图中,我们假定进程执行了:newfd=dup(1);当此函数开始执行时,假定下一个可用的描述符是3(这是非常可能的,因为0、1和2由shell打开)。因为两个文件描述符指向同一文件表项,所以它们共享同一文件状态标志(读、写、添加等)以及同一当前文件偏移量。每个文件描述符都有它自己的一套文件描述符标志。新描述符的执行时关闭(close-on-exec)标志总是由dup函数清除。每个打开文件(或设备)...

文件I/O(不带缓冲)之原子操作

一、添写至一个文件考虑一个进程,它要将数据添加到一个文件尾端。早期的UNIX系统并不支持open的O_APPEND选项,所以程序被编写成下列形式:if(lseek(fd,0L,2)<0)/*positiontoEOF*/err_sys("lseekerror");if(write(fd,buf,100)!=100)/*andwrite*/err_sys("writeerror");对单个进程而言,这段程序能正常工作,但若有多个进程同时使用这种方法将数据添加到同一文件,则会产生问题。假定有两个独立的进程A和B都对同一文件进行添加操作。每个进程都已打开了该文件,但未使用O_APPEND标志。此时,各数据结构之间的关系如图3-2所示(参考【文件I/O(不带缓冲)之文件共享】)。每个进程都有它自己的文件表项,但是共享一个v节点表项。假定进程A调用了lseek,它将进程A的该文件当前偏移量设置为1500字节(当前文件尾端处)。然后内核切换进程使进程B运行。进程B执行lseek,也将其对该文件的当前偏移量设置为1500字节(当前文件尾端处)。然后B调用write,它将B的该文件当前文件偏移量...

文件I/O(不带缓冲)之文件共享

UNIX系统支持在不同进程间共享打开的文件。内核使用三种数据结构表示打开的文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。(1)每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:       (a)文件描述符标志(close_on_exec)。进程中每个打开描述符都有一个执行时关闭(close_on_exec)标志,若此标志设置,则在执行exec时关闭该描述符,否则该描述符仍打开。除非特地用fcntl设置了该标志,否则系统默认操作是在执行exec后仍保持该描述符打开。       (b)指向一个文件表项的指针。(2)内核为所有打开文件维持一张文件表。每个文件表项包含:       (a)文件状态标志(读、写、添加、同步和非阻塞等)。   ...
代码星球 代码星球·2021-02-21

文件I/O(不带缓冲)之I/O的效率

程序清单3-3中的程序使用read和write函数复制文件。关于该程序应注意下列各点:它从标准输入读,写至标准输出,这就假定在执行本程序之前,这些标准输入、输出已由shell安排好。确实,所有常用的UNIX系统shell都提供一种方法,它在标准输入上打开一个文件用于读,在标准输出上创建(或重写)一个文件。这使得程序不必自行打开输入和输出文件。很多应用程序假定标准输入是文件描述符0,标准输出是文件描述符1。本示例中则使用在<unistd.h>中定义的两个名字:STDIN_FILENO和STDOUT_FILENO。考虑到进程终止时,UNIX系统内核会关闭该进程的所有打开的文件描述符,所以此示例并不会关闭输入和输出文件。对UNIX系统内核而言,文本文件和二进制代码文件并无区别,所以本示例对这两种文件都能工作。程序清单3-3将标准输入复制到标志输出[root@localhostapue]#catprog3-3.c#include"apue.h"#defineBUFFSIZE4096intmain(void){intn;charbuf[BUFFSIZE];while((n=read(...
代码星球 代码星球·2021-02-21

文件I/O(不带缓冲)之write函数

调用write函数向打开的文件写数据。#include<unistd.h>ssize_twrite(intfiledes,constvoid*buf,size_tnbytes);返回值:若成功则返回已写的字节数,若出错则返回-1。其返回值通常与参数nbytes的值相同,否则表示出错。write出错的一个常见原因是:磁盘已写满,或者超过了一个给定的进程的文件长度限制。对于普通文件,写操作从文件的当前偏移量处开始。如果在打开该文件时,指定了O_APPEND选项,则在每次写操作之前,将文件偏移量设置在文件的当前结尾处。在一次成功写之后,该文件偏移量增加实际写的字节数。 本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。...

文件I/O(不带缓冲)之read函数

调用read函数从打开文件中读数据。#include<unistd.h>ssize_tread(intfiledes,void*buf,size_tnbytest);返回值:若成功则返回读到的字节数,若已读到文件结尾则返回0,若出错则返回-1。有多种情况可是实际读到的字节数少于要求读的字节数:读普通文件时,在读到要求字节数之前已到达了文件尾端。当从终端设备读时,通常一次最多读一行。当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读到字节数。当从管道或FIFO读时,如若管道包含的字节数少于所需的数量,那么read将只返回实际可用的字节数。当从某些面向记录的设备(例如磁带)读时,一次做多返回一个记录。当某一信号造成中断,而已经读了部分数据量时。读操作从文件的当前偏移量处开始,在成功返回之前,该偏移量将增加实际读到的字节数。POSIX.1从几个方面对read函数的原型作了更改。其经典定义是:intread(intfiledes,char*buf,unsignednbytes);首先,为了与ISOC保持一致,将第二个参数由char*改为void*。在ISOC中,类型void*...

文件I/O(不带缓冲)之lseek函数

每个打开的文件都有一个与其相关联的“当前文件偏移量”(currentfileoffset)。它通常是一个非负整数,用以度量从文件开始处计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读写的字节数。按系统默认情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0。可以调用lseek显示地为一个打开的文件设置其偏移量:#include<unistd.h>off_tlseek(intfiledes,off_toffset,intwhence);返回值:若成功则返回新的文件偏移量,若出错则返回-1。对参数offset的解释与参数whence的值有关。(注意:当前文件偏移量和参数offset是完全不同的概念。)若whence是SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节。若whence是SEEK_CUR,则将该文件的偏移量设置为其当前位置加offset,offset可为正或负。若whence是SEEK_END,则将新文件的偏移量设置为文件长度加上offset,offset可为正或负。若lseek成功执行,则返回...

文件I/O(不带缓冲)之close函数

可调用close函数关闭一个打开的文件:#include<unistd.h>intclose(intfiledes);返回值:若成功则返回0,若出错则返回-1。关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,内核自动关闭它所有打开的文件。很多程序都利用了这一功能而不显示地用close关闭打开文件。 本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。...

文件I/O(不带缓冲)之creat函数

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。也可调用creat函数创建一个新文件。#include<fcntl.h>intcreat(constchar*pathname,mode_tmode); 返回值:若成功则返回为只写打开的文件描述符,若出错则返回-1。注意,此函数等效于:open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);在早期的UNIX系统版本中,open函数的第二个参数只能是0、1或2,没有办法打开一个尚未存在的文件,因此需要另一个系统调用creat以创建新文件。现在,open函数提供了选项O_CREAT和O_TRUNC,于是也就不再需要creat函数。creat的一个不足之处是它以只写方式打开所创建的文件。在提供open的新版本之前,如果要创建一个临时文件,并要先写该文件,然后又读该文件,则必须先调用creat、close,然后再调用open。现在则可用下列方式调用open:open(pathname,O_RDWR|O...

文件I/O(不带缓冲)之open函数

调用open函数可以打开或创建一个文件。#include<fcntl.h>intopen(constchar*pathname,intoflag,.../*mode_tmode*/); 返回值:若成功则返回文件描述符,若出错则返回-1。我们将第三个参数写为...,ISOC用这种方法表明余下参数的数量及其类型根据具体的调用会有所不同。对于open函数而言,仅当创建新文件时才使用第三个参数。在函数原型中将此参数放置在注释中。pathname是要打开或创建的文件的名字。oflag参数可用来说明此函数的多个选项。用下列一个或多个常量进行“或”运算构成oflag参数(这些常量定义在<fcntl.h>头文件中):O_RDONLY                 只读打开O_WRONLY         &nb...

文件I/O(不带缓冲)概述

一、引言UNIX系统中大多数文件I/O只需用到5个函数open、read、write、lseek以及close。这些函数经常被称为不带缓冲的I/O(unbufferedI/O)。术语不带缓冲指的是每个read和write都调用内核中的一个系统调用。这些不带缓冲的I/O函数不是ISOC的组成部分,但是,它们是POSIX.1和SingleUNIXSpecification的组成部分。二、文件描述符对于内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读或写一个文件时,使用open或write返回的文件描述符标识该文件,将其作为参数传送给read或write。按照惯例,UNIX系统shell使用文件描述符0与进程的标准输入相关联,文件描述符1与标准输出相关联,文件描述符2与标准出错输出相关联。这是各种shell以及很多应用程序使用的惯例,而与UNIX内核无关。尽管如此,如果不遵照这种惯例,那么很多UNIX系统应用程序就不能正常工作。在依从POSIX的应用程序中,幻数0、1、2应当替换成符号常量STD...
代码星球 代码星球·2021-02-21

UNIX标准化及实现之POSIX标准可选头文件

POSIX标准定义的可选头文件文件说明<aio.h>异步I/O<mqueue.h>消息队列<pthread.h>线程<sched.h>执行调度<semaphore.h>信号量<spawn.h>实时spawn接口<stropts.h>XSISTREAMS接口<trace.h>事件跟踪...
首页上一页...3132333435...下一页尾页