3.檔案io

3.1 檔案核心資料結構

3.2 複製檔案描述符的核心資料結構

3.3 對指定的描述符列印檔案標誌

#include "apue.h"
#include <fcntl.h> int
main(int argc, char *argv[])
{
int val; if (argc != 2)
err_quit("usage: a.out <descriptor#>"); 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 (val & O_SYNC)
printf(", synchronous writes"); #if !defined(_POSIX_C_SOURCE) && defined(O_FSYNC) && (O_FSYNC != O_SYNC)
if (val & O_FSYNC)
printf(", synchronous writes");
#endif putchar('\n');
exit(0);
}

結果

3.4 開啟檔案狀態標誌

#include "apue.h"
#include <fcntl.h> void
set_fl(int fd, int flags) /* flags are file status flags to turn on */
{
int val; if ((val = fcntl(fd, F_GETFL, 0)) < 0)
err_sys("fcntl F_GETFL error"); val |= flags; /* turn on flags */ if (fcntl(fd, F_SETFL, val) < 0)
err_sys("fcntl F_SETFL error");
}

如果將中間的一條語句修改如下(關閉檔案標誌):

val &= ~flags;  //turn flags off

3.5 將標誌輸入複製到標準輸出

#include "apue.h"

#define	BUFFSIZE	4096

int
main(void)
{
int n;
char buf[BUFFSIZE]; //set_fl(STDOUT_FILENO,O_SYNC) //開啟同步寫標誌
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);
}

程式執行時,設定O_SYNC會增加系統時間和時鐘時間。

4.檔案和目錄

4.1 access函式的使用

#include "apue.h"
#include <fcntl.h> int
main(int argc, char *argv[])
{
if (argc != 2)
err_quit("usage: a.out <pathname>");
if (access(argv[1], R_OK) < 0)
err_ret("access error for %s", argv[1]);
else
printf("read access OK\n");
if (open(argv[1], O_RDONLY) < 0)
err_ret("open error for %s", argv[1]);
else
printf("open for reading OK\n");
exit(0);
}

8.程序控制

8.1 fork函式例項

#include "apue.h"

int		globvar = 6;		/* external variable in initialized data */
char buf[] = "a write to stdout\n"; int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid; var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
err_sys("write error");
printf("before fork\n"); /* we don't flush stdout */ if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
globvar++; /* modify variables */
var++;
} else {
sleep(2); /* parent */
} printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar,
var);
exit(0);
}

執行結果

分析

  • 為啥是sizeof(buf)-1:

  • 為什麼出現有兩次before fork出現:

8.2 fork之後父子程序對檔案的共享

8.3 vfork函式例項

#include "apue.h"

int		globvar = 6;		/* external variable in initialized data */

int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid; var = 88;
printf("before vfork\n"); /* we don't flush stdio */
if ((pid = vfork()) < 0) {
err_sys("vfork error");
} else if (pid == 0) { /* child */
globvar++; /* modify parent's variables */
var++;
_exit(0); /* child terminates */
} /* parent continues here */
printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar,
var);
exit(0);
}

執行結果