2.Linux文件IO编程
2.1Linux文件IO概述
2.1.0POSIX规范
POSIX:(Portable Operating System Interface)可移植操作系统接口规范。
由IEEE制定,是为了提高UNIX(也适用于Linux)环境下应用程序的可移植性。
2.1.1虚拟文件系统
Linux具有与其他操作系统和谐共存的能力。
Linux文件系统由两层构建:第一层是虚拟文件系统(VFS),第二层是各种不同的具体的文件系统。
VFS把各种具体的文件系统的公共部分抽取出来,形成一个抽象层,是系统内核的一部分。
位于用户程序和具体的文件系统之间,为用户程序提供标准的文件系统调用接口。对用户屏蔽底层文件系统的实现细节和差异。
1 nodev sysfs 2 nodev rootfs 3 nodev ramfs 4 nodev bdev 5 nodev proc 6 nodev cpuset 7 nodev cgroup 8 nodev tmpfs 9 nodev devtmpfs 10 nodev debugfs 11 nodev tracefs 12 nodev securityfs 13 nodev sockfs 14 nodev bpf 15 nodev pipefs 16 nodev devpts 17 ext3 18 ext2 19 ext4 20 squashfs 21 nodev hugetlbfs 22 vfat 23 nodev ecryptfs 24 fuseblk 25 nodev fuse 26 nodev fusectl 27 nodev pstore 28 nodev mqueue 29 nodev rpc_pipefs 30 nodev nfs 31 nodev nfs4 32 nodev nfsd
2.1.2 文件和文件描述符
Linux文件系统是基于文件概念的。文件是以字符序列构成的信息载体。可以把IO设备当做文件来处理。
Linux中的文件主要分为6种:普通文件、目录文件、符号链接文件、管道文件、套接字文件和设备文件。
一个进程启动时,都会打开3个流,标准输入、标准输出和标准错误。
对应的文件描述符0、1、2,宏分别STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。
2.1.3 文件IO和标准IO的区别
1.只要在开发环境中有标准C库,标准IO就可以使用。Linux既可以使用标准IO,也可以使用文件IO。
2.通过文件IO读写文件时,每次操作都会执行相关系统调用。好处:直接读写实际文件。坏处:频繁的系统调用会增加系统开销。
3.文件IO中用文件描述符表示一个打开的文件,可以访问不同类型的文件(普通文件、管道文件、设备文件等)。
标准IO中用FILE(流)表示一个打开的文件,通常只是用来访问普通文件。
2.2文件IO操作
主要介绍文件IO相关函数:open()、read()、write()、lseek()和close()。它们不带缓冲,直接对文件(包括设备)进行读写操作。
2.2.1 文件打开和关闭
打开:
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
说明:open用于创建或打开文件,在打开或创建文件时可以指定文件打开方式及文件的访问权限。
关闭: int close(int fd);
说明:用于关闭一个被打开的文件。当一个进程终止时,所有打开的文件都有内核自动关闭。
很多程序都利用这一特性而不显式地关闭一个文件。
1 /******************************************************************* 2 * > File Name: 01-open.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Sun 03 Sep 2017 09:01:10 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 14 int main(int argc, char* argv[]) 15 { 16 int fd; 17 18 if((fd = open("test.txt", O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0){ 19 perror("Fail to open test.txt :"); 20 return (-1); 21 }else{ 22 printf("Succeed to open test.txt, fd = %d\n ", fd); 23 } 24 25 close(fd); 26 27 return 0; 28 }
1 OPEN(2) Linux Programmer's Manual OPEN(2) 2 3 4 5 NAME 6 open, creat - open and possibly create a file or device 7 8 SYNOPSIS 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 13 int open(const char *pathname, int flags); 14 int open(const char *pathname, int flags, mode_t mode); 15 16 int creat(const char *pathname, mode_t mode); 17 18 DESCRIPTION 19 Given a pathname for a file, open() returns a file descriptor, a small, nonnegative integer for use in subse‐ 20 quent system calls (read(2), write(2), lseek(2), fcntl(2), etc.). The file descriptor returned by a success‐ 21 ful call will be the lowest-numbered file descriptor not currently open for the process. 22 23 By default, the new file descriptor is set to remain open across an execve(2) (i.e., the FD_CLOEXEC file 24 descriptor flag described in fcntl(2) is initially disabled; the O_CLOEXEC flag, described below, can be used 25 to change this default). The file offset is set to the beginning of the file (see lseek(2)). 26 27 A call to open() creates a new open file description, an entry in the system-wide table of open files. This 28 entry records the file offset and the file status flags (modifiable via the fcntl(2) F_SETFL operation). A 29 file descriptor is a reference to one of these entries; this reference is unaffected if pathname is subse‐ 30 quently removed or modified to refer to a different file. The new open file description is initially not 31 shared with any other process, but sharing may arise via fork(2). 32 33 The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. These 34 request opening the file read-only, write-only, or read/write, respectively. 35 36 In addition, zero or more file creation flags and file status flags can be bitwise-or'd in flags. The file 37 creation flags are O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_TRUNC, and O_TTY_INIT. 38 The file status flags are all of the remaining flags listed below. The distinction between these two groups 39 of flags is that the file status flags can be retrieved and (in some cases) modified using fcntl(2). The 40 full list of file creation flags and file status flags is as follows: 41 42 O_APPEND 43 The file is opened in append mode. Before each write(2), the file offset is positioned at the end of 44 the file, as if with lseek(2). O_APPEND may lead to corrupted files on NFS filesystems if more than 45 one process appends data to a file at once. This is because NFS does not support appending to a file, 46 so the client kernel has to simulate it, which can't be done without a race condition. 47 48 O_ASYNC 49 Enable signal-driven I/O: generate a signal (SIGIO by default, but this can be changed via fcntl(2)) 50 when input or output becomes possible on this file descriptor. This feature is available only for 51 terminals, pseudoterminals, sockets, and (since Linux 2.6) pipes and FIFOs. See fcntl(2) for further 52 details. 53 54 O_CLOEXEC (Since Linux 2.6.23) 55 Enable the close-on-exec flag for the new file descriptor. Specifying this flag permits a program to 56 avoid additional fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag. Additionally, use of this 57 flag is essential in some multithreaded programs since using a separate fcntl(2) F_SETFD operation to 58 set the FD_CLOEXEC flag does not suffice to avoid race conditions where one thread opens a file 59 descriptor at the same time as another thread does a fork(2) plus execve(2). 60 61 O_CREAT 62 If the file does not exist it will be created. The owner (user ID) of the file is set to the effec‐ 63 tive user ID of the process. The group ownership (group ID) is set either to the effective group ID 64 of the process or to the group ID of the parent directory (depending on filesystem type and mount 65 options, and the mode of the parent directory, see the mount options bsdgroups and sysvgroups 66 described in mount(8)). 67 68 mode specifies the permissions to use in case a new file is created. This argument must be supplied 69 when O_CREAT is specified in flags; if O_CREAT is not specified, then mode is ignored. The effective 70 permissions are modified by the process's umask in the usual way: The permissions of the created file 71 are (mode & ~umask). Note that this mode applies only to future accesses of the newly created file; 72 the open() call that creates a read-only file may well return a read/write file descriptor. 73 74 The following symbolic constants are provided for mode: 75 76 S_IRWXU 00700 user (file owner) has read, write and execute permission 77 78 S_IRUSR 00400 user has read permission 79 80 S_IWUSR 00200 user has write permission 81 82 S_IXUSR 00100 user has execute permission 83 84 S_IRWXG 00070 group has read, write and execute permission 85 86 S_IRGRP 00040 group has read permission 87 88 S_IWGRP 00020 group has write permission 89 90 S_IXGRP 00010 group has execute permission 91 92 S_IRWXO 00007 others have read, write and execute permission 93 94 S_IROTH 00004 others have read permission 95 96 S_IWOTH 00002 others have write permission 97 98 S_IXOTH 00001 others have execute permission 99 100 O_DIRECT (Since Linux 2.4.10) 101 Try to minimize cache effects of the I/O to and from this file. In general this will degrade perfor‐ 102 mance, but it is useful in special situations, such as when applications do their own caching. File 103 I/O is done directly to/from user-space buffers. The O_DIRECT flag on its own makes an effort to 104 transfer data synchronously, but does not give the guarantees of the O_SYNC flag that data and neces‐ 105 sary metadata are transferred. To guarantee synchronous I/O, O_SYNC must be used in addition to 106 O_DIRECT. See NOTES below for further discussion. 107 108 A semantically similar (but deprecated) interface for block devices is described in raw(8). 109 110 O_DIRECTORY 111 If pathname is not a directory, cause the open to fail. This flag is Linux-specific, and was added in 112 kernel version 2.1.126, to avoid denial-of-service problems if opendir(3) is called on a FIFO or tape 113 device. 114 115 O_EXCL Ensure that this call creates the file: if this flag is specified in conjunction with O_CREAT, and 116 pathname already exists, then open() will fail. 117 118 When these two flags are specified, symbolic links are not followed: if pathname is a symbolic link, 119 then open() fails regardless of where the symbolic link points to. 120 121 In general, the behavior of O_EXCL is undefined if it is used without O_CREAT. There is one excep‐ 122 tion: on Linux 2.6 and later, O_EXCL can be used without O_CREAT if pathname refers to a block device. 123 If the block device is in use by the system (e.g., mounted), open() fails with the error EBUSY. 124 125 On NFS, O_EXCL is supported only when using NFSv3 or later on kernel 2.6 or later. In NFS environ‐ 126 ments where O_EXCL support is not provided, programs that rely on it for performing locking tasks will 127 contain a race condition. Portable programs that want to perform atomic file locking using a lock‐ 128 file, and need to avoid reliance on NFS support for O_EXCL, can create a unique file on the same 129 filesystem (e.g., incorporating hostname and PID), and use link(2) to make a link to the lockfile. If 130 link(2) returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its 131 link count has increased to 2, in which case the lock is also successful. 132 133 O_LARGEFILE 134 (LFS) Allow files whose sizes cannot be represented in an off_t (but can be represented in an off64_t) 135 to be opened. The _LARGEFILE64_SOURCE macro must be defined (before including any header files) in 136 order to obtain this definition. Setting the _FILE_OFFSET_BITS feature test macro to 64 (rather than 137 using O_LARGEFILE) is the preferred method of accessing large files on 32-bit systems (see fea‐ 138 ture_test_macros(7)). 139 140 O_NOATIME (Since Linux 2.6.8) 141 Do not update the file last access time (st_atime in the inode) when the file is read(2). This flag 142 is intended for use by indexing or backup programs, where its use can significantly reduce the amount 143 of disk activity. This flag may not be effective on all filesystems. One example is NFS, where the 144 server maintains the access time. 145 146 O_NOCTTY 147 If pathname refers to a terminal device—see tty(4)—it will not become the process's controlling termi‐ 148 nal even if the process does not have one. 149 150 O_NOFOLLOW 151 If pathname is a symbolic link, then the open fails. This is a FreeBSD extension, which was added to 152 Linux in version 2.1.126. Symbolic links in earlier components of the pathname will still be fol‐ 153 lowed. See also O_NOPATH below. 154 155 O_NONBLOCK or O_NDELAY 156 When possible, the file is opened in nonblocking mode. Neither the open() nor any subsequent opera‐ 157 tions on the file descriptor which is returned will cause the calling process to wait. For the han‐ 158 dling of FIFOs (named pipes), see also fifo(7). For a discussion of the effect of O_NONBLOCK in con‐ 159 junction with mandatory file locks and with file leases, see fcntl(2). 160 161 O_PATH (since Linux 2.6.39) 162 Obtain a file descriptor that can be used for two purposes: to indicate a location in the filesystem 163 tree and to perform operations that act purely at the file descriptor level. The file itself is not 164 opened, and other file operations (e.g., read(2), write(2), fchmod(2), fchown(2), fgetxattr(2), 165 mmap(2)) fail with the error EBADF. 166 167 The following operations can be performed on the resulting file descriptor: 168 169 * close(2); fchdir(2) (since Linux 3.5); fstat(2) (since Linux 3.6). 170 171 * Duplicating the file descriptor (dup(2), fcntl(2) F_DUPFD, etc.). 172 173 * Getting and setting file descriptor flags (fcntl(2) F_GETFD and F_SETFD). 174 175 * Retrieving open file status flags using the fcntl(2) F_GETFL operation: the returned flags will 176 include the bit O_PATH. 177 178 179 * Passing the file descriptor as the dirfd argument of openat(2) and the other "*at()" system calls. 180 181 * Passing the file descriptor to another process via a UNIX domain socket (see SCM_RIGHTS in 182 unix(7)). 183 184 When O_PATH is specified in flags, flag bits other than O_DIRECTORY and O_NOFOLLOW are ignored. 185 186 If the O_NOFOLLOW flag is also specified, then the call returns a file descriptor referring to the 187 symbolic link. This file descriptor can be used as the dirfd argument in calls to fchownat(2), 188 fstatat(2), linkat(2), and readlinkat(2) with an empty pathname to have the calls operate on the sym‐ 189 bolic link. 190 191 O_SYNC The file is opened for synchronous I/O. Any write(2)s on the resulting file descriptor will block the 192 calling process until the data has been physically written to the underlying hardware. But see NOTES 193 below. 194 195 O_TRUNC 196 If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or 197 O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the 198 O_TRUNC flag is ignored. Otherwise the effect of O_TRUNC is unspecified. 199 200 Some of these optional flags can be altered using fcntl(2) after the file has been opened. 201 202 creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC. 203 204 RETURN VALUE 205 open() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set 206 appropriately). 207 208 ERRORS 209 EACCES The requested access to the file is not allowed, or search permission is denied for one of the direc‐ 210 tories in the path prefix of pathname, or the file did not exist yet and write access to the parent 211 directory is not allowed. (See also path_resolution(7).) 212 213 EDQUOT Where O_CREAT is specified, the file does not exist, and the user's quota of disk blocks or inodes on 214 the filesystem has been exhausted. 215 216 EEXIST pathname already exists and O_CREAT and O_EXCL were used. 217 218 EFAULT pathname points outside your accessible address space. 219 220 EFBIG See EOVERFLOW. 221 222 EINTR While blocked waiting to complete an open of a slow device (e.g., a FIFO; see fifo(7)), the call was 223 interrupted by a signal handler; see signal(7). 224 225 EINVAL The filesystem does not support the O_DIRECT flag. See NOTES for more information. 226 227 EISDIR pathname refers to a directory and the access requested involved writing (that is, O_WRONLY or O_RDWR 228 is set). 229 230 ELOOP Too many symbolic links were encountered in resolving pathname, or O_NOFOLLOW was specified but path‐ 231 name was a symbolic link. 232 233 EMFILE The process already has the maximum number of files open. 234 235 ENAMETOOLONG 236 pathname was too long. 237 238 ENFILE The system limit on the total number of open files has been reached. 239 240 ENODEV pathname refers to a device special file and no corresponding device exists. (This is a Linux kernel 241 bug; in this situation ENXIO must be returned.) 242 243 ENOENT O_CREAT is not set and the named file does not exist. Or, a directory component in pathname does not 244 exist or is a dangling symbolic link. 245 246 ENOMEM Insufficient kernel memory was available. 247 248 ENOSPC pathname was to be created but the device containing pathname has no room for the new file. 249 250 ENOTDIR 251 A component used as a directory in pathname is not, in fact, a directory, or O_DIRECTORY was specified 252 and pathname was not a directory. 253 254 ENXIO O_NONBLOCK | O_WRONLY is set, the named file is a FIFO and no process has the file open for reading. 255 Or, the file is a device special file and no corresponding device exists. 256 257 EOVERFLOW 258 pathname refers to a regular file that is too large to be opened. The usual scenario here is that an 259 application compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 tried to open a file whose 260 size exceeds (2<<31)-1 bits; see also O_LARGEFILE above. This is the error specified by POSIX.1-2001; 261 in kernels before 2.6.24, Linux gave the error EFBIG for this case. 262 263 EPERM The O_NOATIME flag was specified, but the effective user ID of the caller did not match the owner of 264 the file and the caller was not privileged (CAP_FOWNER). 265 266 EROFS pathname refers to a file on a read-only filesystem and write access was requested. 267 268 ETXTBSY 269 pathname refers to an executable image which is currently being executed and write access was 270 requested. 271 272 EWOULDBLOCK 273 The O_NONBLOCK flag was specified, and an incompatible lease was held on the file (see fcntl(2)). 274 275 CONFORMING TO 276 SVr4, 4.3BSD, POSIX.1-2001. The O_DIRECTORY, O_NOATIME, O_NOFOLLOW, and O_PATH flags are Linux-specific, and 277 one may need to define _GNU_SOURCE (before including any header files) to obtain their definitions. 278 279 The O_CLOEXEC flag is not specified in POSIX.1-2001, but is specified in POSIX.1-2008. 280 281 O_DIRECT is not specified in POSIX; one has to define _GNU_SOURCE (before including any header files) to get 282 its definition. 283 284 NOTES 285 Under Linux, the O_NONBLOCK flag indicates that one wants to open but does not necessarily have the intention 286 to read or write. This is typically used to open devices in order to get a file descriptor for use with 287 ioctl(2). 288 289 Unlike the other values that can be specified in flags, the access mode values O_RDONLY, O_WRONLY, and 290 O_RDWR, do not specify individual bits. Rather, they define the low order two bits of flags, and are defined 291 respectively as 0, 1, and 2. In other words, the combination O_RDONLY | O_WRONLY is a logical error, and 292 certainly does not have the same meaning as O_RDWR. Linux reserves the special, nonstandard access mode 3 293 (binary 11) in flags to mean: check for read and write permission on the file and return a descriptor that 294 can't be used for reading or writing. This nonstandard access mode is used by some Linux drivers to return a 295 descriptor that is to be used only for device-specific ioctl(2) operations. 296 297 The (undefined) effect of O_RDONLY | O_TRUNC varies among implementations. On many systems the file is actu‐ 298 ally truncated. 299 300 There are many infelicities in the protocol underlying NFS, affecting amongst others O_SYNC and O_NDELAY. 301 302 POSIX provides for three different variants of synchronized I/O, corresponding to the flags O_SYNC, O_DSYNC, 303 and O_RSYNC. Currently (2.6.31), Linux implements only O_SYNC, but glibc maps O_DSYNC and O_RSYNC to the 304 same numerical value as O_SYNC. Most Linux filesystems don't actually implement the POSIX O_SYNC semantics, 305 which require all metadata updates of a write to be on disk on returning to user space, but only the O_DSYNC 306 semantics, which require only actual file data and metadata necessary to retrieve it to be on disk by the 307 time the system call returns. 308 309 Note that open() can open device special files, but creat() cannot create them; use mknod(2) instead. 310 311 On NFS filesystems with UID mapping enabled, open() may return a file descriptor but, for example, read(2) 312 requests are denied with EACCES. This is because the client performs open() by checking the permissions, but 313 UID mapping is performed by the server upon read and write requests. 314 315 If the file is newly created, its st_atime, st_ctime, st_mtime fields (respectively, time of last access, 316 time of last status change, and time of last modification; see stat(2)) are set to the current time, and so 317 are the st_ctime and st_mtime fields of the parent directory. Otherwise, if the file is modified because of 318 the O_TRUNC flag, its st_ctime and st_mtime fields are set to the current time. 319 320 O_DIRECT 321 The O_DIRECT flag may impose alignment restrictions on the length and address of user-space buffers and the 322 file offset of I/Os. In Linux alignment restrictions vary by filesystem and kernel version and might be 323 absent entirely. However there is currently no filesystem-independent interface for an application to dis‐ 324 cover these restrictions for a given file or filesystem. Some filesystems provide their own interfaces for 325 doing so, for example the XFS_IOC_DIOINFO operation in xfsctl(3). 326 327 Under Linux 2.4, transfer sizes, and the alignment of the user buffer and the file offset must all be multi‐ 328 ples of the logical block size of the filesystem. Under Linux 2.6, alignment to 512-byte boundaries suf‐ 329 fices. 330 331 O_DIRECT I/Os should never be run concurrently with the fork(2) system call, if the memory buffer is a pri‐ 332 vate mapping (i.e., any mapping created with the mmap(2) MAP_PRIVATE flag; this includes memory allocated on 333 the heap and statically allocated buffers). Any such I/Os, whether submitted via an asynchronous I/O inter‐ 334 face or from another thread in the process, should be completed before fork(2) is called. Failure to do so 335 can result in data corruption and undefined behavior in parent and child processes. This restriction does 336 not apply when the memory buffer for the O_DIRECT I/Os was created using shmat(2) or mmap(2) with the 337 MAP_SHARED flag. Nor does this restriction apply when the memory buffer has been advised as MADV_DONTFORK 338 with madvise(2), ensuring that it will not be available to the child after fork(2). 339 340 The O_DIRECT flag was introduced in SGI IRIX, where it has alignment restrictions similar to those of Linux 341 2.4. IRIX has also a fcntl(2) call to query appropriate alignments, and sizes. FreeBSD 4.x introduced a 342 flag of the same name, but without alignment restrictions. 343 344 O_DIRECT support was added under Linux in kernel version 2.4.10. Older Linux kernels simply ignore this 345 flag. Some filesystems may not implement the flag and open() will fail with EINVAL if it is used. 346 347 Applications should avoid mixing O_DIRECT and normal I/O to the same file, and especially to overlapping byte 348 regions in the same file. Even when the filesystem correctly handles the coherency issues in this situation, 349 overall I/O throughput is likely to be slower than using either mode alone. Likewise, applications should 350 avoid mixing mmap(2) of files with direct I/O to the same files. 351 352 The behaviour of O_DIRECT with NFS will differ from local filesystems. Older kernels, or kernels configured 353 in certain ways, may not support this combination. The NFS protocol does not support passing the flag to the 354 server, so O_DIRECT I/O will bypass the page cache only on the client; the server may still cache the I/O. 355 The client asks the server to make the I/O synchronous to preserve the synchronous semantics of O_DIRECT. 356 Some servers will perform poorly under these circumstances, especially if the I/O size is small. Some 357 servers may also be configured to lie to clients about the I/O having reached stable storage; this will avoid 358 the performance penalty at some risk to data integrity in the event of server power failure. The Linux NFS 359 client places no alignment restrictions on O_DIRECT I/O. 360 361 In summary, O_DIRECT is a potentially powerful tool that should be used with caution. It is recommended that 362 applications treat use of O_DIRECT as a performance option which is disabled by default. 363 364 "The thing that has always disturbed me about O_DIRECT is that the whole interface is just stupid, and 365 was probably designed by a deranged monkey on some serious mind-controlling substances."—Linus 366 367 BUGS 368 Currently, it is not possible to enable signal-driven I/O by specifying O_ASYNC when calling open(); use 369 fcntl(2) to enable this flag. 370 371 SEE ALSO 372 chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), openat(2), 373 read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), fifo(7), path_resolution(7), symlink(7) 374 375 COLOPHON 376 This page is part of release 3.54 of the Linux man-pages project. A description of the project, and informa‐ 377 tion about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/. 378 379 380 381 Linux 2013-08-09 OPEN(2)
2.2.2 文件读写
ssize_t read(int fd, void *buf, size_t count);
说明:read函数从文件中读取数据存放到缓冲区中,并返回实际读取的字节数。若返回0,则表示没有数据可读,
即已达到文件尾。读操作从文件的当前读写位置开始读取内容,当前读写位置自动往后移动。
ssize_t write(int fd, const void *buf, size_t count);
说明:write函数将数据写入文件中,并将返回实际写入的字节数。写操作从文件的当前读写位置开始写入。
对磁盘文件进行写操作时,若磁盘已满,返回失败。
1 /******************************************************************* 2 * > File Name: 02-read.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Sun 03 Sep 2017 09:41:03 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 14 #define N 64 15 16 int main(int argc, char* argv[]) 17 { 18 int fd, nbyte, sum = 0; 19 char buf[N]; 20 21 /*1.判断命令行参数*/ 22 if(argc < 2){ 23 printf("Usage : %s <file_name>\n", argv[0]); 24 return (-1); 25 } 26 27 /*2.打开文件*/ 28 if((fd = open(argv[1], O_RDONLY)) < 0){ 29 perror("Fail to open :"); 30 return (-1); 31 } 32 33 /*3.循环读取文件,累加读到的字节数*/ 34 while((nbyte = read(fd, buf, N)) > 0){ 35 sum += nbyte; 36 } 37 38 printf("The length of %s is %d bytes\n", argv[0], sum); 39 40 close(fd); 41 42 return 0; 43 }
2.2.3文件定位
off_t lseek(int fd, off_t offset, int whence);
offset(@param):相对基准点whence的偏移量,以字节为单位,正数表示向前移动,负数表示向后移动;
whence:SEEK_SET:文件的起始位置;SEEK_CUR:文件的当前读写位置;SEEK_END:文件的结束位置;
说明:lseek函数对文件当前读写位置进行定位。它只能对可定位(可随机访问)文件操作。
管道、套接字和大部分字符设备文件不支持此类访问。
1 /******************************************************************* 2 * > File Name: 05-lseek.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Mon 04 Sep 2017 11:49:08 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 #include <stdlib.h> 14 15 #define BUFFER_SIZE (1024*1) /*每次读写缓存大小,影响运行效率*/ 16 #define SRC_FILE_NAME "src_file" /*源文件名*/ 17 #define DEST_FILE_NAME "dst_file" /*目标文件名*/ 18 #define OFFSET (1024*10) /*复制的数据大小*/ 19 20 int main(int argc, char* argv[]) 21 { 22 int fds, fdd; 23 unsigned char buff[BUFFER_SIZE]; 24 int read_len; 25 26 /*1.以只读方式打开源文件*/ 27 if((fds = open(SRC_FILE_NAME, O_RDONLY)) < 0){ 28 perror("Fail to open src_file :"); 29 return (-1); 30 } 31 32 /*2.以只写方式打开目标文件,若此文件不存在则创建,访问权限644*/ 33 if((fdd = open(DEST_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0){ 34 perror("Fail to open dest_file :"); 35 return (-1); 36 } 37 38 /*3.将源文件的读写指针移到最后10KB的起始位置*/ 39 lseek(fds , -OFFSET, SEEK_END); 40 41 /*4.读取源文件的最后10KB数据并写入目标文件,每次读写1KB*/ 42 while((read_len = read(fds, buff, sizeof(buff))) > 0){ 43 write(fdd, buff, read_len); 44 } 45 46 close(fds); 47 close(fdd); 48 49 return 0; 50 }
1 LSEEK(2) Linux Programmer's Manual LSEEK(2) 2 3 4 5 NAME 6 lseek - reposition read/write file offset 7 8 SYNOPSIS 9 #include <sys/types.h> 10 #include <unistd.h> 11 12 off_t lseek(int fd, off_t offset, int whence); 13 14 DESCRIPTION 15 The lseek() function repositions the offset of the open file associated with the file descriptor fd to the 16 argument offset according to the directive whence as follows: 17 18 SEEK_SET 19 The offset is set to offset bytes. 20 21 SEEK_CUR 22 The offset is set to its current location plus offset bytes. 23 24 SEEK_END 25 The offset is set to the size of the file plus offset bytes. 26 27 The lseek() function allows the file offset to be set beyond the end of the file (but this does not change 28 the size of the file). If data is later written at this point, subsequent reads of the data in the gap (a 29 "hole") return null bytes ('\0') until data is actually written into the gap. 30 31 Seeking file data and holes 32 Since version 3.1, Linux supports the following additional values for whence: 33 34 SEEK_DATA 35 Adjust the file offset to the next location in the file greater than or equal to offset containing 36 data. If offset points to data, then the file offset is set to offset. 37 38 SEEK_HOLE 39 Adjust the file offset to the next hole in the file greater than or equal to offset. If offset points 40 into the middle of a hole, then the file offset is set to offset. If there is no hole past offset, 41 then the file offset is adjusted to the end of the file (i.e., there is an implicit hole at the end of 42 any file). 43 44 In both of the above cases, lseek() fails if offset points past the end of the file. 45 46 These operations allow applications to map holes in a sparsely allocated file. This can be useful for appli‐ 47 cations such as file backup tools, which can save space when creating backups and preserve holes, if they 48 have a mechanism for discovering holes. 49 50 For the purposes of these operations, a hole is a sequence of zeros that (normally) has not been allocated in 51 the underlying file storage. However, a filesystem is not obliged to report holes, so these operations are 52 not a guaranteed mechanism for mapping the storage space actually allocated to a file. (Furthermore, a 53 sequence of zeros that actually has been written to the underlying storage may not be reported as a hole.) 54 In the simplest implementation, a filesystem can support the operations by making SEEK_HOLE always return the 55 offset of the end of the file, and making SEEK_DATA always return offset (i.e., even if the location referred 56 to by offset is a hole, it can be considered to consist of data that is a sequence of zeros). 57 58 The _GNU_SOURCE feature test macro must be defined in order to obtain the definitions of SEEK_DATA and 59 SEEK_HOLE from <unistd.h>. 60 61 RETURN VALUE 62 Upon successful completion, lseek() returns the resulting offset location as measured in bytes from the 63 beginning of the file. On error, the value (off_t) -1 is returned and errno is set to indicate the error. 64 65 ERRORS 66 EBADF fd is not an open file descriptor. 67 68 EINVAL whence is not valid. Or: the resulting file offset would be negative, or beyond the end of a seekable 69 device. 70 71 EOVERFLOW 72 The resulting file offset cannot be represented in an off_t. 73 74 ESPIPE fd is associated with a pipe, socket, or FIFO. 75 76 ENXIO whence is SEEK_DATA or SEEK_HOLE, and the current file offset is beyond the end of the file. 77 78 CONFORMING TO 79 SVr4, 4.3BSD, POSIX.1-2001. 80 81 SEEK_DATA and SEEK_HOLE are nonstandard extensions also present in Solaris, FreeBSD, and DragonFly BSD; they 82 are proposed for inclusion in the next POSIX revision (Issue 8). 83 84 NOTES 85 Some devices are incapable of seeking and POSIX does not specify which devices must support lseek(). 86 87 On Linux, using lseek() on a terminal device returns ESPIPE. 88 89 When converting old code, substitute values for whence with the following macros: 90 91 old new 92 0 SEEK_SET 93 1 SEEK_CUR 94 2 SEEK_END 95 L_SET SEEK_SET 96 L_INCR SEEK_CUR 97 L_XTND SEEK_END 98 99 Note that file descriptors created by dup(2) or fork(2) share the current file position pointer, so seeking 100 on such files may be subject to race conditions. 101 102 SEE ALSO 103 dup(2), fork(2), open(2), fseek(3), lseek64(3), posix_fallocate(3) 104 105 COLOPHON 106 This page is part of release 3.54 of the Linux man-pages project. A description of the project, and informa‐ 107 tion about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/. 108 109 110 111 Linux 2013-03-27 LSEEK(2)
2.2.4 文件锁
int fcntl(int fd, int cmd, ... /* arg */ );
当多个程序共同操作一个文件时,给文件上锁,来解决对共享资源的竞争。
建议性锁:要求每个相关程序在访问文件之前检查是否有锁存在,并且尊重已有锁。(不建议使用,无法保证每个程序都自动检查是否有锁)
强制性锁:由内核执行的锁,当一个文件被上锁进行写入操作的时候,内核将阻止其他任何程序对该文件进行读写操作。
采用强制性锁对性能的影响较大,每次读写内核都检查是否有锁存在。
实现上锁的函数:lockf():对文件施加建议性锁。
fcntl():可以施加建议性锁,也可以施加强制性锁。还能对文件的某一记录上锁,即记录锁。
记录锁:分读取锁(共享锁)和写入锁(排斥锁)。
1 FCNTL(2) Linux Programmer's Manual FCNTL(2) 2 3 4 5 NAME 6 fcntl - manipulate file descriptor 7 8 SYNOPSIS 9 #include <unistd.h> 10 #include <fcntl.h> 11 12 int fcntl(int fd, int cmd, ... /* arg */ ); 13 14 DESCRIPTION 15 fcntl() performs one of the operations described below on the open file descriptor fd. The operation is 16 determined by cmd. 17 18 fcntl() can take an optional third argument. Whether or not this argument is required is determined by cmd. 19 The required argument type is indicated in parentheses after each cmd name (in most cases, the required type 20 is int, and we identify the argument using the name arg), or void is specified if the argument is not 21 required. 22 23 Duplicating a file descriptor 24 F_DUPFD (int) 25 Find the lowest numbered available file descriptor greater than or equal to arg and make it be a copy 26 of fd. This is different from dup2(2), which uses exactly the descriptor specified. 27 28 On success, the new descriptor is returned. 29 30 See dup(2) for further details. 31 32 F_DUPFD_CLOEXEC (int; since Linux 2.6.24) 33 As for F_DUPFD, but additionally set the close-on-exec flag for the duplicate descriptor. Specifying 34 this flag permits a program to avoid an additional fcntl() F_SETFD operation to set the FD_CLOEXEC 35 flag. For an explanation of why this flag is useful, see the description of O_CLOEXEC in open(2). 36 37 File descriptor flags 38 The following commands manipulate the flags associated with a file descriptor. Currently, only one such flag 39 is defined: FD_CLOEXEC, the close-on-exec flag. If the FD_CLOEXEC bit is 0, the file descriptor will remain 40 open across an execve(2), otherwise it will be closed. 41 42 F_GETFD (void) 43 Read the file descriptor flags; arg is ignored. 44 45 F_SETFD (int) 46 Set the file descriptor flags to the value specified by arg. 47 48 File status flags 49 Each open file description has certain associated status flags, initialized by open(2) and possibly modified 50 by fcntl(). Duplicated file descriptors (made with dup(2), fcntl(F_DUPFD), fork(2), etc.) refer to the same 51 open file description, and thus share the same file status flags. 52 53 The file status flags and their semantics are described in open(2). 54 55 F_GETFL (void) 56 Get the file access mode and the file status flags; arg is ignored. 57 58 F_SETFL (int) 59 Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, 60 O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored. On 61 Linux this command can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags. 62 63 Advisory locking 64 F_GETLK, F_SETLK and F_SETLKW are used to acquire, release, and test for the existence of record locks (also 65 known as file-segment or file-region locks). The third argument, lock, is a pointer to a structure that has 66 at least the following fields (in unspecified order). 67 68 struct flock { 69 ... 70 short l_type; /* Type of lock: F_RDLCK, 71 F_WRLCK, F_UNLCK */ 72 short l_whence; /* How to interpret l_start: 73 SEEK_SET, SEEK_CUR, SEEK_END */ 74 off_t l_start; /* Starting offset for lock */ 75 off_t l_len; /* Number of bytes to lock */ 76 pid_t l_pid; /* PID of process blocking our lock 77 (F_GETLK only) */ 78 ... 79 }; 80 81 The l_whence, l_start, and l_len fields of this structure specify the range of bytes we wish to lock. Bytes 82 past the end of the file may be locked, but not bytes before the start of the file. 83 84 l_start is the starting offset for the lock, and is interpreted relative to either: the start of the file (if 85 l_whence is SEEK_SET); the current file offset (if l_whence is SEEK_CUR); or the end of the file (if l_whence 86 is SEEK_END). In the final two cases, l_start can be a negative number provided the offset does not lie 87 before the start of the file. 88 89 l_len specifies the number of bytes to be locked. If l_len is positive, then the range to be locked covers 90 bytes l_start up to and including l_start+l_len-1. Specifying 0 for l_len has the special meaning: lock all 91 bytes starting at the location specified by l_whence and l_start through to the end of file, no matter how 92 large the file grows. 93 94 POSIX.1-2001 allows (but does not require) an implementation to support a negative l_len value; if l_len is 95 negative, the interval described by lock covers bytes l_start+l_len up to and including l_start-1. This is 96 supported by Linux since kernel versions 2.4.21 and 2.5.49. 97 98 The l_type field can be used to place a read (F_RDLCK) or a write (F_WRLCK) lock on a file. Any number of 99 processes may hold a read lock (shared lock) on a file region, but only one process may hold a write lock 100 (exclusive lock). An exclusive lock excludes all other locks, both shared and exclusive. A single process 101 can hold only one type of lock on a file region; if a new lock is applied to an already-locked region, then 102 the existing lock is converted to the new lock type. (Such conversions may involve splitting, shrinking, or 103 coalescing with an existing lock if the byte range specified by the new lock does not precisely coincide with 104 the range of the existing lock.) 105 106 F_SETLK (struct flock *) 107 Acquire a lock (when l_type is F_RDLCK or F_WRLCK) or release a lock (when l_type is F_UNLCK) on the 108 bytes specified by the l_whence, l_start, and l_len fields of lock. If a conflicting lock is held by 109 another process, this call returns -1 and sets errno to EACCES or EAGAIN. 110 111 F_SETLKW (struct flock *) 112 As for F_SETLK, but if a conflicting lock is held on the file, then wait for that lock to be released. 113 If a signal is caught while waiting, then the call is interrupted and (after the signal handler has 114 returned) returns immediately (with return value -1 and errno set to EINTR; see signal(7)). 115 116 F_GETLK (struct flock *) 117 On input to this call, lock describes a lock we would like to place on the file. If the lock could be 118 placed, fcntl() does not actually place it, but returns F_UNLCK in the l_type field of lock and leaves 119 the other fields of the structure unchanged. If one or more incompatible locks would prevent this 120 lock being placed, then fcntl() returns details about one of these locks in the l_type, l_whence, 121 l_start, and l_len fields of lock and sets l_pid to be the PID of the process holding that lock. 122 123 In order to place a read lock, fd must be open for reading. In order to place a write lock, fd must be open 124 for writing. To place both types of lock, open a file read-write. 125 126 As well as being removed by an explicit F_UNLCK, record locks are automatically released when the process 127 terminates or if it closes any file descriptor referring to a file on which locks are held. This is bad: it 128 means that a process can lose the locks on a file like /etc/passwd or /etc/mtab when for some reason a 129 library function decides to open, read and close it. 130 131 Record locks are not inherited by a child created via fork(2), but are preserved across an execve(2). 132 133 Because of the buffering performed by the stdio(3) library, the use of record locking with routines in that 134 package should be avoided; use read(2) and write(2) instead. 135 136 Mandatory locking 137 (Non-POSIX.) The above record locks may be either advisory or mandatory, and are advisory by default. 138 139 Advisory locks are not enforced and are useful only between cooperating processes. 140 141 Mandatory locks are enforced for all processes. If a process tries to perform an incompatible access (e.g., 142 read(2) or write(2)) on a file region that has an incompatible mandatory lock, then the result depends upon 143 whether the O_NONBLOCK flag is enabled for its open file description. If the O_NONBLOCK flag is not enabled, 144 then system call is blocked until the lock is removed or converted to a mode that is compatible with the 145 access. If the O_NONBLOCK flag is enabled, then the system call fails with the error EAGAIN. 146 147 To make use of mandatory locks, mandatory locking must be enabled both on the filesystem that contains the 148 file to be locked, and on the file itself. Mandatory locking is enabled on a filesystem using the "-o mand" 149 option to mount(8), or the MS_MANDLOCK flag for mount(2). Mandatory locking is enabled on a file by dis‐ 150 abling group execute permission on the file and enabling the set-group-ID permission bit (see chmod(1) and 151 chmod(2)). 152 153 The Linux implementation of mandatory locking is unreliable. See BUGS below. 154 155 Managing signals 156 F_GETOWN, F_SETOWN, F_GETOWN_EX, F_SETOWN_EX, F_GETSIG and F_SETSIG are used to manage I/O availability sig‐ 157 nals: 158 159 F_GETOWN (void) 160 Return (as the function result) the process ID or process group currently receiving SIGIO and SIGURG 161 signals for events on file descriptor fd. Process IDs are returned as positive values; process group 162 IDs are returned as negative values (but see BUGS below). arg is ignored. 163 164 F_SETOWN (int) 165 Set the process ID or process group ID that will receive SIGIO and SIGURG signals for events on file 166 descriptor fd to the ID given in arg. A process ID is specified as a positive value; a process group 167 ID is specified as a negative value. Most commonly, the calling process specifies itself as the owner 168 (that is, arg is specified as getpid(2)). 169 170 If you set the O_ASYNC status flag on a file descriptor by using the F_SETFL command of fcntl(), a 171 SIGIO signal is sent whenever input or output becomes possible on that file descriptor. F_SETSIG can 172 be used to obtain delivery of a signal other than SIGIO. If this permission check fails, then the 173 signal is silently discarded. 174 175 Sending a signal to the owner process (group) specified by F_SETOWN is subject to the same permissions 176 checks as are described for kill(2), where the sending process is the one that employs F_SETOWN (but 177 see BUGS below). 178 179 If the file descriptor fd refers to a socket, F_SETOWN also selects the recipient of SIGURG signals 180 that are delivered when out-of-band data arrives on that socket. (SIGURG is sent in any situation 181 where select(2) would report the socket as having an "exceptional condition".) 182 183 The following was true in 2.6.x kernels up to and including kernel 2.6.11: 184 185 If a nonzero value is given to F_SETSIG in a multithreaded process running with a threading 186 library that supports thread groups (e.g., NPTL), then a positive value given to F_SETOWN has a 187 different meaning: instead of being a process ID identifying a whole process, it is a thread ID 188 identifying a specific thread within a process. Consequently, it may be necessary to pass 189 F_SETOWN the result of gettid(2) instead of getpid(2) to get sensible results when F_SETSIG is 190 used. (In current Linux threading implementations, a main thread's thread ID is the same as 191 its process ID. This means that a single-threaded program can equally use gettid(2) or get‐ 192 pid(2) in this scenario.) Note, however, that the statements in this paragraph do not apply to 193 the SIGURG signal generated for out-of-band data on a socket: this signal is always sent to 194 either a process or a process group, depending on the value given to F_SETOWN. 195 196 The above behavior was accidentally dropped in Linux 2.6.12, and won't be restored. From Linux 2.6.32 197 onward, use F_SETOWN_EX to target SIGIO and SIGURG signals at a particular thread. 198 199 F_GETOWN_EX (struct f_owner_ex *) (since Linux 2.6.32) 200 Return the current file descriptor owner settings as defined by a previous F_SETOWN_EX operation. The 201 information is returned in the structure pointed to by arg, which has the following form: 202 203 struct f_owner_ex { 204 int type; 205 pid_t pid; 206 }; 207 208 The type field will have one of the values F_OWNER_TID, F_OWNER_PID, or F_OWNER_PGRP. The pid field 209 is a positive integer representing a thread ID, process ID, or process group ID. See F_SETOWN_EX for 210 more details. 211 212 F_SETOWN_EX (struct f_owner_ex *) (since Linux 2.6.32) 213 This operation performs a similar task to F_SETOWN. It allows the caller to direct I/O availability 214 signals to a specific thread, process, or process group. The caller specifies the target of signals 215 via arg, which is a pointer to a f_owner_ex structure. The type field has one of the following val‐ 216 ues, which define how pid is interpreted: 217 218 F_OWNER_TID 219 Send the signal to the thread whose thread ID (the value returned by a call to clone(2) or get‐ 220 tid(2)) is specified in pid. 221 222 F_OWNER_PID 223 Send the signal to the process whose ID is specified in pid. 224 225 F_OWNER_PGRP 226 Send the signal to the process group whose ID is specified in pid. (Note that, unlike with 227 F_SETOWN, a process group ID is specified as a positive value here.) 228 229 F_GETSIG (void) 230 Return (as the function result) the signal sent when input or output becomes possible. A value of 231 zero means SIGIO is sent. Any other value (including SIGIO) is the signal sent instead, and in this 232 case additional info is available to the signal handler if installed with SA_SIGINFO. arg is ignored. 233 234 F_SETSIG (int) 235 Set the signal sent when input or output becomes possible to the value given in arg. A value of zero 236 means to send the default SIGIO signal. Any other value (including SIGIO) is the signal to send 237 instead, and in this case additional info is available to the signal handler if installed with SA_SIG‐ 238 INFO. 239 240 By using F_SETSIG with a nonzero value, and setting SA_SIGINFO for the signal handler (see sigac‐ 241 tion(2)), extra information about I/O events is passed to the handler in a siginfo_t structure. If 242 the si_code field indicates the source is SI_SIGIO, the si_fd field gives the file descriptor associ‐ 243 ated with the event. Otherwise, there is no indication which file descriptors are pending, and you 244 should use the usual mechanisms (select(2), poll(2), read(2) with O_NONBLOCK set etc.) to determine 245 which file descriptors are available for I/O. 246 247 By selecting a real time signal (value >= SIGRTMIN), multiple I/O events may be queued using the same 248 signal numbers. (Queuing is dependent on available memory). Extra information is available if 249 SA_SIGINFO is set for the signal handler, as above. 250 251 Note that Linux imposes a limit on the number of real-time signals that may be queued to a process 252 (see getrlimit(2) and signal(7)) and if this limit is reached, then the kernel reverts to delivering 253 SIGIO, and this signal is delivered to the entire process rather than to a specific thread. 254 255 Using these mechanisms, a program can implement fully asynchronous I/O without using select(2) or poll(2) 256 most of the time. 257 258 The use of O_ASYNC, F_GETOWN, F_SETOWN is specific to BSD and Linux. F_GETOWN_EX, F_SETOWN_EX, F_GETSIG, and 259 F_SETSIG are Linux-specific. POSIX has asynchronous I/O and the aio_sigevent structure to achieve similar 260 things; these are also available in Linux as part of the GNU C Library (Glibc). 261 262 Leases 263 F_SETLEASE and F_GETLEASE (Linux 2.4 onward) are used (respectively) to establish a new lease, and retrieve 264 the current lease, on the open file description referred to by the file descriptor fd. A file lease provides 265 a mechanism whereby the process holding the lease (the "lease holder") is notified (via delivery of a signal) 266 when a process (the "lease breaker") tries to open(2) or truncate(2) the file referred to by that file 267 descriptor. 268 269 F_SETLEASE (int) 270 Set or remove a file lease according to which of the following values is specified in the integer arg: 271 272 F_RDLCK 273 Take out a read lease. This will cause the calling process to be notified when the file is 274 opened for writing or is truncated. A read lease can be placed only on a file descriptor that 275 is opened read-only. 276 277 F_WRLCK 278 Take out a write lease. This will cause the caller to be notified when the file is opened for 279 reading or writing or is truncated. A write lease may be placed on a file only if there are no 280 other open file descriptors for the file. 281 282 F_UNLCK 283 Remove our lease from the file. 284 285 Leases are associated with an open file description (see open(2)). This means that duplicate file descrip‐ 286 tors (created by, for example, fork(2) or dup(2)) refer to the same lease, and this lease may be modified or 287 released using any of these descriptors. Furthermore, the lease is released by either an explicit F_UNLCK 288 operation on any of these duplicate descriptors, or when all such descriptors have been closed. 289 290 Leases may be taken out only on regular files. An unprivileged process may take out a lease only on a file 291 whose UID (owner) matches the filesystem UID of the process. A process with the CAP_LEASE capability may 292 take out leases on arbitrary files. 293 294 F_GETLEASE (void) 295 Indicates what type of lease is associated with the file descriptor fd by returning either F_RDLCK, 296 F_WRLCK, or F_UNLCK, indicating, respectively, a read lease , a write lease, or no lease. arg is 297 ignored. 298 299 When a process (the "lease breaker") performs an open(2) or truncate(2) that conflicts with a lease estab‐ 300 lished via F_SETLEASE, the system call is blocked by the kernel and the kernel notifies the lease holder by 301 sending it a signal (SIGIO by default). The lease holder should respond to receipt of this signal by doing 302 whatever cleanup is required in preparation for the file to be accessed by another process (e.g., flushing 303 cached buffers) and then either remove or downgrade its lease. A lease is removed by performing an 304 F_SETLEASE command specifying arg as F_UNLCK. If the lease holder currently holds a write lease on the file, 305 and the lease breaker is opening the file for reading, then it is sufficient for the lease holder to down‐ 306 grade the lease to a read lease. This is done by performing an F_SETLEASE command specifying arg as F_RDLCK. 307 308 If the lease holder fails to downgrade or remove the lease within the number of seconds specified in 309 /proc/sys/fs/lease-break-time then the kernel forcibly removes or downgrades the lease holder's lease. 310 311 Once a lease break has been initiated, F_GETLEASE returns the target lease type (either F_RDLCK or F_UNLCK, 312 depending on what would be compatible with the lease breaker) until the lease holder voluntarily downgrades 313 or removes the lease or the kernel forcibly does so after the lease break timer expires. 314 315 Once the lease has been voluntarily or forcibly removed or downgraded, and assuming the lease breaker has not 316 unblocked its system call, the kernel permits the lease breaker's system call to proceed. 317 318 If the lease breaker's blocked open(2) or truncate(2) is interrupted by a signal handler, then the system 319 call fails with the error EINTR, but the other steps still occur as described above. If the lease breaker is 320 killed by a signal while blocked in open(2) or truncate(2), then the other steps still occur as described 321 above. If the lease breaker specifies the O_NONBLOCK flag when calling open(2), then the call immediately 322 fails with the error EWOULDBLOCK, but the other steps still occur as described above. 323 324 The default signal used to notify the lease holder is SIGIO, but this can be changed using the F_SETSIG com‐ 325 mand to fcntl(). If a F_SETSIG command is performed (even one specifying SIGIO), and the signal handler is 326 established using SA_SIGINFO, then the handler will receive a siginfo_t structure as its second argument, and 327 the si_fd field of this argument will hold the descriptor of the leased file that has been accessed by 328 another process. (This is useful if the caller holds leases against multiple files). 329 330 File and directory change notification (dnotify) 331 F_NOTIFY (int) 332 (Linux 2.4 onward) Provide notification when the directory referred to by fd or any of the files that 333 it contains is changed. The events to be notified are specified in arg, which is a bit mask specified 334 by ORing together zero or more of the following bits: 335 336 DN_ACCESS A file was accessed (read, pread, readv) 337 DN_MODIFY A file was modified (write, pwrite, writev, truncate, ftruncate). 338 DN_CREATE A file was created (open, creat, mknod, mkdir, link, symlink, rename). 339 DN_DELETE A file was unlinked (unlink, rename to another directory, rmdir). 340 DN_RENAME A file was renamed within this directory (rename). 341 DN_ATTRIB The attributes of a file were changed (chown, chmod, utime[s]). 342 343 (In order to obtain these definitions, the _GNU_SOURCE feature test macro must be defined before 344 including any header files.) 345 346 Directory notifications are normally "one-shot", and the application must reregister to receive fur‐ 347 ther notifications. Alternatively, if DN_MULTISHOT is included in arg, then notification will remain 348 in effect until explicitly removed. 349 350 A series of F_NOTIFY requests is cumulative, with the events in arg being added to the set already 351 monitored. To disable notification of all events, make an F_NOTIFY call specifying arg as 0. 352 353 Notification occurs via delivery of a signal. The default signal is SIGIO, but this can be changed 354 using the F_SETSIG command to fcntl(). In the latter case, the signal handler receives a siginfo_t 355 structure as its second argument (if the handler was established using SA_SIGINFO) and the si_fd field 356 of this structure contains the file descriptor which generated the notification (useful when estab‐ 357 lishing notification on multiple directories). 358 359 Especially when using DN_MULTISHOT, a real time signal should be used for notification, so that multi‐ 360 ple notifications can be queued. 361 362 NOTE: New applications should use the inotify interface (available since kernel 2.6.13), which pro‐ 363 vides a much superior interface for obtaining notifications of filesystem events. See inotify(7). 364 365 Changing the capacity of a pipe 366 F_SETPIPE_SZ (int; since Linux 2.6.35) 367 Change the capacity of the pipe referred to by fd to be at least arg bytes. An unprivileged process 368 can adjust the pipe capacity to any value between the system page size and the limit defined in 369 /proc/sys/fs/pipe-max-size (see proc(5)). Attempts to set the pipe capacity below the page size are 370 silently rounded up to the page size. Attempts by an unprivileged process to set the pipe capacity 371 above the limit in /proc/sys/fs/pipe-max-size yield the error EPERM; a privileged process 372 (CAP_SYS_RESOURCE) can override the limit. When allocating the buffer for the pipe, the kernel may 373 use a capacity larger than arg, if that is convenient for the implementation. The F_GETPIPE_SZ opera‐ 374 tion returns the actual size used. Attempting to set the pipe capacity smaller than the amount of 375 buffer space currently used to store data produces the error EBUSY. 376 377 F_GETPIPE_SZ (void; since Linux 2.6.35) 378 Return (as the function result) the capacity of the pipe referred to by fd. 379 380 RETURN VALUE 381 For a successful call, the return value depends on the operation: 382 383 F_DUPFD The new descriptor. 384 385 F_GETFD Value of file descriptor flags. 386 387 F_GETFL Value of file status flags. 388 389 F_GETLEASE 390 Type of lease held on file descriptor. 391 392 F_GETOWN Value of descriptor owner. 393 394 F_GETSIG Value of signal sent when read or write becomes possible, or zero for traditional SIGIO behavior. 395 396 F_GETPIPE_SZ 397 The pipe capacity. 398 399 All other commands 400 Zero. 401 402 On error, -1 is returned, and errno is set appropriately. 403 404 ERRORS 405 EACCES or EAGAIN 406 Operation is prohibited by locks held by other processes. 407 408 EAGAIN The operation is prohibited because the file has been memory-mapped by another process. 409 410 EBADF fd is not an open file descriptor, or the command was F_SETLK or F_SETLKW and the file descriptor open 411 mode doesn't match with the type of lock requested. 412 413 EDEADLK 414 It was detected that the specified F_SETLKW command would cause a deadlock. 415 416 EFAULT lock is outside your accessible address space. 417 418 EINTR For F_SETLKW, the command was interrupted by a signal; see signal(7). For F_GETLK and F_SETLK, the 419 command was interrupted by a signal before the lock was checked or acquired. Most likely when locking 420 a remote file (e.g., locking over NFS), but can sometimes happen locally. 421 422 EINVAL For F_DUPFD, arg is negative or is greater than the maximum allowable value. For F_SETSIG, arg is not 423 an allowable signal number. 424 425 EMFILE For F_DUPFD, the process already has the maximum number of file descriptors open. 426 427 ENOLCK Too many segment locks open, lock table is full, or a remote locking protocol failed (e.g., locking 428 over NFS). 429 430 EPERM Attempted to clear the O_APPEND flag on a file that has the append-only attribute set. 431 432 CONFORMING TO 433 SVr4, 4.3BSD, POSIX.1-2001. Only the operations F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_GETLK, 434 F_SETLK and F_SETLKW, are specified in POSIX.1-2001. 435 436 F_GETOWN and F_SETOWN are specified in POSIX.1-2001. (To get their definitions, define BSD_SOURCE, or 437 _XOPEN_SOURCE with the value 500 or greater, or define _POSIX_C_SOURCE with the value 200809L or greater.) 438 439 F_DUPFD_CLOEXEC is specified in POSIX.1-2008. (To get this definition, define _POSIX_C_SOURCE with the value 440 200809L or greater, or _XOPEN_SOURCE with the value 700 or greater.) 441 442 F_GETOWN_EX, F_SETOWN_EX, F_SETPIPE_SZ, F_GETPIPE_SZ, F_GETSIG, F_SETSIG, F_NOTIFY, F_GETLEASE, and 443 F_SETLEASE are Linux-specific. (Define the _GNU_SOURCE macro to obtain these definitions.) 444 445 NOTES 446 The original Linux fcntl() system call was not designed to handle large file offsets (in the flock struc‐ 447 ture). Consequently, an fcntl64() system call was added in Linux 2.4. The newer system call employs a dif‐ 448 ferent structure for file locking, flock64, and corresponding commands, F_GETLK64, F_SETLK64, and F_SETLKW64. 449 However, these details can be ignored by applications using glibc, whose fcntl() wrapper function transpar‐ 450 ently employs the more recent system call where it is available. 451 452 The errors returned by dup2(2) are different from those returned by F_DUPFD. 453 454 Since kernel 2.0, there is no interaction between the types of lock placed by flock(2) and fcntl(). 455 456 Several systems have more fields in struct flock such as, for example, l_sysid. Clearly, l_pid alone is not 457 going to be very useful if the process holding the lock may live on a different machine. 458 459 BUGS 460 A limitation of the Linux system call conventions on some architectures (notably i386) means that if a (nega‐ 461 tive) process group ID to be returned by F_GETOWN falls in the range -1 to -4095, then the return value is 462 wrongly interpreted by glibc as an error in the system call; that is, the return value of fcntl() will be -1, 463 and errno will contain the (positive) process group ID. The Linux-specific F_GETOWN_EX operation avoids this 464 problem. Since glibc version 2.11, glibc makes the kernel F_GETOWN problem invisible by implementing 465 F_GETOWN using F_GETOWN_EX. 466 467 In Linux 2.4 and earlier, there is bug that can occur when an unprivileged process uses F_SETOWN to specify 468 the owner of a socket file descriptor as a process (group) other than the caller. In this case, fcntl() can 469 return -1 with errno set to EPERM, even when the owner process (group) is one that the caller has permission 470 to send signals to. Despite this error return, the file descriptor owner is set, and signals will be sent to 471 the owner. 472 473 The implementation of mandatory locking in all known versions of Linux is subject to race conditions which 474 render it unreliable: a write(2) call that overlaps with a lock may modify data after the mandatory lock is 475 acquired; a read(2) call that overlaps with a lock may detect changes to data that were made only after a 476 write lock was acquired. Similar races exist between mandatory locks and mmap(2). It is therefore inadvis‐ 477 able to rely on mandatory locking. 478 479 SEE ALSO 480 dup2(2), flock(2), open(2), socket(2), lockf(3), capabilities(7), feature_test_macros(7) 481 482 locks.txt, mandatory-locking.txt, and dnotify.txt in the Linux kernel source directory Documentation/filesys‐ 483 tems/ (on older kernels, these files are directly under the Documentation/ directory, and mandatory-lock‐ 484 ing.txt is called mandatory.txt) 485 486 COLOPHON 487 This page is part of release 3.54 of the Linux man-pages project. A description of the project, and informa‐ 488 tion about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/. 489 490 491 492 Linux 2012-04-15 FCNTL(2)
1 /******************************************************************* 2 * > File Name: lock_set.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Mon 27 Nov 2017 10:35:41 PM CST 6 ******************************************************************/ 7 8 #include "lock_set.h" 9 10 int lock_set(int fd, int type){ 11 struct flock old_lock, lock; 12 13 lock.l_whence = SEEK_SET; 14 lock.l_start = 0; 15 lock.l_len = 0; 16 lock.l_type = type; 17 lock.l_pid = -1; 18 19 /*判断文件是否上锁*/ 20 fcntl(fd, F_GETLK, &lock); 21 22 if(lock.l_type != F_UNLCK){ 23 /*判断文件不能上锁的原因*/ 24 if(lock.l_type == F_RDLCK){ 25 /*该文件已有读取锁*/ 26 printf("Read lock already set by %d\n", lock.l_pid); 27 }else if(lock.l_type == F_WRLCK){ 28 /*该文件已有写入锁*/ 29 printf("Write lock already set by %d\n", lock.l_pid); 30 } 31 } 32 33 /*l_type可能已被F_GETLK修改过*/ 34 lock.l_type = type; 35 /*根据不同的type值进行阻塞上锁或解锁*/ 36 if((fcntl(fd, F_SETLKW, &lock)) < 0){ 37 printf("Lock failed :type = %d\n", lock.l_type); 38 return (-1); 39 } 40 41 switch(lock.l_type){ 42 case F_RDLCK: 43 { 44 printf("Read lock set by %d\n", getpid()); 45 } 46 break; 47 case F_WRLCK: 48 { 49 printf("Write lock set by %d\n", getpid()); 50 } 51 break; 52 case F_UNLCK: 53 { 54 printf("Release lock by %d\n", getpid()); 55 return 1; 56 } 57 break; 58 }/*end of switch*/ 59 60 return 0; 61 } 62 63 #if (0) 64 int main(void) 65 { 66 return 0; 67 } 68 #endif
1 #ifndef __LOCK_SET_H__ 2 #define __LOCK_SET_H__ 3 4 #include <stdio.h> 5 #include <unistd.h> 6 #include <fcntl.h> 7 #include "lock_set.h" 8 9 int lock_set(int fd, int type); 10 11 #endif
1 /******************************************************************* 2 * > File Name: fcntl_read.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Tue 28 Nov 2017 12:25:57 AM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <sys/file.h> 11 #include <sys/types.h> 12 #include <sys/stat.h> 13 #include <stdlib.h> 14 #include "lock_set.h" 15 16 int main(int argc, char* argv[]) 17 { 18 int fd; 19 20 fd = open("Hello", O_RDWR|O_CREAT, 0644); 21 if(fd < 0){ 22 printf("Open file error\n"); 23 exit(1); 24 } 25 26 /*给文件上读取锁*/ 27 lock_set(fd, F_RDLCK); 28 getchar(); 29 30 /*给文件解锁*/ 31 lock_set(fd, FUNLCK); 32 getchar(); 33 close(fd); 34 35 return 0; 36 }
1 /******************************************************************* 2 * > File Name: write_lock.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Mon 27 Nov 2017 11:45:20 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <sys/file.h> 10 #include <sys/stat.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include "lock_set.h" 14 15 int lock_set(int fd, int type); 16 17 int main(int argc, char* argv[]) 18 { 19 int fd; 20 21 /*首先打开文件*/ 22 if((fd = open("hello", O_RDWR|O_CREAT)) < 0){ 23 perror("fail to open"); 24 return -1; 25 } 26 27 /*给文件上锁*/ 28 lock_set(fd, F_WRLCK); 29 getchar(); //等待用户键盘输入 30 31 /*给文件解锁*/ 32 lock_set(fd, F_UNLCK); 33 getchar(); 34 close(fd); 35 36 return 0; 37 }
2.3实验内容——生产者和消费者
1 /******************************************************************* 2 * > File Name: producer.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Tue 28 Nov 2017 11:20:29 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <fcntl.h> 13 #include "lock_set.h" 14 15 #define MAXLEN 10 /*缓冲区大小最大值*/ 16 #define ALPHABET 1 /*表示使用英文字符*/ 17 #define ALPHABET_START 'a' /*头一个字符,可以用'A'*/ 18 #define COUNT_OF_ALPHABET 26 /*字母字符的个数*/ 19 #define DIGIT 2 /*表示使用数字字符*/ 20 #define DIGIT_START '0' /*头一个字符*/ 21 #define COUNT_OF_DIGIT 10 /*数字字符的个数*/ 22 #define SIGN_TYPE ALPHABET /*本实例选用英文字符*/ 23 const char *fifo_file = "./myfifo"; /*仿真FIFO文件名*/ 24 char buff[MAXLEN]; /*缓冲区*/ 25 26 /*功能:生产一个字符并写入仿真FIFO文件中*/ 27 int product(void){ 28 int fd; 29 unsigned int sign_type, sign_start, sign_count, size; 30 static unsigned int counter = 0; 31 32 /*打开仿真FIFO文件*/ 33 if((fd = open(fifo_file, O_CREAT|O_RDWR|O_APPEND, 0644)) < 0){ 34 perror("Open fifo_file error :");exit(EXIT_FAILURE); 35 } 36 37 sign_type = SIGN_TYPE; 38 switch(sign_type){ 39 case ALPHABET:/*英文字符*/ 40 { 41 sign_start = ALPHABET_START; 42 sign_count = COUNT_OF_ALPHABET; 43 } 44 break; 45 case DIGIT:/*数字字符*/ 46 { 47 sign_start = DIGIT_START; 48 sign_count = COUNT_OF_DIGIT; 49 } 50 break; 51 default: 52 { 53 return -1; 54 } 55 }/*end of switch*/ 56 57 sprintf(buff, "%c", (sign_start + counter)); 58 counter = (counter + 1)%sign_count; 59 60 lock_set(fd, F_WRLCK); /*上写锁*/ 61 if((size = write(fd, buff, strlen(buff))) < 0){ 62 printf("Producer write error\n"); 63 return -1; 64 } 65 66 lock_set(fd, F_UNLCK); /*解锁*/ 67 68 close(fd); 69 return 0; 70 } 71 72 int main(int argc, char* argv[]) 73 { 74 int time_step = 1; /*生产周期*/ 75 int time_life = 10; /*需要生产的资源总数*/ 76 77 if(argc > 1){ 78 /*第一个参数表示生产周期*/ 79 sscanf(argv[1], "%d", &time_step); 80 } 81 82 if(argc > 2){ 83 /*第二个参数表示需要生产的资源数*/ 84 sscanf(argv[2], "%d", &time_life); 85 } 86 87 while(time_life --){ 88 if(product() <0){ 89 break; 90 } 91 sleep(time_step); 92 } 93 94 exit(EXIT_SUCCESS); 95 }
1 /******************************************************************* 2 * > File Name: customer.c 3 * > Author: fly 4 * > Mail: XXXXXXXX@icode.com 5 * > Create Time: Wed 29 Nov 2017 08:32:23 PM CST 6 ******************************************************************/ 7 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <stdlib.h> 11 #include <fcntl.h> 12 #include "lock_set.h" 13 14 #define MAX_FILE_SIZE 100*1024*1024 /*100MB*/ 15 16 const char *fifo_file = "./myfifo"; /*仿真FIFO文件名*/ 17 const char *tmp_file = "./tmp"; /*临时文件名*/ 18 19 /*资源消费函数*/ 20 int customing(const char *myfifo, int need){ 21 int fd; 22 char buff; 23 int counter = 0; 24 25 /*以可读方式打开文件*/ 26 if((fd = open(myfifo, O_RDONLY)) < 0){ 27 printf("Function customing error\n"); 28 return -1; 29 } 30 31 printf("Enjoy :"); 32 /*找到文件的开头*/ 33 lseek(fd, SEEK_SET, 0); 34 35 while(counter < need){ 36 while((read(fd, &buff, 1) == 1) && (counter < need)){ 37 fputc(buff, stdout); /*消费者就是在屏幕上简单的显示*/ 38 counter ++; 39 } 40 } 41 42 fputs("\n", stdout); 43 close(fd); 44 return 0; 45 } 46 47 /*功能:从sour_file文件的offset偏移处开始将count个字节数据复制到dest_file文件*/ 48 int myfilecopy(const char *sour_file, const char *dest_file, int offset, int count, int copy_mode){ 49 int in_file, out_file; 50 int counter = 0; 51 char buf_unit; 52 53 if((in_file = open(sour_file, O_RDONLY|O_NONBLOCK)) < 0){ 54 printf("Function myfilecopy error in source file\n");return (-1); 55 } 56 57 if((out_file = open(dest_file, O_CREAT|O_RDWR|O_TRUNC|O_NONBLOCK, 0644)) < 0){ 58 printf("Function myfilecopy error in destination file :");return (-1); 59 } 60 61 lseek(in_file, offset, SEEK_SET); 62 while((read(in_file, &buf_unit, 1)) && (counter < count)){ 63 write(out_file, &buf_unit, 1); 64 counter ++; 65 } 66 67 close(in_file);close(out_file); 68 return 0; 69 } 70 71 /*功能:实现FIFO消费者*/ 72 int custom(int need){ 73 int fd; 74 75 /*对资源进行消费,need表示该消费的资源数目*/ 76 customing(fifo_file, need); 77 78 if((fd = open(fifo_file, O_RDWR)) < 0){ 79 perror("Function myfilecopy error in source_file :");return (-1); 80 } 81 82 /*为了模拟FIFO结构,对整个文件内容进行平行移动*/ 83 lock_set(fd, F_WRLCK); 84 myfilecopy(fifo_file, tmp_file, need, MAX_FILE_SIZE, 0); 85 myfilecopy(tmp_file, fifo_file, 0, MAX_FILE_SIZE, 0); 86 lock_set(fd, F_UNLCK); 87 unlink(tmp_file); 88 close(fd); 89 return 0; 90 } 91 92 int main(int argc, char* argv[]) 93 { 94 int customer_capacity = 10; 95 96 if(argc > 1){ 97 /*第一个参数指定需要消费的资源数目,默认值为10*/ 98 sscanf(argv[1], "%d", &customer_capacity); 99 } 100 101 if(customer_capacity > 0){ 102 custom(customer_capacity); 103 } 104 105 exit(EXIT_SUCCESS); 106 }