X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Received: by 10.224.185.79 with SMTP id cn15mr2026319qab.4.1364032694846; Sat, 23 Mar 2013 02:58:14 -0700 (PDT) X-Received: by 10.49.84.35 with SMTP id v3mr323767qey.16.1364032694818; Sat, 23 Mar 2013 02:58:14 -0700 (PDT) Newsgroups: comp.os.msdos.djgpp Date: Sat, 23 Mar 2013 02:58:14 -0700 (PDT) Complaints-To: groups-abuse AT google DOT com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=2.173.27.66; posting-account=v5xbdQoAAAAOGc9Ccc-kLZyobvPlN3Qr NNTP-Posting-Host: 2.173.27.66 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <261476b1-c137-495d-95df-a92075cd9960@googlegroups.com> Subject: DJGPP scandir and alphasort example code From: Georg Potthast Injection-Date: Sat, 23 Mar 2013 09:58:14 +0000 Content-Type: text/plain; charset=ISO-8859-1 Bytes: 6238 Lines: 199 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com - DJGPP scandir and alphasort example code - I was converting a program from Linux to DOS and this frequently used the scandir command. AFAIK this is not available with djgpp and so I wrote that function myself with help of examples I found via Google. Since I assume this command may be of interest to other programmers too I post it here. HTH 1. First the libscandir.a library: Compile with: gcc -g -s -c libscandir.c ar rcs libscandir.a libscandir.o #include #include #include #include #include #include #include #include /* Alphabetic order comparison routine */ int alphasort(const void *d1, const void *d2) { return(strcmp((*(struct dirent **)d1)->d_name, (*(struct dirent **)d2)->d_name)); } /* arg1 = directory name arg2 = unallocated array of pointers to dirent(direct) strctures arg3 = pointer to function to specify which files to include arg4 = pointer to sorting function to qsort, e.g. alphasort */ int scandir(char *dirname, struct dirent *(*namelist[]), int (*sd_select)(const struct dirent *), int (*dcomp)(const void *, const void *)) { DIR *dirptr; struct dirent *dir_entry; int tdirsize = sizeof(struct dirent); register int i=0; int si=0; size_t cnt; glob_t glob_results; char *wildcard; char *wildcardpos; wildcard=calloc(_POSIX_PATH_MAX,sizeof(char)); if ((dirptr = opendir(dirname)) == NULL) return -1; //read number of entries in directory strcpy(wildcard,dirname); //remove trailing slash wildcardpos=strrchr(wildcard,'\\'); if (strlen(wildcardpos)==strlen(wildcard)) wildcard[strlen(wildcard)-1]='\0'; //add * for all entries strcat(wildcard,"\\*"); if(glob(wildcard, GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_NOSORT, NULL, &glob_results) == 0) cnt = glob_results.gl_pathc +2; //add two for . and .. globfree(&glob_results); free(wildcard); //dynamic tdir array allocation static struct dirent *tdir; tdir = (struct dirent*) calloc(cnt,sizeof(struct dirent)); if ((*namelist = (struct dirent **) calloc(cnt, sizeof(struct dirent *))) == NULL) return -1; if ((dir_entry = (struct dirent *) malloc(tdirsize + _POSIX_PATH_MAX)) == NULL) return -1; while (dir_entry = readdir(dirptr)) { if (sd_select == NULL){ si=1; //no select routine specified, return all } else { si = sd_select(dir_entry); } if (si) { if (((*namelist)[i] = (struct dirent *) malloc(tdirsize + _POSIX_PATH_MAX)) == NULL) return -1; memcpy((*namelist)[i], dir_entry, sizeof(dir_entry)+_POSIX_PATH_MAX); i++; } } if (dcomp != NULL) qsort((char *) &((*namelist)[0]), i, sizeof(struct dirent *), dcomp); return i; } 2. the header file for this library: #ifndef scandir_h #define scandir_h #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include /* example select routine */ #if 0 int sd_select(struct dirent *entry) //remove . and .. from directory list { if ((strcmp(entry->d_name,".") == 0) || (strcmp(entry->d_name,"..") == 0)) { return (0); } else { return (1); } } #endif /* Alphabetic order comparison routine */ int alphasort(const void *d1, const void *d2); /* * rewrite of BSD scandir. * arg1 = directory name * arg2 = unallocated array of pointers to dirent(direct) strctures * arg3 = specifier for which objects to pick (pointer to function) * arg4 = sorting function pointer to pass to qsort */ int scandir(char *dirname, struct dirent *(*namelist[]), int (*sd_select)(const struct dirent *), int (*dcomp)(const void *, const void *)); #ifdef __cplusplus } #endif #endif //!scandir_h 3. a test program for this libary: if all files are in one directory compile with: gcc -g scandirtest.c -o scandirtest.exe libscandir.a or copy libscandir.a into djgpp\lib and scandir.h into djgpp\include: gcc -g scandirtest.c -o scandirtest.exe -lscandir (you then would use #include below instead) #include #include #include "scandir.h" /* select routine */ int sd_select(const struct dirent *entry) //remove . and .. from directory list { if ((strcmp(entry->d_name,".") == 0) || (strcmp(entry->d_name,"..") == 0)) { return (0); } else { return (1); } } int main(void) { struct dirent **namelist; int n,i; /* all entries in current directory unsorted */ //n = scandir((char*)".", &namelist, 0, 0); /* all entries in current directory sorted */ //n = scandir((char*)".", &namelist, 0, alphasort); /* all entries in root sorted with "." and ".." entries removed*/ n = scandir((char*)"/", &namelist, sd_select, alphasort); if (n < 0) perror("scandir"); else { for(i = 0; i < n; i++) { printf("%02d: %s\n", i+1, namelist[i]->d_name); } //release memory allocated while (n--) { free(namelist[n]); } free(namelist); } }