符号链接

符号链接的用途

符号链接是对一个文件的间接指针,它与前面介绍的硬连接不同,硬连接指向文件的i节点。引入符号链接是为了避开硬连接的一些限制:

  • 硬链接通常要求链接和文件位于同一文件系统中。
  • 只有超级用户才能创建指向目录的硬链接(在底层文件系统支持的情况下)。

而对于符号链接:

  • 对符号链接以及它指向何种对象并无任何文件系统限制;
  • 任何用户都可以创建指向目录的符号链接。

跟随符号链接

符号链接一般用于将一个文件或整个目录结构移到系统中另外一个位置。

用符号链接作为函数参数时,需要了解该函数所处理的是否是符号链接指向的文件。也就是是否跟随符号链接

  • 如果该函数具有处理符号链接的功能,则其路径名参数引用由符号链接指向的文件。
  • 否则,一个路径名参数引用链接本身。

图4-17列出了本章中所说明的各个函数是否处理符号链接。

特殊的例子:

如果同时使用O_CREAT和O_EXCL,调用open函数。

  • 我们知道如果要打开的是文件,而文件已经存在,则出错。如果不存在则创建此文件,这使得测试和创建两者成为一个原子操作。
  • 如果要打开的是符号链接,不管符号链接指向的文件是否存在,都会返回错误。这种处理方式的意图是堵塞一个安全性漏洞,以防止具有特权的进程被诱骗写错误的文件。

    例如:进程A用于写已经存在的A.txt文件,如果删除A.txt文件,而把A.txt文件制作成一个符号链接指向自定义文件,进程就可以随意写任何文件了。

符号链接可能引入循环

使用符号链接可能在文件系统中引入循环。大多数查找路径名的函数在这种情况发生时都将出错返回,errno值为ELOOP。考虑下列命令序列:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ mkdir foo
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ touch foo/a
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ln -s ../foo foo/testdir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ls -l foo
total 0
-rw-rw-r-- 1 harlan harlan 0 Jun 11 16:40 a
lrwxrwxrwx 1 harlan harlan 6 Jun 11 16:40 testdir -> ../foo

图4-18显示了结果:

可以一直循环下去。。。

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ cd foo/testdir/testdir/testdir/testdir
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples/foo/testdir/testdir/testdir/testdir$

Solaris的标准函数ftw以降序遍历文件结构,打印遇到的每个路径名,直至ftw出错返回。但是Linux中的ftw和nftw记录了看到的目录并避免多次重复一个目录,因此这两个函数不显示solaris中ftw的出错运行行为。

open一个符号链接

open函数跟随符号链接,如果符号链接指向的文件不存在,open返回出错,表示它不能打开该文件。这可能会使不熟悉符号链接的用户感到迷茫:

harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ln -s /no/sucn/file myfile
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ ll myfile
lrwxrwxrwx 1 harlan harlan 13 6月 12 08:28 myfile -> /no/sucn/file
harlan@DESKTOP-KU8C3K5:/github/APUE/chapter_4/myexamples$ cat myfile
cat: myfile: 没有那个文件或目录

创建和读取符号链接

使用symlink或者symlinkat函数创建一个符号链接。

#include <unistd.h>
int symlink(const char* actualpath,const char *sympath);
int symlinkat(const char*actualpath,int fd,const char* sympath);
成功返回0;如果出错返回-1

调用这两个函数创建符号链接时:

  • 不要求actualpath已经存在。
  • actualpath和sympath并不需要位于同一个文件系统中。

因为open函数跟随符号链接,因此需要有一种方法打开链接本身,并读该链接中的名字。readlink和readlinkat函数提供了这种功能:

#include <unistd.h>
ssize_t readlink(const char* restrict pathname,char *restrict buf,size_t bufsize);
ssize_t readlinkat(int fd,const char* restrict pathname,char * restrict buf,size_t bufsize);
成功返回读取的字节数;如果失败返回-1。

