Very nice work.

Actually, OW_get is always null-terminated (we add an extra byte to the
allocation and zero it), but not all values are strings (like memory from
devices like the DS1993 are arbitrary data).

I believe owcapi is tread-safe. Certainly the underlying owlib is. owcapi has no
global variables so should be tread safe.

Calling OW_get before OW_init should return an error, I'll put in a check on
"indevices" which will show if there are any valid devices configured. Calling
OW_init implicitly would not work, since the "device" is not known (I know, the
use of a environment variable is possible).

Not calling OW_finish isn't terrible. You just can't call OW_init again, I bet.
It is the functional equivalent of "free"ing memory after use. The process death
should reclaim the memory as well.

Thanks for creating the example.

Paul

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] Behalf Of Geo
Carncross
Sent: Thursday, October 13, 2005 10:26 AM
To: owfs-developers@lists.sourceforge.net
Subject: RE: [Owfs-developers] New owcapi interface. Happy?


On Thu, 2005-10-13 at 06:45 -0400, Alfille, Paul H.,M.D. wrote:
> Oops, did my irony leak out? Can I retrieve it?

Paul, I know you despise being dragged through this :), so let me say
first that I appreciate you taking the time to examine this with me.

> I must admit sone mistification at the requested changes. I find it much
harder
> to write and document to the new OW_get, but it really isn't a big issue. At
> least the buffer, if allocatable, will be the proper length. 

Indeed.

> I clearly need to put in some example code for people.

Complete Example of using OW_get():

#include <stdio.h>
#include <stdlib.h>
#include <OWcapi.h>

void die(const char *s) { perror(s); exit(EXIT_FAILURE); }
int main(int argc, char *argv[])
{
        char *s;
        size_t n;

        if (!OW_init(NULL)) die("OW_init");
        if (!OW_get("10.468ACE13579B/temperature",&s,&n)) die("OW_get");
        OW_finish();
        (void)printf("temp is: ");
        if (n && fwrite(s,n,1,stdout) != 1) die("fwrite");
        (void)putchar('\n');
        if (fflush(stdout) == EOF) die("fflush");
        if (ferror(stdout)) die("ferror");
        free(s);
        exit(EXIT_SUCCESS);
}

Note that error checking is included- something I notice is often
missing from "example code". Commented version:

        /* initialize the 1wire system. NULL uses system-defaults for
         * the device/port -- usually the result of getenv("OWDEVICE");
         */
        if (!OW_init(NULL)) die("OW_init");

        /* fetch our device temp */
        if (!OW_get("10.468ACE13579B/temperature",&s,&n)) die("OW_get");

        /* tell 1wire system we're done using it. */
        OW_finish();

        /* emit results */
        (void)printf("temp is: ");

        /* note that if n==0
         * fwrite() will return 0 (on many systems, including Linux)
         * even though POSIX suggests it could return 1.
         *
         * Remember: there's no guarantee that s will be null terminated
         * so we must use fwrite to display it.
         */
        if (n && fwrite(s,n,1,stdout) != 1) die("fwrite");

        (void)putchar('\n');

        /* you are checking for errors, aren't you? :) */
        if (fflush(stdout) == EOF) die("fflush");
        if (ferror(stdout)) die("ferror");

        /* free the memory allocated by OW_get() */
        free(s);

        exit(EXIT_SUCCESS);


> Modify away.

I find, after looking at the example code generated for an interface,
that I can always come up with some brevity improvements. Clearly this
interface is adequate (as was the previous one)- and this interface acts
very similarly to the other [generated] interfaces- but after looking at
the example, what looks redundant?

In my code, I'd probably never free(s)- but this is an example, so we
should show a complete snapshot with the understanding that the user
will know that free() is unnecessary _here_, but remind them it'll be
necessary elsewhere.

I'd also probably not use printf/write/fflush/ferror simply because the
error handling of those routines is awful, but again: the user at least
thinks they know how those routines work, so they'll not be surprised
too much.

This leaves us with this:

        if (!OW_init(NULL)) die("OW_init");
        if (!OW_get("10.468ACE13579B/temperature",&s,&n)) die("OW_get");
        OW_finish();

Clearly the user will never have to "work around" any deficiencies with
this API- they don't need to make repeated calls to OW_get with larger
buffer sizes, and so on....

Okay, so it's adequate and complete, but some questions remain:

* Do I need the OW_finish() What exactly does OW_finish() buy me in this
example?
* Alright, how about OW_init()? Is it reasonable to have OW_get call it
if OW_init(NULL) hasn't been called yet?

I think that they should be kept ESPECIALLY because other
language-bindings have them, but why are they called?

Is there danger in me doing this?

        OW_init(0);
        switch (fork()) {
        case 0: OW_get(...);
        default: OW_get(...);
        };

What happens? What kind of surprise do I get? What if I use owserver?

I find it's usually easier to say things like:

* API xyz should only be utilized by a single thread/process

and to hell with the consequences :)


> Paul
> 
> 
> -----Original Message-----
> From: [EMAIL PROTECTED] on behalf of Christian
> Magnusson
> Sent: Wed 10/12/2005 11:34 PM
> To: owfs-developers
> Subject: Re: [Owfs-developers] New owcapi interface. Happy?
>  
> 
> That subject almost sounded ironic to me... :)  Are you tired of
> new changes?
> Anyway, nice that this capi finally is developed. I will be back
> with some additions to this later. I have written some c-applications
> using a mounted fuse filesystem, and I have always been missing lots of
> functions and connections to the actual 1-wire devices all the time.
> I guess I could add some of that code to the c-api now instead.
> 
> /Christian
> 
> 
> On Thu, 2005-10-13 at 04:02, Paul Alfille wrote:
> > /*
> > $Id: owcapi.h,v 1.3 2005/10/11 21:37:21 alfille Exp $
> >    OWFS (owfs, owhttpd, owserver, owperl, owtcl, owphp, owpython, owcapi)
> >    one-wire file system and related programs
> > 
> >     By Paul H Alfille
> >     {c} 2003-5 GPL
> >     [EMAIL PROTECTED]
> > */
> 
> 
> 
> 
> -------------------------------------------------------
> This SF.Net email is sponsored by:
> Power Architecture Resource Center: Free content, downloads, discussions,
> and more. http://solutions.newsforge.com/ibmarch.tmpl
> _______________________________________________
> Owfs-developers mailing list
> Owfs-developers@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/owfs-developers

-- 
Internet Connection High Quality Web Hosting
http://www.internetconnection.net/



-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
Owfs-developers mailing list
Owfs-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/owfs-developers


-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
Owfs-developers mailing list
Owfs-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/owfs-developers

Reply via email to