[augeas-devel] Re: Add (*aug_fprintf) vector and void * I/O handle [+PATCH]

Jeff Johnson n3npq at mac.com
Wed Jun 24 02:54:57 UTC 2009


On Jun 23, 2009, at 8:46 AM, David Lutterkort wrote:

> Hi Jeff,
>
> On Sat, 2009-06-20 at 16:08 -0400, Jeff Johnson wrote:
>> This dinky patch permits an application (like RPM) to
>> capture fprintf output into a buffer without resorting
>> to memstream's.
>>
>> Slightly better would be to add the (vector to struct aug
>> to permit per-instance overrides, but that is likely overkill,
>> and would be a bit more intrusive into your API.
>>
>> Patch against current Augeas git afaik.
>
> Yeah, aug_print wasn't the smartest thing to include in the API, since
> its use is extremely limited.
>

Absoulutely agreed that aug_print isn't exactly essential to augtool
(but its is the only means atm to display paths for orientation to
a user).

And most definitely the patch I sent you is quick-n-dirty. It
was the minimal necessary change to accompish a highly peculier
and unusual task, i.e. embedding augtool within rpm. That isn't
what augtool was designed for, and better could/should be done
with augtool. Meanwhile, I needed to capture stdout into a
buffer "portably", which means no memstream's and libio etc etc.

> The right way to address that shortcoming is to add a tree-walking  
> API;
> though I am not quite sure what the right callback mechanism is. I am
> thinking that the callback should get an opaque, unique token, the  
> label
> and the value of the current node - the order of callbacks should be
> 'ENTER node foo', traverse all children, 'LEAVE node foo' -  
> actually, we
> also need a separate indication for starting and ending the  
> traversal of
> a tree, since an XPath expression can match multiple disconnected
> subtrees (e.g., '/augeas//error')
>

Capturing I/O and adding a tree walk with callbacks are ultimately
different goals. Both need to be done. Consider your foo.aug lens I/O,  
which is I/O
that cannot be handled by a tree walk, to see the difference.

But sure, a tree walk with callbacks could replace aug_print easily.

> That would give us a signature for the callback like
>
>        enum aug_iter_event {
>          AUG_START,   /* start traversal of a new subtree */
>          AUG_ENTER,   /* enter a node, used before traversing any  
> children */
>          AUG_LEAVE,   /* leave a node, used after traversing all  
> children */
>          AUG_END      /* finish traversal of a subtree */
>        };
>        int (*aug_iter) (void *token, enum aug_iter_event event,  
> const char *label, const char *value, void *user_data);
>
> and an API function
>
>        int aug_iter(augeas *aug, const char *pathx, aug_iter *iter);
>

As I suggested privately, I'd look to fts(3) as a solid and mature  
example
of an API that is both consistent with what is in Augeas (both XPath  
and fts(3)
have a means to collect sub-node or sub-directory "children", unlike  
nftw(3) from POSIX),
and also has data structures and parameterization defined that is  
useful for any file
system traversal. fts(3) is exactly the "guts" of *BSD find(1) for  
years and years,
even if one tends to prefer the POSIX nftw(3) on Linux.

I also mentioned that a very slight modification to fts(3) to add  
vectors like

         DIR * (*fts_opendir) (const char * path)
                 /*@globals fileSystem @*/
                 /*@modifies fileSystem @*/;
         struct dirent * (*fts_readdir) (DIR * dir)
                 /*@globals fileSystem @*/
                 /*@modifies *dir, fileSystem @*/;
         int (*fts_closedir) (/*@only@*/ DIR * dir)
                 /*@globals fileSystem @*/
                 /*@modifies *dir, fileSystem @*/;
         int (*fts_stat) (const char * path, /*@out@*/ struct stat * st)
                 /*@globals fileSystem @*/
                 /*@modifies *st, fileSystem @*/;
         int (*fts_lstat) (const char * path, /*@out@*/ struct stat *  
st)
                 /*@globals fileSystem @*/
                 /*@modifies *st, fileSystem @*/;

adds the ability to traverse non-file system trees if one can live
within some modest constraints, like populating a stat(2) structure
sufficiently to drive an fts(3) tree traversal, and populating
DIR and struct dirent structures compatibly with the existing OS  
structures.

RPM has been using this modified fts(3) for years to traverse remote
FTP/HTTP trees, XPath paths would be far far easier, mostly because
no network errors would ever be involved.

The reason for use a private fts(3) is not only for a public API that  
is largely documented
and identical with "man 3 fts", but also to use the same fts(3) within  
Augeas
itself, which most certainly is doing file tree traversals, albeit by
assembling paths and using glob(3) to, say, load modules in aug_init().

But most certainly, any well defined file tree walk API across the  
Augeas XPath tree
will suffice for (and benefit) Augeas.

> Maybe the stuff about subtree start/end should be split into a second
> callback that gets the full path to the subtree's root passed in.
>
> What do you think ? (Please post your reply to augeas-devel so others
> can chime in),

Done.

73 de Jeff
> David
>
>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4664 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20090623/a7d9887c/attachment.p7s>


More information about the augeas-devel mailing list