iod.c revision 50e1e10fa0ac12a3e2a9d20a75ee9041873cda96
1/*
2 * iod.c		- Iterate a function on each entry of a directory
3 *
4 * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
5 *                           Laboratoire MASI, Institut Blaise Pascal
6 *                           Universite Pierre et Marie Curie (Paris VI)
7 *
8 * This file can be redistributed under the terms of the GNU Library General
9 * Public License
10 */
11
12/*
13 * History:
14 * 93/10/30	- Creation
15 */
16
17#include "e2p.h"
18
19int iterate_on_dir (const char * dir_name,
20		    int (*func) (const char *, struct dirent *, void *),
21		    void * private)
22{
23	DIR * dir;
24#if HAVE_DIRENT_NAMELEN
25	/* Declare DE_BUF with some extra room for the name.  */
26	char de_buf[sizeof (struct dirent) + 32];
27	struct dirent *de = (struct dirent *)&de_buf;
28#else
29	struct dirent de_buf, *de = &de_buf;
30#endif
31	struct dirent *dep;
32
33	dir = opendir (dir_name);
34	if (dir == NULL)
35		return -1;
36	while ((dep = readdir (dir)))
37	{
38#if HAVE_DIRENT_NAMELEN
39	  /* See if there's enough room for this entry in DE, and grow if
40	     not.  */
41	  if (de_len < dep->d_reclen)
42	    {
43	      de_len = dep->d_reclen + 32;
44	      de =
45		(de == (struct dirent *)&de_buf
46		 ? malloc (de_len)
47		 : realloc (de, de_len));
48	      if (de == NULL)
49		{
50		  errno = ENOMEM;
51		  return -1;
52		}
53	    }
54	  memcpy (de, dep, dep->d_reclen);
55#else
56	  *de = *dep;
57#endif
58	  (*func) (dir_name, de, private);
59	}
60#if HAVE_DIRENT_NAMELEN
61	if (de != (struct dirent *)&de_buf)
62	  free (de);
63#endif
64	closedir (dir);
65	return 0;
66}
67