scandir函数的研究【笔记】
以下是本人的学习笔记,代码并非原创,均摘自官方源码,贴出来仅供学习记录用
scandir 的使用要注意内存泄漏的问题
scandir函数实现:
vi ./uClibc-0.9.33.2/libc/misc/dirent/scandir.c
/*
* Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/ #include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include "dirstream.h" int scandir(const char *dir, struct dirent ***namelist,
int (*selector) (const struct dirent *),
int (*compar) (const struct dirent **, const struct dirent **))
{
DIR *dp = opendir (dir);
struct dirent *current;
struct dirent **names = NULL;
size_t names_size = , pos;
int save; if (dp == NULL)
return -; save = errno;
__set_errno (); pos = ;
while ((current = readdir (dp)) != NULL) {
int use_it = selector == NULL; if (! use_it)
{
use_it = (*selector) (current);
/* The selector function might have changed errno.
* It was zero before and it need to be again to make
* the latter tests work. */
if (! use_it)
__set_errno ();
}
if (use_it)
{
struct dirent *vnew;
size_t dsize; /* Ignore errors from selector or readdir */
__set_errno (); if (unlikely(pos == names_size))
{
struct dirent **new;
if (names_size == )
names_size = ;
else
names_size *= ;
new = (struct dirent **) realloc (names,
names_size * sizeof (struct dirent *));
if (new == NULL)
break;
names = new;
} dsize = ¤t->d_name[_D_ALLOC_NAMLEN(current)] - (char*)current;
vnew = (struct dirent *) malloc (dsize);
if (vnew == NULL)
break; names[pos++] = (struct dirent *) memcpy (vnew, current, dsize);
}
} if (unlikely(errno != ))
{
save = errno;
closedir (dp);
while (pos > )
free (names[--pos]);
free (names);
__set_errno (save);
return -;
} closedir (dp);
__set_errno (save); /* Sort the list if we have a comparison function to sort with. */
if (compar != NULL)
qsort (names, pos, sizeof (struct dirent *), (comparison_fn_t) compar);
*namelist = names;
return pos;
}
例子参考1:
vi ./uClibc-0.9.33.2/test/stdlib/qsort.c
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h> static int select_files(const struct dirent *dirbuf)
{
if (dirbuf->d_name[] == '.')
return ;
else
return ;
} int main(void)
{
struct dirent **array;
struct dirent *dirbuf; int i, numdir; chdir("/");
numdir = scandir(".", &array, select_files, NULL);
printf("\nGot %d entries from scandir().\n", numdir);
for (i = ; i < numdir; ++i) {
dirbuf = array[i];
printf("[%d] %s\n", i, dirbuf->d_name);
free(array[i]);
}
free(array);
numdir = scandir(".", &array, select_files, alphasort);
printf("\nGot %d entries from scandir() using alphasort().\n", numdir);
for (i = ; i < numdir; ++i) {
dirbuf = array[i];
printf("[%d] %s\n", i, dirbuf->d_name);
}
printf("\nCalling qsort()\n");
/* Even though some manpages say that alphasort should be
* int alphasort(const void *a, const void *b),
* in reality glibc and uclibc have const struct dirent**
* instead of const void*.
* Therefore we get a warning here unless we use a cast,
* which makes people think that alphasort prototype
* needs to be fixed in uclibc headers.
*/
qsort(array, numdir, sizeof(struct dirent *), (void*) alphasort);
for (i = ; i < numdir; ++i) {
dirbuf = array[i];
printf("[%d] %s\n", i, dirbuf->d_name);
free(array[i]);
}
free(array);
return ();
}
例子参考2:
man scandir
EXAMPLE
#define _SVID_SOURCE
/* print files in current directory in reverse order */
#include <dirent.h> int
main(void)
{
struct dirent **namelist;
int n; n = scandir(".", &namelist, NULL, alphasort);
if (n < )
perror("scandir");
else {
while (n--) {
printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
}
}
scandir函数的研究【笔记】的更多相关文章
- Hive自定义函数的学习笔记(1)
前言: hive本身提供了丰富的函数集, 有普通函数(求平方sqrt), 聚合函数(求和sum), 以及表生成函数(explode, json_tuple)等等. 但不是所有的业务需求都能涉及和覆盖到 ...
- linux 系统获得当前文件夹下存在的所有文件 scandir函数和struct dirent **namelist结构体[转]
linux 系统获得当前文件夹下存在的所有文件 scandir函数和struct dirent **namelist结构体 1.引用头文件#include<dirent.h> struct ...
- scandir函数详解
scandir函数详解2009-10-30 10:51scandir函数:读取特定的目录数据表头文件:#include <dirent.h>定义函数:int scandir(const c ...
- R语言函数化学习笔记6
R语言函数化学习笔记 1.apply函数 可以让list或者vector的元素依次执行一遍调用的函数,输出的结果是list格式 2.sapply函数 原理和list一样,但是输出的结果是一个向量的形式 ...
- R语言函数化学习笔记3
R语言函数化学习笔记3 R语言常用的一些命令函数 1.getwd()查看当前R的工作目录 2.setwd()修改当前工作目录 3.str()可以输出指定对象的结构(类型,位置等),同理还有class( ...
- R语言函数化编程笔记2
R语言函数化编程笔记2 我学过很多的编程语言,可以我写的代码很啰嗦,一定是我太懒了.或许是基础不牢地动山摇 1.为什么要学函数 函数可以简化编程语言,减少重复代码或者说面向对象的作用 2.函数 2.1 ...
- R语言函数化编程笔记1
R语言函数化编程笔记1 notes:有一个不错的网站叫做stack overflow,有问题可以从上面找或者搜索答案,会有大佬相助. 在github上面可以找到很多R的扩展包,如果自己额修改被接受,那 ...
- PHP scandir() 函数
------------恢复内容开始------------ 实例 列出 images 目录中的文件和目录: <?php$dir = "/images/"; // Sort ...
- JavaScript权威设计--JavaScript函数(简要学习笔记十一)
1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...
随机推荐
- python的N个小功能(更新文件)
########################################################################## #对于第二份文件:第一份与第二份不相同,以第二份为 ...
- BZOJ 1444 有趣的游戏(AC自动机+矩阵快速幂)
真的是很有趣的游戏... 对每个单词构建好AC自动机后,由于单词都是相同长度的且不同,所以不会出现互相为子串的形式. 那么我们对AC自动机上的节点构建转移矩阵.对于每个单词末尾的节点.该节点的出边仅仅 ...
- sql语句查询各门课程平均分的最大值
解法一: select courseno,stuno,avg(score) '平均分最高值'--这里是求平均,后面的条件是过滤最大值的 from tablename group by courseno ...
- Windows用户相关操作
获取所有用户 NET_API_STATUS NetUserEnum( LPCWSTR servername, DWORD level, DWORD filter, LPBYTE* bufptr, DW ...
- Mysql外键设置中的CASCADE、NO ACTION、RESTRICT、SET NULL
转: Mysql外键设置中的CASCADE.NO ACTION.RESTRICT.SET NULL 2017年06月11日 10:03:13 雅静8 阅读数:5491 版权声明:本文为博主原创文章 ...
- git使用笔记(十四)cat-file
By francis_hao Mar 18,2018 git cat-file :提供仓库中对象实体的类型.大小和内容的信息 概要 git cat-file (-t | -s | -e | ...
- 在 Ubuntu16.04上安装anaconda+Spyder+TensorFlow(支持GPU)
TensorFlow 官方文档中文版 http://www.tensorfly.cn/tfdoc/get_started/introduction.html https://zhyack.github ...
- Linux中怎么终止正在运行的后台程序
linux 任务管理-后台运行与终止fg.bg.jobs.&.ctrl + z命令一. &加在一个命令的最后,可以把这个命令放到后台执行 ,如gftp &,二.ctrl + z ...
- ECONNRESET和WSAECONNRESET怎么产生的以及如何避免
ECONNRESET是linux环境网络编程产生的错误,错误码为104, WSAECONNRESET是windows环境网络编程产生的错误,错误码为10054 两者产生的原因都一样,分以下几种情况: ...
- STL源码分析-vector
http://note.youdao.com/noteshare?id=55dc651a7489f1413b3a3169401dcf94