APUE-文件和目录(七)符号链接的更多相关文章

  1. [APUE]文件和目录(上)

    一.文件权限 1. 各种ID 我在读这一章时遇到了各种ID,根据名字完全不清楚什么意思,幸好看到了这篇文章,http://blog.csdn.net/ccjjnn19890720/article/de ...

  2. [APUE]文件和目录(中)

    一.link.unlink.remove和rename 一个文件可以有多个目录项指向其i节点.使用link函数可以创建一个指向现存文件连接 #include <unistd.h> int ...

  3. APUE 文件和目录

    文件和目录 Unix 所有的文件都对应一个 struct stat,包含了一个文件所有的信息. #include <sys/stat.h> struct stat { mode_t st_ ...

  4. [APUE]文件和目录(下)

    一.mkdir和rmdir函数 #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *pathn ...

  5. APUE ☞ 文件和目录

    粘着位(Sticky Bit) S_ISVTX位被称为粘着位.如果一个可执行程序文件的这一位被设置了,程序第一次运行完之后,程序的正文部分的一个副本仍被保存在交换区(程序的正文部分是机器指令).这使得 ...

  6. [置顶] 文件和目录(二)--unix环境高级编程读书笔记

    在linux中,文件的相关信息都记录在stat这个结构体中,文件长度是记录在stat的st_size成员中.对于普通文件,其长度可以为0,目录的长度一般为1024的倍数,这与linux文件系统中blo ...

  7. UNIX 环境高级编程 文件和目录

    函数stat , fstat , fstatat , lstat stat函数返回与此文件有关的信息结构. fstat函数使用已打开的文件描述符(而stat则使用文件名) fstatat函数 为一个相 ...

  8. Find 查找命令时过滤掉某些文件或目录 以及 -maxdepth、-mindepth的用法

    1)find过滤目录使用find命令在linux系统中查找文件时,有时需要忽略某些目录,可以使用"-path 过滤的目录路径 -prune -o"参数来进行过滤.不过必须注意:要忽 ...

  9. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  10. apue chapter 4 文件和目录

    1.文件信息结构体 struct stat{ mode_t st_mode; //file type and permissions ino_t st_ino; //i-node number (se ...

随机推荐

  1. MVC框架中,遇到 [程序集清单定义与程序集引用不匹配]怎么办?

    项目里有一个WinForm程序,它需要使用一套第三方控件.而我的机器上存有这套控件的两种版本(一个是源码版,一个是演示版).结果经常出现“程序集清单定义与程序集引用不匹配的问题”的异常.最要命的是有时 ...

  2. [ext4]010 磁盘布局 - 如何查找inode的磁盘位置

    在linux系统中,任何一个文件,都有一个inode与其对应,也就是说,在一个文件系统中,一个文件都有唯一的ino来标示他,那么在ext4系统中,ino是如何确定的哪? 当我们新创建的文件或目录时,会 ...

  3. jquery的ajax与spring mvc对接注意事项

    昨天一直纠结这么一个问题,应用场景是这样的: 这里登陆是通过jquery的ajax传输数据到后台controller类相应的映射mapping接收.本来是想,在后台验证成功之后返回一个视图modelA ...

  4. linux 内核的futex

    futex是linux内核为用户空间实现锁等同步机制而设计的同步排队(队列queueing)服务.在futex.c的注释中,futex起源于"Fast Userspace Mutex&quo ...

  5. Webgis开源解决方案之环境搭建(三)

    前两篇文章介绍了开源GIS服务器Geoserver的安装以及开源数据库Postgres的安装,这篇文章介绍开源前端udig软件的安装,使用在后续篇幅中介绍 开源前端目前主流的是QGIS或者udig,网 ...

  6. 基于三层交换机和基于路由子接口的vlan间路由

    1:通过三层交换机实现vlan间的通信:为三层交换机创建vlan,设置交换机的两个SVI,并配置IP地址. (在二层交换机上只能配置一个SVI端口,用来实现交换机交换机远程管理,在三层交换机上可以配置 ...

  7. [刷题]Codeforces 746G - New Roads

    Description There are n cities in Berland, each of them has a unique id - an integer from 1 to n, th ...

  8. SpringData系列二 Repository接口

    本节主要介绍Repository接口规范,及其子接口 Repository是一个空接口,即标准接口 若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repositoty B ...

  9. robotframe 学习笔记(之一)

    在robot framework中,通过 Set variable关键字来定义变量 连接对象: 通过Catenate关键字可以连接多个信息 加上"SEPARATOR=",可以对多个 ...

  10. centos永久修改主机名

    永久修改主机名 以上的修改只是临时修改,重启后就恢复原样了. 步骤1: 修改/etc/sysconfig/network中的hostname vi /etc/sysconfig/network HOS ...