From: Moi on
On Thu, 18 Feb 2010 21:37:02 -0700, Phred Phungus wrote:

> Hello newsgroups,
>
> As an exercise for an autodidact, I've been trying to write a reasonable
> read directory utility in more or less standard C.
>
> #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
>

Please read my reply from 6 feb 2010.
If you read it carefully, you'll notice that
the only place were a fixed size buffer
occurs, is in the symlink handling, (which is not needed anyway).

Please don't start a new topic for the same issue.
Starting a new topic will *not* help you or the repliers
to find the relevant stuff.

HTH,
AvK
From: Phred Phungus on
Moi wrote:

> Please read my reply from 6 feb 2010.
> If you read it carefully, you'll notice that
> the only place were a fixed size buffer
> occurs, is in the symlink handling, (which is not needed anyway).
>
> Please don't start a new topic for the same issue.
> Starting a new topic will *not* help you or the repliers
> to find the relevant stuff.
>
> HTH,
> AvK

On the contrary, I mean for the new thread to destroy the context, so
that I can refocus. In directories I, I was recursing through
subdirectories, as this is what the first source I got to work at all
did. Now, I'm not. This source also had references to PATH_MAX, which
was quite the can of worms.

Your source from 2-6 uses a struct hack, which I consider to be a design
flaw:

> struct bag {
> unsigned used;
> unsigned size;
> char *data[1]; /* struct hack here ... */
> };

If I wanted to continue with this material, it would be in the direction
of using buffers effectively. In particular, I would address what one
does when the buffer he has isn't large enough for the data to be
accomodated. Your solution is here:

> struct bag * bag_resize( struct bag * old, unsigned size )
> {
> struct bag * new;
> unsigned used;
>
> #if SHOW_BAGS
> fprintf( stderr, "Bag_resize(%u -->> %u)\n", old?old->size:0, size );
> #endif
> if ( !size ) { free ( old ); return NULL; }new = malloc ( sizeof *new + size * sizeof new->data[0] );
> if ( !new ) {
> fprintf( stderr, "Bag_resize: Malloc(%u) went wrong\n"
> , (unsigned) sizeof *new + size * sizeof new->data[0] );
> return old;
> }
> used = old ? size < old->used ? size : old->used : 0;
> if ( used ) memcpy ( new->data, old->data, used * sizeof new->data[0] );
> new->used = used;
> new->size = size;
> for ( ; used < size; used++ ) new->data[used] = NULL;
> free ( old );
> return new;
> }

[sorry, I can only "paste as quotation" right now. It's annoying.]

This is pretty readable, but again, there's that struct hack. I thought
I would try for a different design.

Nevertheless, I appreciate your comment with compilable source.
--
fred
From: Moi on
On Sun, 28 Feb 2010 11:50:41 -0700, Phred Phungus wrote:

> Moi wrote:
>
>> Please read my reply from 6 feb 2010. If you read it carefully, you'll
>> notice that the only place were a fixed size buffer occurs, is in the
>> symlink handling, (which is not needed anyway).
>>
>> Please don't start a new topic for the same issue. Starting a new topic
>> will *not* help you or the repliers to find the relevant stuff.
>>
>> HTH,
>> AvK
>
> On the contrary, I mean for the new thread to destroy the context, so
> that I can refocus. In directories I, I was recursing through

Well I can advice you: don't refocus on fixed-size buffers. You don't need them.
Also, it shows you don't need recursion.
(which is good, because each time you recurse, you'll open an additional DIR cursor.)


> subdirectories, as this is what the first source I got to work at all
> did. Now, I'm not. This source also had references to PATH_MAX, which
> was quite the can of worms.

As I said, the only place where a fixed sized buffer was used was in
the handling of symlinks (which is rather unimportant).

>
> Your source from 2-6 uses a struct hack, which I consider to be a design
> flaw:

Please elaborate. IMHO, there is no reason to see a struct hack as a flaw.
Also, rewriting it to use an extra pointer element instead of the poor man's VLAs
would probably not cost more than 10-15 minutes.

>
>> struct bag {
>> unsigned used;
>> unsigned size;
>> char *data[1]; /* struct hack here ... */ };

char **data; /* no struct hack here! */


HTH,
AvK

From: Ersek, Laszlo on
In article <75e15$4b8abee6$5350c024$10011(a)cache100.multikabel.net>,
Moi <root(a)invalid.address.org> writes:

> Please elaborate. IMHO, there is no reason to see a struct hack as a flaw.

The struct hack is undefined behavior in C89, because (sloppily
speaking) you're over-subscripting an array whose size you've made
available to the compiler at compile time.

http://href.hu/x/bmy4
http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/8c4ffee38737e501/e1f24f1be062ca14#e1f24f1be062ca14

http://href.hu/x/bmy5
http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/75f15a39d051abed/d922650b07cb292b#d922650b07cb292b

http://href.hu/x/bmy6
http://groups.google.com/group/comp.lang.c.moderated/browse_thread/thread/5d89504a6c1e959d/4c9f9be97be1868f#4c9f9be97be1868f

There are ways to get around it, if the hacked array has a character
type as element type (that is, no special alignment needs). Otherwise, I
think the required alignment cannot be ensured portably.

As a curiosity mentioned in the second thread as well, SUSv2 (which is
based on C89) has examples featuring the struct hack (with character
types as element types):

http://www.opengroup.org/onlinepubs/007908775/xsh/msgsnd.html
http://www.opengroup.org/onlinepubs/007908775/xsh/msgrcv.html

C99 has a dedicated facility, the flexible array member, but it has a
different syntax.

C99 6.7.2.1 "Structure and union specifiers", p17 (Example):

----v----
[...]

struct s { int n; double d[]; };

[...]
----^----

Cheers,
lacos
From: Ersek, Laszlo on
In article <41wm5VNPEw0f(a)ludens>, lacos(a)ludens.elte.hu (Ersek, Laszlo) writes:

> There are ways to get around it, if the hacked array has a character
> type as element type (that is, no special alignment needs). Otherwise, I
> think the required alignment cannot be ensured portably.

I think it's only fair to say that James Kuyper did provide an example,
with an array of double, in

http://groups.google.com/group/comp.lang.c.moderated/msg/22c60e9047477c10

Cheers,
lacos
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: Forging IPv6 addresses?
Next: using select as a sleep call