🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.unix.programmer
1 messages
1 total messages Started by frank Wed, 27 Jan 2010 07:21
readir() II
#3428
Author: 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
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads