- 浏览: 140804 次
文章分类
最新评论
根据文件系统基本结构中的介绍,任何一个文件都可以有多个目录项指向其 i 节点。创建一个指向现有文件的链接的方法是使用 link 函数或 linkat 函数(创建新目录项和增加链接计数是一个原子操作)。
两个函数都创建一个新目录项 newpath,它引用现有文件 existingpath。如果 newpath 已经存在,则返回出错。
对于 linkat 函数,现有文件是通过 efd 和 existingpath 参数指定的,新的路径名是通过 nfd 和 newpath 参数指定的。默认情况下,如果两个路径名中的任一个是相对路径,那么它需要通过相对于对应的文件描述符进行计算。如果两个文件描述符中的任一个设置为 AT_FDCWD,那么相应的路径名(如果它是相对路径)就通过相对于当前目录进行计算。如果任一路径名是绝对路径,相应的文件描述符参数就会被忽略。当现有文件是符号链接时,由flag 参数来控制 linkat 函数是创建指向现有符号链接的链接还是指向其所指向的文件的链接。如果 flag 参数中设置了 AT_SYMLINK_FOLLOW 标志,就创建指向符号链接目标的链接。否则就创建一个指向符号链接本身的链接。
注意,很多文件系统实现不允许创建对于目录的硬链接,以免在文件系统中形成循环。
为删除一个现有的目录项,可以调用 unlink 或 unlinkat 函数。
这两个函数删除目录项,并将由 pathname 所引用的文件的链接计数减 1。如果对该文件还有其他链接,则仍可通过其他链接访问该文件。如果出错,则不对该文件做任何更改。
如果 pathname 参数是相对路径名,那么 unlinkat 函数计算相对于由 fd 文件描述符参数代表的路径名。如果 fd 设置为 AT_FDCWD,那么通过相当于调用进程的当前工作目录来计算路径名(除非 pathname 是绝对路径名)。当 flag 参数设置为 AT_REMOVEDIR 标志时,unlinkat 函数可类似于 rmdir 一样删除目录。否则执行与 unlink 同样的操作。
为了解除对文件的链接,必须对包含该目录项的目录具有写和执行权限。如果对该目录设置了粘着位,则对该目录具有写权限,并且还要具备下面三个条件之一:
1、拥有该文件。
2、拥有该目录。
3、具有超级用户权限。
只有当链接计数变为 0 时,该文件的内容才可被删除。此外,当有进程打开了该文件时,其内容也不能删除。关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个计数为 0,内核再去检查其链接计数,如果也是 0,那么就删除该文件的内容。
下面这个程序打开一个文件,之后立刻解除它的链接,然后执行该程序的进程睡眠 15 秒,接着终止。
运行结果:
unlink 的这种特性经常被用来确保即使是在程序崩溃时,它所创建的临时文件也不会遗留下来。进程用 open 或 creat 创建一个文件,然后立即调用 unlink,因为该文件仍旧是打开的,所以不会被立即删除,只有当进程关闭该文件或终止时(此时内核会关闭该进程所打开的全部文件),该文件的内容才被删除。
如果 pathname 是符号链接,那么 unlink 删除该符号链接,而不是所引用的文件。给出符号链接名的情况下,没有一个函数能删除由该链接所引用的文件。
另外,也可用 remove 函数解除对一个文件或目录的链接。对于文件,remove 的功能与 unlink 相同;对于目录,remove 的功能同 rmdir。
#include <unistd.h> int link(const char *existingpath, const char *newpath); int linkat(int efd, const char *existingpath, int nfd, const char *newpath, int flag); /* 返回值:若成功,都返回 0;否则,都返回 -1 */
两个函数都创建一个新目录项 newpath,它引用现有文件 existingpath。如果 newpath 已经存在,则返回出错。
对于 linkat 函数,现有文件是通过 efd 和 existingpath 参数指定的,新的路径名是通过 nfd 和 newpath 参数指定的。默认情况下,如果两个路径名中的任一个是相对路径,那么它需要通过相对于对应的文件描述符进行计算。如果两个文件描述符中的任一个设置为 AT_FDCWD,那么相应的路径名(如果它是相对路径)就通过相对于当前目录进行计算。如果任一路径名是绝对路径,相应的文件描述符参数就会被忽略。当现有文件是符号链接时,由flag 参数来控制 linkat 函数是创建指向现有符号链接的链接还是指向其所指向的文件的链接。如果 flag 参数中设置了 AT_SYMLINK_FOLLOW 标志,就创建指向符号链接目标的链接。否则就创建一个指向符号链接本身的链接。
注意,很多文件系统实现不允许创建对于目录的硬链接,以免在文件系统中形成循环。
为删除一个现有的目录项,可以调用 unlink 或 unlinkat 函数。
#include <unistd.h> int unlink(const char *pathname); int unlinkat(int fd, const char *pathname, int flag); /* 返回值:若成功,都返回 0;否则,都返回 -1 */
这两个函数删除目录项,并将由 pathname 所引用的文件的链接计数减 1。如果对该文件还有其他链接,则仍可通过其他链接访问该文件。如果出错,则不对该文件做任何更改。
如果 pathname 参数是相对路径名,那么 unlinkat 函数计算相对于由 fd 文件描述符参数代表的路径名。如果 fd 设置为 AT_FDCWD,那么通过相当于调用进程的当前工作目录来计算路径名(除非 pathname 是绝对路径名)。当 flag 参数设置为 AT_REMOVEDIR 标志时,unlinkat 函数可类似于 rmdir 一样删除目录。否则执行与 unlink 同样的操作。
为了解除对文件的链接,必须对包含该目录项的目录具有写和执行权限。如果对该目录设置了粘着位,则对该目录具有写权限,并且还要具备下面三个条件之一:
1、拥有该文件。
2、拥有该目录。
3、具有超级用户权限。
只有当链接计数变为 0 时,该文件的内容才可被删除。此外,当有进程打开了该文件时,其内容也不能删除。关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个计数为 0,内核再去检查其链接计数,如果也是 0,那么就删除该文件的内容。
下面这个程序打开一个文件,之后立刻解除它的链接,然后执行该程序的进程睡眠 15 秒,接着终止。
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> int main(void){ if(open("tempfile", O_RDWR) < 0){ printf("open error\n"); exit(1); } if(unlink("tempfile") < 0){ printf("unlink error\n"); exit(1); } printf("*** file unlinked\n"); sleep(15); printf("done\n"); exit(0); }
运行结果:
$ ls -l tempfile -rw-r----- 1 sar 413265408 Jan 21 07:14 tempfile $ df /home # 检查可用磁盘空间 Filesystem 1K-blocks Used Available Used Mounted on /dev/hda4 11021440 1956332 9065108 18% /home $ ./unlinkDemo.out & # 在后台运行程序 1364 # 进程 ID *** file unlinked # 解除了文件链接 $ ls -l tempfile ls:tempfile: No such file or directory # 目录项已被删除 $ df /home # 检查可用磁盘空间的变化 Filesystem 1K-blocks Used Available Used Mounted on /dev/hda4 11021440 1956332 9065108 18% /home $ done # 程序执行结束,关闭所有打开文件 $ df /home # 现在应当有更多可用的磁盘空间 Filesystem 1K-blocks Used Available Used Mounted on /dev/hda4 11021440 1552352 9469088 15% /home
unlink 的这种特性经常被用来确保即使是在程序崩溃时,它所创建的临时文件也不会遗留下来。进程用 open 或 creat 创建一个文件,然后立即调用 unlink,因为该文件仍旧是打开的,所以不会被立即删除,只有当进程关闭该文件或终止时(此时内核会关闭该进程所打开的全部文件),该文件的内容才被删除。
如果 pathname 是符号链接,那么 unlink 删除该符号链接,而不是所引用的文件。给出符号链接名的情况下,没有一个函数能删除由该链接所引用的文件。
另外,也可用 remove 函数解除对一个文件或目录的链接。对于文件,remove 的功能与 unlink 相同;对于目录,remove 的功能同 rmdir。
#include <stdio.h> int remove(const char *pathname); /* 返回值:若成功,返回 0;否则,返回 -1 */
发表评论
-
打开伪终端设备
2018-07-09 20:50 1248在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1533伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 791多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 937终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 566尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 933虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 706tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 807终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 432终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 575在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 943在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 612在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 490消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 479有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 412FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 383管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 878readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 449POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 584记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 432UNIX 系统中,守护进程遵循下列通用惯例。 ...
相关推荐
5. **隐式链接与显式链接**:DEF文件主要用于隐式链接,即通过`GetProcAddress`函数在运行时查找和加载导出函数。对于显式链接,函数的导出通常由编译器自动处理。 6. **多线程支持**:如果DLL需要支持多线程,需要...
在Windows操作系统中,动态链接库(Dynamic Link Library,简称DLL)是一种可执行文件格式,它包含了一组可供其他程序使用的函数和资源。DLL文件允许多个程序共享同一块内存空间,从而节省系统资源,提高执行效率。...
对于标签"www.pudn.com.txt",这可能是指一个包含更多资源链接或示例代码的文本文件,通常在编程学习中,这些链接会提供额外的信息或者示例来帮助理解相关主题。 总的来说,理解Linux下的文件拷贝函数涉及对文件I/O...
然而,直接调用`.obj`(目标文件)中的函数并不常见,因为`.obj`文件通常用于编译链接过程,而不是作为直接调用的接口。本文将深入探讨如何在C语言中实现这一非典型操作,并提供相关资源和示例。 首先,理解`.obj`...
PE文件结构包含了程序的代码、数据以及元数据,其中导出函数(Exported Functions)是PE文件的重要组成部分,特别是对于动态链接库(DLL)而言,导出函数使得其他程序能够调用其功能。"PE文件导出函数查看器"是一款...
在IT领域,特别是软件开发...通过解析PE文件的导出函数表,我们可以了解DLL的接口,这对于动态链接、逆向工程或调试工作都具有实际价值。同时,掌握虚拟地址的计算方法,有助于我们更好地理解程序在内存中的运行机制。
这些函数可能是开发者显式声明为导出的,也可以是通过链接器隐式导出的。通过这个工具,你可以: 1. **识别导出函数**:查看器会列出所有的导出函数名,这对于理解和使用DLL的功能非常有用。你可以看到函数名称、...
3. **链接CUDA函数**: 在`.cpp`文件中,你需要包含`cuAdd.cu`,这可以通过使用NVCC编译器的“自定义命令”完成。在`.cpp`文件中声明`cuAdd`函数的extern "C"版本,因为CUDA是C++兼容的,但需要处理名称修饰问题: ...
在编程领域,函数指针和动态链接库是两个非常关键且实用的概念,它们在软件开发中扮演着重要的角色。下面将详细阐述这两个知识点及其在实际工程中的应用。 首先,我们来了解一下函数指针。函数指针是C/C++语言中的...
在Windows操作系统中,PE(Portable Executable)文件格式是用于存放可执行程序、动态链接库(DLL)等的二进制文件。查看PE文件中导入的函数是一项重要的逆向工程任务,这对于理解程序的行为、调试和安全分析至关...
当开发者编写代码时,使用到CyUSB.dll提供的API函数,编译器实际上链接的是CyAPI.lib文件,而运行时通过该库找到实际的dll文件中的函数地址。 3. **CyUSB.dll接口函数的使用**: CyUSB.dll提供的接口函数涵盖了...
Windows API主要由动态链接库(DLL)组成,如kernel32.dll、user32.dll和advapi32.dll等,这些库包含了丰富的功能函数。了解和熟练使用API函数对于Windows平台的软件开发至关重要。 在描述中提到,这个中文帮助文件...
"DLL函数查看器V2.0"是一个专门用于查看和探索DLL文件中所包含的函数的工具,对于开发者和系统管理员来说,它是一个非常实用的辅助工具。 DLL函数查看器的主要功能在于帮助用户识别和理解DLL文件内部的函数定义。当...
在实际应用中,使用这些API函数通常需要包含`Windows.h`头文件,并且需要链接`kernel32.lib`库。下面是一个简单的示例代码,展示如何使用这些函数: ```cpp #include #include int main() { // 拷贝文件 if (!...
- **优化调用**:分析函数的偏移地址有助于优化程序的动态链接过程,尤其是在进行性能敏感的编程时。 - **逆向工程**:在进行逆向工程或安全分析时,查看DLL导出函数可以帮助理解程序的工作原理。 DLLEXP文件可能是...
为了使用这个DLL,客户端首先需要链接到相应的库文件(.lib),然后通过`LoadLibrary`加载DLL,并使用`GetProcAddress`获取接口函数的地址。这样,就可以在运行时调用DLL提供的纯虚函数接口,使用自定义的实现。 ...
查看动态链接库DLL文件接口函数信息.DLL函数查看器V3.5不仅支持查看DLL文件的导出函数和引用函数信息及引用函数来源,也支持所有符合PE文件格式的文件,包括EXE文件、OCX文件等的导出函数和引用函数信息。 注:在我的...
DLL项目通常包含一个头文件(.h),定义对外公开的函数原型,以及一个实现这些函数的实现文件(.cpp)。 接着,我们创建一个C++的主程序,该程序负责动态加载DLL并调用其输出函数。在C++中,我们使用`LoadLibrary()...