File Descriptors
A file descriptor is a non-negative integer. When we open an existing file or create a new file, the kernel returns a file descriptor to the process.
STDIN_FILENO
,STDOUT_FILENO
, andSTDERR_FILENO
open
Function
#include <fcntl.h>
int open(const char *pathname, int oflag, ... /* mode_t mode */);
- Returns: file descriptor if OK, -1 on error
- oflag
oflag | meaning |
---|---|
O_RDONLY | Open for reading only. |
O_WRONLY | Open for writing only. |
O_RDWR | Open for reading and writing. |
optional | |
O_APPEND | Append to the end of file on each write. |
O_CREAT | Create the file if it doesn’t exist. This option requires a third argument to the open function, the mode, which specifies the access permission bits of the new file. |
O_EXCL | Generate an error if O_CREAT is also specified and the file already exists. |
O_TRUNC | If the file exists and if it is successfully opened for either write-only or readwrite, truncate its length to 0. |
O_NOCTTY | If the pathname refers to a terminal device, do not allocate the device as the controlling terminal for this process. |
O_NONBLOCK | O_NONBLOCK |
If the pathname refers to a FIFO, a block special file, or a character special file, this option sets the nonblocking mode for both the opening of the file and subsequent I/O. | ||
O_DSYNC | Have each write wait for physical I/O to complete, but don’t wait for file attributes to be updated if they don’t affect the ability to read the data just written. | |
O_RSYNC | O_RSYNC |
Have each read operation on the file descriptor wait until any pending writes for the same portion of the file are complete. | ||
O_SYNC | Have each write wait for physical I/O to complete, including I/O necessary to update file attributes modified as a result of the write. | |
creat
Function
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);
- equivalent to
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
close
Function
#include <unistd.h>
int close(int filedes);
lseek
Function
#include <unistd.h>
off_t lseek(int filedes , off_t offset, int whence);
whence
may be one ofSEEK_SET
,SEEK_CUR
orSEEK_END
#include<stdio.h>
#include <unistd.h>
int main() {
if (lseek(STDIN_FILENO,0,SEEK_SET)<0){
printf("can not seekn");
} else{
printf("can seekn");
}
return 0;
}
> ./seekable.out < /dev/seekable.c
can seek
> cat seekable.c | ./seekable.out
can not seek
#include<stdio.h>
#include <apue.h>
#include <fcntl.h>
int main() {
char buf1[] = "abc";
char buf2[] = "dfe";
int fd;
if ((fd = creat("hole.tmp", FILE_MODE)) < 0)
err_sys("create file errorn");
if ((write(fd, buf1, strlen(buf1))) < 0)
err_sys("write errorn");
if ((lseek(fd, 100000000, SEEK_CUR)) == -1)
err_sys("seek errorn");
if ((write(fd, buf2, strlen(buf2))) < 0)
err_sys("write errorn");
return 0;
}
- A hole in a file isn’t required to have storage backing it on disk
> ./file_hole.out
> dd bs=1 count=100006 if=/dev/zero of=nohole.tmp
100006+0 records in
100006+0 records out
100006 bytes (100 kB) copied, 0.190321 s, 525 kB/s
> ls -ls
12 -rwxr-xr-x 1 lion lion 10872 Nov 12 13:42 file_hole.out
8 -rw-r--r-- 1 lion lion 100006 Nov 12 13:42 hole.tmp
100 -rw-r--r-- 1 lion lion 100006 Nov 12 13:42 nohole.tmp
read
Function
#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
- Returns nuber of bytes read , 0 if EOF , 1 on error
write
Function
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
The return value is usually equal to the nbytes argument; otherwise, an error has occurred.
IO Efficiency
#include<stdio.h>
#include <apue.h>
#include <stdlib.h>
int copy(int bufsize) {
int n;
char buf[bufsize];
while ((n = read(STDIN_FILENO, buf, bufsize)) > 0) {
if (n != write(STDOUT_FILENO, buf, n)) {
err_sys("write errorn");
return -1;
}
}
if (n < 0) {
err_sys("read errorn");
return -1;
}
}
int main(int argc, char **argv) {
if (argc != 2) {
err_sys("usage copy.out bufsizen");
}
int bufsize = atoi(argv[1]);
copy(bufsize);
return 0;
}
File Sharing
Atomic Operation
Appending to a File
pread
and pwrite
Functions
#include <unistd.h>
ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);
ssize_t pwrite(int fileses, const void *buf, size_t nbytes, off_t offset);
Creating a File
dup
and dup2
Functions
#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2);
The new file descriptor returned by dup is guaranteed to be the lowest-numbered available file descriptor.
Withdup2
, we specify the value of the new descriptor with thefiledes2
argument.
Iffiledes2
is already open, it is first closed. Iffiledes
equalsfiledes2
, thendup2
returnsfiledes2
without closing it.
dup2(filedes, filedes2);
is equivalent to
- dup example
```c
#include
#include
#include
int main() {
int fd;
if ((fd = dup(STDOUT_FILENO)) == -1)
err_sys(“dup failed”);
printf(“fd=%dn”, fd);
if (write(fd, “aaan”, 4) != 4)
err_sys(“write failed”);
exit(0);
}
fd=3
aaa
- dup2 return value
```c
close(filedes2);
fcntl(filedes, F_DUPFD, filedes2);
近期评论