- #include
- #include
-
- 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
- #include
-
- 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
- #include
-
- 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
- #include
-
- int removexattr(const char* path, const char* key);
- int lremovexattr(const char* path, const char* key);
- int fremovexattr(int fd, const char* key);
- #include
- #include
-
- 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
- #include
- #include
-
-
- int main() {
- char *cwd;
- cwd = get_current_dir_name();
- if(cwd) {
- printf("%s", cwd);
- }
- free(cwd);
- return 0;
- }
- #include
-
- int chdir(const char* path);
- int fchdir(int fd);
chdir()可用于将当前工作目录变更为path所指定的路径名称,可以绝对路径也可以相对路径,fchdir()用于将当前工作目录变更为fd(必须对应到已经打开的目录)所代表的路径名称。
- #define _GNU_SOURCE
- #include
- #include
- #include
-
-
- 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
- #include
-
- int mkdir(const char* path, mode_t mode);
执行成功时,会创建权限为mode(经过umask修改)的目录path。
- #include
-
- int rmdir(const char* path);
path路径必须是空的,只能包含‘.’和'..‘路径,没有实现rm -r 的递归删除功能,须手动深度搜索,从叶节点开始删除。
- #include
- #include
-
- DIR* opendir(const char* name);
执行成功时,会创建一个目录流,表示name所指定的目录。目录流就是一个信息比较多的文件描述符,代表已经打开的目录,因此可以获取特定目录流后面的文件描述符:
- #define _BSD_SOURCE
- #include
- #include
-
- int dirfd(DIR* dir);
执行成功时,返回dir目录流的文件描述符。
- #include
- #include
-
- struct dirent* readdir(DIR* dir);

- #include
- #include
-
- int closedir(DIR* dir);
- #include
- #include
- #include
- #include
- #include
- #include
-
- /**
- * 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
-
- int link(const char* oldpath, const char* newpath);
调用成功之后,oldpath和newpath会指向同一个文件,无法区分谁是最初的链接。
- #include
- int symlink(const char* oldpath, const char* newpath);
- #include
- int unlink(const char* pathname);
-
- #include
- int remove(const char* path);
执行成功时,remove会从文件系统中删除path并且返回0,如果path是一个文件,调用unlink,如果path是一个目录,则调用rmdir()
- #include
- int rename(const char* oldpath, const char* newpath);
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
-
-
- 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;
- }
- #include
- int inotify_init(void);
- #include
- 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。
- 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");
- }
- #include
- int inotify_rm_watch(int fd, uint32_t wd);
- #include
-
- unsigned int queue_len;
- int ret;
- ret = ioctl(fd, FIONREAD, &queue_len);
- if (ret < 0)
- perror("ioctl");
- else
- printf("%u bytes pending in queue\n", queue_len);
- int ret;
- // fd 经 inotify_init() 取得
- ret = close(fd);
- if (fd == -1)