unix 环境高级编程(1)

来源:互联网 发布:送货派单软件 编辑:程序博客网 时间:2024/06/16 19:14

既然已经做出决定,就要努力走下去。
文件和目录
unix 文件系统是目录和文件的一种层次, 所有东西的起点是成为根的目录,名称“/”
创建新目录时系统会自动创建两个文件名:. 和.. , . 表示当前目录, ..表示父亲目录
标准输入文件描述符 0 标准输出文件描述符 1 重定向 ./a.out > data a.out的输出重定向至文件data ./a.out outfile 将 infiel 复制到 outfile
程序 进程
程序时一个存储在磁盘上某个目录中的可执行文件。内核使用exec函数将程序读入内存,
进程:程序执行的实例,进程控制的主要函数 frok exec waitpid
文件描述符: 对内核而言,所有打开的文件都会通过文件描述符引用,是非负数, 当读写时通过 open或者creat 返回的文件描述符表示该文件,将其作为参数送给read或者write, 系统shell把文件描输入0 与进程的标准输入关联,文件描述符1与标准输出关联,文件描输入2 与 标准错误关联,
open openat 函数返回的描述符一定时最小的未使用描述符的数值
open(path , flag, …)
openat(fd, path, flag..)
fd 把 open 和 spenat 区分开来:
如果path是绝对路径, 二者没区别
如果path是相对路径, fd参数之处了相对路径在文件系统中的开售位置,fd参数是通过打开相对路径所在的目录来获取
path是相对路径, fd 参数为 AT_FDCWD 在这种情况下,路径名在当前工作目录中获取
create(path, mode) close(fd)
lseek 设置文件偏移量,

#include <fcntl.h>int main(){   int fd;   char buf[] = "abcdefghij";   if((fd = open("test.txt", O_RDWR|O_APPEND)) == -1){       err_sys("open error!");   }   if(lseek(fd, 0, SEEK_SET) == -1)     err_sys("lseek error");   if(write(fd, buf, 10) != 10)     err_sys("write error");   close(fd);   char buf1[] = "abcdefghij";   if((fd = open("test.txt", O_RDWR|O_APPEND)) == -1){       err_sys("open error!");   }   if(lseek(fd, 0, SEEK_SET) == -1)     err_sys("lseek error");   if(read(fd, buf1, 10) != 10)     err_sys("read error");    printf("%s",buf1);   close(fd);

可以通过 od 来观察文件的实际内容
注意: 当 文件打开mode 设置为 O_APPEND时,无论怎样设置偏移量文件的写操作总是进行在文件的末尾,读操作则可以从偏移量开始。
文件的偏移量可以为负值,所以在监测时,应监测他是不是等于-1
文件有可能出现空洞,但是却不占盘块。

read 从文件中读数据
write 从文件中写数据

文件共享 dup dup2
进程:
每一个进程都有一个记录项,记录项中包含一张打开文件描述符表,每个文件描述符占一项(文件描述符标志,指向文件表项的指针)。
内核为所有打开文件维持一张文件表( 文件状态标志, 当前文件偏移量,指向该文件V节点表项的指针)
每个打开文件都有一个v节点结构(包含文件i节点)i节点包括文件长度,指向盘块,所有者)、

原子操作:
pread(int fd, buf, bytes, offset)
pwrite(int fd, bud, butes, offset)
相当于调用lseek 再调用 read write
文件共享, 复制一个现有的文件描述符;
dup(fd) 返回一个最小的当前文件描述符 相当于fcntl(fd, F_DUPFD,0)
dup2(fd1, fd2) 可以用fd2参数指定文件描述符, 如果fd2已经打开,先关闭, 如果fd 等于fd2 ,则不关闭,直接返回 否则FD_CLOEXEC文件描述标志就被清除,这样fd2在进程调用exec是打开状态 相当于 fcntl(fd, F_DUPFD, fd2)

 不同exec来模拟 dup2#include "apue.h"#include "apueerror.h"#include <fcntl.h>#include <stdio.h>#include <stdbool.h>#define MAX_OPENbool mydup2(int fd, int newfd){     //检测fd 时候有效     if(fd < 0 || fd >MAX_OPEN){        printf("fd is wrong!");        return false;     }     //检测newfd 时候有效     if(newfd < 0 || newfd > MAX_OPEN){        printf("newfd is wrong!");        return false;     }     int queue[newfd + 10];     //检测fd 是否是打开状态     if((queue[fd] = dup(fd)) != -1){        printf("error");        return false;     }else{        if(newfd == fd) return true;        int i = 0;       close(newfd);       for(i = 0; i <= newfd; i++){          queue[i] = dup(fd);       if(queue[i] == -1)  {          printf("open already!");          continue;       }else {          if(queue[i] == newfd){             printf("%d!\n",i);             break;           }            queue[i] = MAX_OPEN + 1;       }     }    int j = 0;    将多打开的关闭掉    for( j = 0; j < i; j++){      if(queue[j] == MAX_OPEN + 1)         close(queue[j]);    }   return true;}

sync, sync, fdatasync

当我们向文件读写数据时,内核通常线将数据复制到缓冲区,然后排入队列,玩些时候再卸入磁盘,
sync(fd)将修改过的所有块缓冲区排入写队列, 然后返回, 不等待时机磁盘写操作完成。
fsync(fd)函数支队有文件 描述符fd指定的文件起作用,并且等待写操作完成后才返回。(数据属性都可以更新)
fdatasync()函数类似于 sync, 但他只影响文件的数据部分,

fcntl(fd, cmd …)
复制一个已有文件的描述符 F_DUPFD/ F_DUPFD_CLOEXEC
获取/设置文件描述标志 F _GETFD/ F_SETFD
获取/设置文件状态标志 F_GETFL/ F_SETFL
获取/设置文件异步i/o所有权 F_GETOWN/ F_SETOWN
获取/设置记录锁 F_GETTLK, GE_SETTLK, F_SETLKW

文件和目录
int stat(pathname, stat *buf)
int fstat(fd,stat * buf)
int lstat(pathname, stat*buf)
int fstatat(fd, pathname, struct *buf, flag)

stat 返回于与pathname命名文件的有关信息lstat 获得fd上打开的文件信息, 但是当命名的文件是一个符号链接时,返回改符号的有关信息。fstatat 当一个相对目录打开时,返回文件统计信息。 flag 为 AT_SYMLINK_NOFOLLOW 标志被设置时 fstatat 不会跟随链接,而是返回器本身信息。 如果 fd 的值时 AT_FDCWD 并且pathname时相对目录时。  fstatat会计算当前pathname的目录,but 是一个指向 stat  结构体的指针

文件类型 普通文件,目录文件, 字符特殊文件, 块特殊文件, fifo。 套接字, 符号链接

access(pathname, mode)
faccess(fd, pathname, mode, flag)
如果 flag = AT_EACCESS 访问检查的是调用进程的有效用户id 和有效组id, 而不是实际id

umask 设计文件模式创建屏蔽字并且返回之前的值,
chmod, fchomod., fchomdat 更改现有文件访问权
chown, fchown, lchown, fchownat, 更改文件的用户,文件的用户组
chown(pathname, owner, group)
fchown(fd, pathname, owner, group)
fchownat(fd, pathname, owner, group, flag)
lchown( pathname, owner, group)
如果owner, 或者group又一个为-1 则不改变 ,
文件截断
truncate(pathname, off_t length)
ftruncate(fd, length)
阶段到 length

link, linkat, unlink, unlinked, remove

符号链接
指对一个文件的简介指针, 硬链接直接指向 文件的i节点, 引入符号链接的原因是为了避免硬链接的一些限制 (硬链接要就链接和文件位于一个文件系统, 只有超级用户才能创建硬链接)
创建和读取符号链接
symlink symlinat
int symlink(acpathname, sympath)
int symlinkat(acpahtname, fd, sympath)
创建了一个指向 actualpaht 的新目录项 sympaht , 并不要求actualpath已经存在,

0 0
原创粉丝点击