From: Andrew Poelstra on
On 2010-01-27, frank <frank(a)example.invalid> wrote:
> 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,
>

Unfortunately because you put the code in your signature, my
newsreader does not include it in my reply! But I only have
a couple of things to say:

1. As has been said, using readdir() instead of readdir_r() would
have been fine, since you don't need thread-safety for this.

2. Instead of checking for . and .., you could have checked for
entry.d_name[0] == '.', and that would have ignored all hidden
directories.

3. What are strarr.c and strarr.h for? At a quick glace, you
probably should have used an opaque struct that kept track
of its own length. That way you could remove length management
from the calling code, and probably save on some realloc()s.


From: Moi on
On Thu, 28 Jan 2010 00:06:21 +0000, Andrew Poelstra wrote:

> On 2010-01-27, Moi <root(a)invalid.address.org> wrote:
>
>> A few points:
>> 0) you need to include a few headers. The code as you posted it did not
>> even compile.
>
> I changed
> #include "strarr2.h"
> to
> #include "strarr.h"

Sorry, I missed the first block of includes while copy/pasting. My bad.
The array stuff (which was commented out) is not even used.

AvK
From: Casper H.S. Dik on
Andrew Poelstra <apoelstra(a)localhost.localdomain> writes:

>Unfortunately because you put the code in your signature, my
>newsreader does not include it in my reply! But I only have
>a couple of things to say:

>1. As has been said, using readdir() instead of readdir_r() would
> have been fine, since you don't need thread-safety for this.

That's not actually true: readdir() is perfectly fine in a threaded
applications as long as you use the directory stream in only one
thread. A particular idiom:

dirp = opendir(..);

while ((dp = readdir(dirp)) != NULL) {
}
closedir(dirp);

works in single and multi-threaded applications EVEN if the routine
is called from multiple threads.

Specially this particular text in the standard is important here:

The pointer returned by readdir() points to data which may be
overwritten by another call to readdir() on the same directory stream.
This data is not overwritten by another call to readdir() on a
different directory stream.

I'd avoid readdir_r() except for the very few cases where it is needed.
(I don't remember finding even one valid use of readdir_r() in, e.g.,
Solaris)

>2. Instead of checking for . and .., you could have checked for
> entry.d_name[0] == '.', and that would have ignored all hidden
> directories.

But often you really want to hide "." and ".." but not te rest.

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
From: frank on
Ben Bacarisse wrote:
> frank <frank(a)example.invalid> writes:
>> Hello again comp.unix.programer,gnu.gcc.help
>
> I can't see the relevance to gnu.gcc.help so I've removed that NG.

Very often, I get hung up on something gcc specific.
>
>> 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.
>
> You've pre-decided that this is a C learning exercise which is not
> obviously a goal that is compatible with getting something working in
> a few days time.

I finally had to face reality on that. I helped the kids with their
homework and made a couple small programs that fit closer to their
curricula. It's all ready for the post office tomorrow.

What remains is muddling my way through unix.
>
> I don't know what you intend (a short description of the purpose would
> help) but the code you posted is equivalent to a few lines of bash
> script (or Perl or Python...). If you don't know any of these,
> learning enough bash to do what the C code does would not take long (a
> day or so).

There are easier ways to read a directory than using C.
--
frank
From: frank on
Moi wrote:
> On Wed, 27 Jan 2010 00:21:30 -0700, frank wrote:
>

snip
> 4) I compacted your process_directory() function for you.

Thanks so much for tinkering with this source, Moi. It really helped me
to see this function re-fashioned.

> if (!strcmp (entry.d_name, ".") || !strcmp (entry.d_name, "..") ) continue;
> namelen = strlen(entry.d_name);
>
> if (dirlen+1+namelen+1 >= sizeof pathName) {
> fprintf(stderr,"Name too long: %u+1+%u+1 %s/%s\n"
> , (unsigned) dirlen, (unsigned) namelen,theDir,entry.d_name );
> continue; }
> memcpy (pathName, theDir, dirlen);
> pathName[dirlen] = '/';
> memcpy (pathName+dirlen+1, entry.d_name, namelen +1);
>
> if (lstat (pathName, &entryInfo) == -1) { /* stat() failed, let's party */
> fprintf (stderr, "Error statting %s: %s\n", pathName, strerror (errno)); continue; }
>
> count++;
> if (S_ISDIR (entryInfo.st_mode)) { /* directory */
> printf ("processing %s/\n", pathName);
> count += process_directory (pathName);
> continue; }
> if (S_ISREG (entryInfo.st_mode)) { /* regular file */
> printf ("\t%s has %lld bytes\n"
> , pathName, (long long) entryInfo.st_size);
> continue; }
> if (S_ISLNK (entryInfo.st_mode)) { /* symbolic link */
> char targetName[PATH_SIZE + 1];
> if (readlink (pathName, targetName, PATH_SIZE) == -1) {
> printf ("\t%s -> (invalid symbolic link!)\n", pathName);
> continue; }
> printf ("\t%s -> %s\n", pathName, targetName);

So, are there any more than than these possibilities for entry.d_name:
1) .
2) ..
3) directory
4) regular file
5) link
?
--
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: Reading /proc/<pid>/maps
Next: Code and Creation 73169