🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.programmer
Article #3428

readir() II

#3428
From: frank
Date: Wed, 27 Jan 2010 07:21
333 lines
8092 bytes
Hello again comp.unix.programer,gnu.gcc.help

I would like to develop a small C utility that does something that a 
mortensen child can use.  If I don't get it done before the end of 
january, then it's not a x-mas gift.  I bought _Crossing the Threshold 
of Hope_ for Alan and have a thumbdrive of music for Robyn.

So this is to make a source listing and not much else.  I'll do that 
after the sig so you won't have to read it unless you want to.

What follows is the readdir() I understand best and then working code 
from unleashed that has a 2-d resizable array.

Jens Thoerring has given me the best design idea that I have right now, 
but if you think you have a better one given the source below, then I'm 
all ears.

Thanks for your constructive comment and cheers,


-- 
frank





#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

#define PATH_SIZE 300

unsigned
process_directory (char *theDir)
{
   DIR *dir = NULL;
   struct dirent entry;
   struct dirent *entryPtr = NULL;
   int retval = 0;
   unsigned count = 0;
   char pathName[PATH_SIZE + 1];

   /* Open the given directory, if we can. */
   dir = opendir (theDir);
   if (dir == NULL)
     {
       printf ("Error opening %s: %s", theDir, strerror (errno));
       return 0;
     }


   retval = readdir_r (dir, &entry, &entryPtr);
   while (entryPtr != NULL)
     {
       struct stat entryInfo;

       if ((strncmp (entry.d_name, ".", PATH_SIZE) == 0) ||
	  (strncmp (entry.d_name, "..", PATH_SIZE) == 0))
	{
	  /* Short-circuit the . and .. entries. */
	  retval = readdir_r (dir, &entry, &entryPtr);
	  continue;
	}

       (void) strncpy (pathName, theDir, PATH_SIZE);
       (void) strncat (pathName, "/", PATH_SIZE);
       (void) strncat (pathName, entry.d_name, PATH_SIZE);

       if (lstat (pathName, &entryInfo) == 0)
	{
	  /* stat() succeeded, let's party */
	  count++;

	  if (S_ISDIR (entryInfo.st_mode))
	    {			/* directory */
	      printf ("processing %s/\n", pathName);
	      count += process_directory (pathName);
	    }
	  else if (S_ISREG (entryInfo.st_mode))
	    {			/* regular file */
	      printf ("\t%s has %lld bytes\n",
		      pathName, (long long) entryInfo.st_size);
	    }
	  else if (S_ISLNK (entryInfo.st_mode))
	    {			/* symbolic link */
	      char targetName[PATH_SIZE + 1];
	      if (readlink (pathName, targetName, PATH_SIZE) != -1)
		{
		  printf ("\t%s -> %s\n", pathName, targetName);
		}
	      else
		{
		  printf ("\t%s -> (invalid symbolic link!)\n", pathName);
		}
	    }
	}
       else
	{
	  printf ("Error statting %s: %s\n", pathName, strerror (errno));
	}

       retval = readdir_r (dir, &entry, &entryPtr);
     }

   /* Close the directory and return the number of entries. */
   (void) closedir (dir);
   return count;
}

int
main (void)
{
   process_directory ("/etc/");
   return EXIT_SUCCESS;
}

// gcc -D_GNU_SOURCE -Wall -Wextra rd3.c -o out


end rd3.c.  strarr2.h:

//  strarr2.h - header for string array demo


#ifndef STRARR_H__
#define STRARR_H__

void FreeStrArray(char **, size_t );
char **AllocStrArray(size_t , size_t);
int ResizeOneString(char **,
                     size_t ,
                     size_t );
int AddFilesToStrArray(char ***,
                       size_t ,
                       int ,
                       size_t );
int ConsolidateStrArray(char **,
                         size_t );

#endif





end strarr2.h begin strarr2.c:




#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "strarr2.h"

void FreeStrArray(char **Array, size_t NumFiles)
{
   size_t index;

   if(Array != NULL)
   {
     for(index = 0; index < NumFiles; index++)
     {
       if(Array[index] != NULL)
       {
         free(Array[index]);
       }
     }
     free(Array);
   }
}

char **AllocStrArray(size_t NumFiles, size_t Width)
{
   char **Array = NULL;
   size_t index;
   int Success = 1;

   /* allocating 0 bytes is not a great idea, and
    * represents a logic error.
    */
   assert(NumFiles > 0);
   assert(Width > 0);

   /* Just in case the zero allocation is NOT caught
    * in testing, we'll check for it here.
    */
   if(NumFiles > 0 && Width > 0)
   {
     Array = malloc(NumFiles * sizeof *Array);
     if(Array != NULL)
     {
       for(index = 0; index < NumFiles; index++)
       {
         Array[index] = malloc(Width * sizeof *Array[index]);
         if(NULL == Array[index])
         {
           Success = 0;
         }
         else
         {
           /* Making this into an empty string is a quick
            * op which will almost invariably be The Right
            * Thing and can never be The Wrong Thing, so
            * we might as well do it.
            */
           Array[index][0] = '\0';
         }
       }
       /* If any inner allocation failed,
        * we should clean up.
        */
       if(1 != Success)
       {
         FreeStrArray(Array, NumFiles);
         Array = NULL;
       }
     }
   }

   return Array;
}

int ResizeOneString(char **Array,
                     size_t index,
                     size_t NewSize)
{
   char *p;
   int Success = 1;

   assert(Array != NULL);

   p = realloc(Array[index], NewSize);
   if(p != NULL)
   {
     Array[index] = p;
   }
   else
   {
     Success = 0;
   }

   return Success;
}

int AddFilesToStrArray(char ***ArrayPtr,
                       size_t OldNumFiles,
                       int NumFilesToAdd,
                       size_t InitWidth)
{
   char **p;
   int Success = 1;
   int index;
   int OldFiles;

   OldFiles = (int)OldNumFiles;
   if(NumFilesToAdd < 0)
   {
     for(index = OldFiles - 1;
         index >= OldFiles + NumFilesToAdd;
         index--)
     {
       free((*ArrayPtr)[index]);
     }
   }

   p = realloc(*ArrayPtr,
               (OldFiles + NumFilesToAdd) *
                sizeof(**ArrayPtr));

   if(p != NULL)
   {
     *ArrayPtr = p;

     for(index = OldFiles;
         Success && index < OldFiles + NumFilesToAdd;
         index++)
     {
       (*ArrayPtr)[index] = malloc(InitWidth);
       if((*ArrayPtr)[index] != NULL)
       {
         (*ArrayPtr)[index][0] = '\0';
       }
       else
       {
         Success = 0;
       }
     }
   }
   else
   {
     Success = 0;
   }
   return Success;
}

int ConsolidateStrArray(char **ArrayPtr,
                         size_t NumFiles)
{
   size_t index;
   size_t Len;
   int NumFailures = 0;

   for(index = 0; index < NumFiles; index++)
   {
     /* If the library has been correctly used, no
      * index pointer will ever be NULL, so we should
      * assert that this is the case.
      */
     assert(ArrayPtr[index] != NULL);
     Len = 1 + strlen(ArrayPtr[index]);
     if(0 == ResizeOneString(ArrayPtr, index, Len))
     {
       ++NumFailures;
     }
   }
   return NumFailures;
}

/* end of strarr.c */
/*
    gcc -Wall -Wextra -c -o string2.o strarr2.c */

end source listings
Technical Details
Message-ID: <7sa7rrFg81U1@mid.individual.net>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: 1200bcf240,1d887f475f1c894c,start
X-Google-Attributes: gid1200bcf240,public,usenet
X-Google-NewGroupId: yes
X-Google-Language: ENGLISH,ASCII-7-bit
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail
From: frank <frank@example.invalid>
Newsgroups: comp.unix.programmer,gnu.gcc.help
Subject: readir() II
Date: Wed, 27 Jan 2010 00:21:30 -0700
Lines: 334
Message-ID: <7sa7rrFg81U1@mid.individual.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Trace: individual.net Q6R9irMhSvlHpeB++kxH4wIycSWNJMDwtAHdHgqH8cX0Lhej2o
Cancel-Lock: sha1:teJ4YR0sdwbn8+BBekYM1qngzdE=
User-Agent: Thunderbird 2.0.0.23 (X11/20090817)