LInux系统编程(3)
最佳答案 问答题库448位专家为你答疑解惑
取得拓展属性
#include <sys/types.h>
#include <attr/xattr.h>ssize_t getxattr(const char* path, const char* key, void* value, size_t size);
ssize_t lgetxattr(const char* path, const char* key, void* value, size_t size);
ssize_t fgetxattr(int fd, const char* key, void* value, size_t size);
执行成功时,getxattr()会从文件path将拓展属性key的值存入value缓冲区,缓冲区的长度为size个字节,并且返回此值的真实大小。
如果size为0,则不会存入value中,只返回值的大小,让应用程序决定缓冲区的大小,方便进行存储。
lgetxattr()的行为如同getxattr(),但是当path是一个符合链接时,返回链接本身的(而非连接的目标文件)的拓展属性。
设定一个拓展属性
#include <sys/types.h>
#include <attr/xattr.h>int setxattr(const char* path, const char* key, const void* value, size_t size, int flags);
int lsetxattr(const char* path, cosnt char* key, const void* value, size_t size, int flags);
int fsetxattr(int fd, const char* key, const void* value, size_t size, int flags);
列出文件上的拓展属性
#include <sys/types.h>
#include <attr/xattr.h>ssize_t listxattr(const char* path, char* list, size_t size);
ssize_t llistxattr(const char* path, char* list, size_t size);
ssize_t flistxattr(int fd, char*list, size_t size);
执行成功时,listxattr()返回path文件的拓展属性列表,存入list中,函数返回列表的实际大小,以字节为单位。
每个拓展属性被传入到list并且以NULL字符结尾,如下所示:
“user.md5_sum\0user.mime_type\0system.posix_acl_default\0”
如果调用时size设置为0,函数返回列表的实际长度。
llistxattr()的行为如同listxattr(),当path是一个符号连接时,返回的是链接本身(而不是链接的目标文件)有关的拓展属性。
移除一个拓展属性
#include <sys/types.h>
#include <attr/xattr.h>int removexattr(const char* path, const char* key);
int lremovexattr(const char* path, const char* key);
int fremovexattr(int fd, const char* key);
获取当前目录
#include <unistd.h>
#include <stdio.h>int main() {char *cwd;cwd = getcwd(NULL, 0);if(cwd) {printf("%s", cwd);}return 0;
}
LInux的C链接库还提供了一个get_current_dir_name()函数,当buf为NULL而且size=0时,函数如同getcwd()函数
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {char *cwd;cwd = get_current_dir_name();if(cwd) {printf("%s", cwd);}free(cwd);return 0;
}
变更当前工作目录
#include <unistd.h>int chdir(const char* path);
int fchdir(int fd);
chdir()可用于将当前工作目录变更为path所指定的路径名称,可以绝对路径也可以相对路径,fchdir()用于将当前工作目录变更为fd(必须对应到已经打开的目录)所代表的路径名称。
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main() {int swd_fd;swd_fd = open(".", O_RDONLY);if (swd_fd == -1) {perror("open");exit(EXIT_FAILURE);}// 变更为不同的目录ret = chdir(some_other_dir);if (ret) {perror("chdir");exit(EXIT_FAILURE);}// 在新目录中进行其他操作// 返回所保存的目录中ret = fchdir(swd_fd);if (ret) {perror("fchdir");exit(EXIT_FAILURE);}// 关闭所在目录ret = close(swd_fd);if (ret) {perror("close");exit(EXIT_FAILURE);}return 0;
}
创建目录
#include <sys/types.h>
#include <sys/stat.h>int mkdir(const char* path, mode_t mode);
执行成功时,会创建权限为mode(经过umask修改)的目录path。
移除目录
#include <unistd.h>int rmdir(const char* path);
path路径必须是空的,只能包含‘.’和'..‘路径,没有实现rm -r 的递归删除功能,须手动深度搜索,从叶节点开始删除。
读取一个目录内容
#include <sys/types.h>
#include <dirent.h>DIR* opendir(const char* name);
执行成功时,会创建一个目录流,表示name所指定的目录。目录流就是一个信息比较多的文件描述符,代表已经打开的目录,因此可以获取特定目录流后面的文件描述符:
#define _BSD_SOURCE
#include <sys/types.h>
#include <dirent.h>int dirfd(DIR* dir);
执行成功时,返回dir目录流的文件描述符。
从目录流中读取数据
#include <sys/types.h>
#include <dirent.h>struct dirent* readdir(DIR* dir);
关闭目录流
#include <sys/types.h>
#include <dirent.h>int closedir(DIR* dir);
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>/*** find_file_int_dir 从目录path中搜索file的文件* 存在返回0,否则返回非0
*/
int find_file_in_dir(const char* path, const char* file) {struct dirent* entry;int ret = 1;DIR* dir;dir = opendir(path);errno = 0; //这句很重要while((entry = readdir(dir)) != NULL) {if (!strcmp(entry->d_name, file)) {ret = 0;break;}}if (errno && !entry) {perror("readdir");}closedir(dir);return ret;
}int main() {printf("%d\n", find_file_in_dir(".", "test.c"));printf("%d\n", find_file_in_dir(".", "aaaa"));return 0;
}
硬链接
#include <unistd.h>int link(const char* oldpath, const char* newpath);
调用成功之后,oldpath和newpath会指向同一个文件,无法区分谁是最初的链接。
符号链接
#include <unistd.h>
int symlink(const char* oldpath, const char* newpath);
解除链接
#include <unistd.h>
int unlink(const char* pathname);#include <stdio.h>
int remove(const char* path);
执行成功时,remove会从文件系统中删除path并且返回0,如果path是一个文件,调用unlink,如果path是一个目录,则调用rmdir()
移动
#include <stdio.h>
int rename(const char* oldpath, const char* newpath);
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <sys/stat.h>int main(int argc, char** argv) {int fd, ret;if (argc < 2) {fprintf(stderr, "usage: %s < device to eject>\n", argv[0]);return 1;}/*** 以只读方式打开CD-ROM设备,O_NONBLOCK用于通知内核,即使* 设备中没有媒体,也要打开设备*/fd = open(argv[1], O_RDONLY | O_NONBLOCK);if (fd < 0) {perror("open");return 1;}/*** 给CD-ROM设备送出弹出命令*/ret = ioctl(fd, CDROMEJECT, 0);if (ret) {perror("ioctl");return 1;}ret = close(fd);if (ret) {perror("close");return 1;}return 0;
}
初始化inotify
#include <inotify.h>
int inotify_init(void);
加入一个新的监视项目
#include <inotify.h>
int inotify_add_watch(int fd, const char* path, uint32_t mask);
为path文件或者目录添加一个mask所描述的监听项目至fd所表示的inotify实例。
int wd;
wd = inotify_add_watch(fd, "/etc", IN_ACCESS | IN_MODIFY);
if (wd == -1) {perror("inotify_add_watch");exit(EXIT_FAILLURE);
}
此范例会在/etc所在目录上的所有读取和写入加上一个监视项目,如果/etc中任何文件被读取或者写入,inotify会传送一个事件给inotify文件描述符fd,提供给监视描述符wd。
inotify事件
读取inotify事件
char buf[BUF_LEN]__attribute__((aligned(4)));
ssize_t len, i = 0;// 读取BUF_LEN个字节的事件
len = read(fd, buf, BUF_LEN);// 读取每个事件直到读完为止
while(i < len) {struct inotify_event * event = (struct inotify_event*) &buf[i];printf("wd=%d mask=%d cookie=%d len=%d dir=%s\n", event->wd,event->mask, event->cookie,event->len, (event->mask & IN_ISDIR)?"yes":"no");//如果有一个名称,则输出它if(event->len)printf("name=%d\n", event->name);//将索引更新为下一个事件的开头i += sizeof(struct inotify_event) + event->len;
}
因为inotify文件描述符的行为如同一个常规文件,可以使用select,poll,epoll监听。
int wd;/*** 只有在/etc/init.d 是一个目录,且他的路径中没有一个部分是符号链接时,* 才会监视/etc/init.d是否被移动过*/wd = inotify_add_watch(fd, "/etc/init.d", IN_MOVE_SELF | IN_ONLYDIR | IN_DONT_FOLLOW);if (wd == -1) {perror("inotify_add_watch");}
移除一个inotify监视项目
#include <inotify.h>
int inotify_rm_watch(int fd, uint32_t wd);
取得事件队列的大小
#include <sys/ioctl.h>unsigned int queue_len;
int ret;
ret = ioctl(fd, FIONREAD, &queue_len);
if (ret < 0)perror("ioctl");
elseprintf("%u bytes pending in queue\n", queue_len);
销毁一个inotify实例
int ret;
// fd 经 inotify_init() 取得
ret = close(fd);
if (fd == -1)
99%的人还看了
相似问题
- 重磅!1区、60年老牌期刊被踢?共5本被剔除!11月SCIE/SSCI期刊目录更新!
- vsto word 获取目录起始页和结束页,如目录起始位置为2、结束位置为3,返回2和3
- Linux文件目录以及文件类型
- 基于pytest-bdd的项目目录结构和命名规范
- 事关Django的静态资源目录设置(Django的setting.py中的三句静态资源(static)目录设置语句分别是什么作用?)
- iOS源码-工程目录讲解
- 报错资源不足,k8s使用containerd运行容器修改挂载点根目录换成/home
- 十三、Linux文件目录指令
- Linux(4):Linux文件与目录管理
- Linux(3):Linux 的文件权限与目录配置
猜你感兴趣
版权申明
本文"LInux系统编程(3)":http://eshow365.cn/6-22445-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: 1 如何入门TensorFlow
- 下一篇: pnpm ERR_PNPM_ADDING_TO_ROOT