本章讲到的函数及程序例子:
1. open function
#include
int open( const char *pathname, int oflag, ... /* mode_t mode */ );
Returns: file descriptor if OK, -1 on error
2. creat function
#include
#include
int creat(const char *pathname, mode_t mode);
Returns: file descriptor opened for write-only if OK, -1 on error
this function is equivalent to:
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
creat只能以只写方式打开文件,因此用open代替creat函数是个不错的选择。
3. close function
#include
int close(int filedes);
Returns: 0 if OK, -1 on error
4. lseek function
The character l in the name lseek means "long integer" 。
#include
off_t lseek(int filedes, off_t offset, int whence);
Returns: new file offset if OK, -1 on error
Figure 3.1. Test whether standard input is capable of seeking
#include "apue.h"
int main(void)
{
if (lseek(STDIN_FILENO, 0, SEEK_CUR) == -1)
printf("cannot seek\n");
else
printf("seek OK\n");
exit(0);
}
程序3.1 测试标准输入能否被设置位移量
程序分析:
(1)按照惯例,UNIX shell使文件描述符0与进程的标准输入相结合,文件描述符1与标准输出相结合,文件描述符2与
标准出错输出相结合。在POSIX.1应用程序中,幻数0、1、2应被代换成符号常数STDIN_FILENO、STDOUT_FILENO和
STDERR_FILENO。这些常数都定义在头文件中,该头文件在apue.h中包含。
(2)lseek函数中对参数offset 的解释与参数whence的值有关。
? 若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset 个字节。
? 若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset, offset可为正或负。
? 若whence是SEEK_END,则将该文件的位移量设置为文件长度加offset, offset可为正或负。
(3)[root@localhost figures]# ./fig3.1
seek OK
通过I/O重定向,将文件fig3.1.c作为程序fig3.1的输入,此时STDIN_FILENO对应的是一个文件,故可以seek;
[root@localhost figures]# cat
cannot seek
通过I/O重定向,将文件fig3.1.c作为cat的输入,由cat输出的fig3.1.c的内容再通过管道作为程序fig3.1的输
入,此时STDIN_FILENO对应的是管道,故不可以seek;
[root@localhost figures]# ./fig3.1
cannot seek
此时程序fig3.1的输入时标准输入,标准输入不可以seek。
Figure 3.2. Create a file with a hole in it
#include "apue.h"
#include
#include
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
int main(void)
{
int fd;
if ((fd = creat("file.hole", FILE_MODE)) < 0)
err_sys("creat error");
if (write(fd, buf1, 10) != 10)
err_sys("buf1 write error");
/* offset now = 10 */
if (lseek(fd, 16384, SEEK_SET) == -1)
err_sys("lseek error");
/* offset now = 16384 */
if (write(fd, buf2, 10) != 10)
err_sys("buf2 write error");
/* offset now = 16394 */
exit(0);
}
(1)[root@localhost figures]# od -c file.hole
0000000 a b c d e f g h i j \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0040000 A B C D E F G H I J
0040012
(2)[root@localhost figures]#vi file.hole
"file.hole" [noeol] 1L, 16394C
5、read function
#include
ssize_t read(int filedes, void *buf, size_t nbytes);
Returns: number of bytes read, 0 if end of file, 1 on error
6、write function
#include
ssize_t write(int filedes, const void *buf, size_t nbytes);
Returns: number of bytes written if OK, -1 on error
Figure 3.4. Copy standard input to standard output
#include "apue.h"
#define BUFFSIZE 4096
int main(void)
{
int n;
char buf[BUFFSIZE];
while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
if (write(STDOUT_FILENO, buf, n) != n)
err_sys("write error");
if (n < 0)
err_sys("read error");
exit(0);
}
(1)考虑到进程终止时,UNIX会关闭所有打开文件描述符,所以此程序并不关闭输入和输出文件。
7、pread and pwrite functions
#include
ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);
Returns: number of bytes read, 0 if end of file, -1 on error
ssize_t pwrite(int filedes, const void *buf, size_t nbytes, off_t offset);
Returns: number of bytes written if OK, -1 on error
当多个进程访问同一个文件时就涉及到了同步与互斥的问题。
The UNIX System provides an atomic way to do this operation if we set the O_APPEND flag when a
file is opened. As we described in the previous section, this causes the kernel to position the file
to its current end of file before each write. We no longer have to call lseek before each write.
8、dup and dup2 functions
#include
int dup(int filedes);
int dup2(int filedes, int filedes2);
Both return: new file descriptor if OK, -1 on error
9、sync, fsync, and fdatasync functions
#include
int fsync(int filedes);
int fdatasync(int filedes);
Returns: 0 if OK, -1 on error
void sync(void);
To ensure consistency of the file system on disk with the contents of the buffer cache, the sync,
fsync, and fdatasync functions are provided.
10、fcntl.h
#include
int fcntl(int filedes, int cmd, ... /* int arg */ );
Returns: depends on cmd if OK (see following), -1 on error
Figure 3.10. Print file flags for specified descriptor
#include "apue.h"
#include
int main(int argc, char *argv[])
{
int val;
if (argc != 2)
err_quit("usage: a.out ");
if ((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)
err_sys("fcntl error for fd %d", atoi(argv[1]));
switch (val & O_ACCMODE)
{
case O_RDONLY:
printf("read only");
break;
case O_WRONLY:
printf("write only");
break;
case O_RDWR:
printf("read write");
break;
default:
err_dump("unknown access mode");
}
if (val & O_APPEND)
printf(", append");
if (val & O_NONBLOCK)
printf(", nonblocking");
#if defined(O_SYNC)
if (val & O_SYNC)
printf(", synchronous writes");
#endif
#if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC)
if (val & O_FSYNC)
printf(", synchronous writes");
#endif
putchar('\n');
exit(0);
}
(1)
11、ioctl function
#include /* System V */
#include /* BSD and Linux */
#include /* XSI STREAMS */
int ioctl(int filedes, int request, ...);
Returns: -1 on error, something else if OK