On Tue, 2005-10-11 at 21:29 -0400, Paul Alfille wrote:
> > > int OW_get( const char * path, char * buffer, int buffer_length ) ;
> >
> > Don't let the programmer specify a buffer length for gets. It's prone to
> > programming errors. The extra malloc() isn't going to cause any real
> > problems, but if you're worried, a:
> >
> 
> We could do that, and demand the programmer "free" the buffer. The length 
> would be problematic, since some "get" values are binary rather than ascii so 
> can't be handled by normal string functions.

Right, then we should use two values:

int OW_get(const char *path,char**buffer,unsigned int *len);

This should be the encouraged interface so that they get the entire
value. If they're sure they can get by with less, they can use
OW_get_buffer().


> The memory allocation choice is purely a matter of style. OW_put will need to 
> know the buffer length, however, since some field can get null bytes in their 
> binary data. The "char ** buffer" parameter in OW_get can scare people, too.

That's probably why people don't use asprintf().

These people get bugs. Learning to use returned pointers like this makes
for safer code.


> libowcapi currently mirrors the owperl API rather closely. It is an 
> admittedly 
> sparse API, but targetted at programs where 1-wire performance and features 
> are secondary to ease of use. For me, the big advantage is that keeping a 
> simple and similar API makes maintainance and documentation far easier.

Perl doesn't have this problem; Perl has a concept of a string. So does
python and Java. C doesn't and when people use C, they frequently make
mistakes.

Helping them avoid mistakes involves:

* allocating for them in the common cases
* don't trust their buffers (!)
* making their program crash lots when broken, and never when correct

That last one is hard, but with small programs and an API that
encourages safe behavior, it's fairly attainable.

I don't think this is simply a matter of style- lots of C programmers
use "style" as an argument to write extremely tricky blocks of code.

The standard C library is used everywhere. It's also not a safe library
to use: fgets() and fread() _frequently_ surprise people. It doesn't
help that these library functions are broken on some machines.

When someone finally finds the need to write a suid program, or a
program that reads from the internet (anonymous), then annoying bugs get
turned into huge security weaknesses.

I'm of the opinion that if char** scares someone, they should be using
tcl or perl or python. If they can get past their fears, they'll be
happier as a result, and will probably do "the right thing" more often.

FS_read() doesn't interact with a file descriptor (for example), so
implementing blocking as described is hard, but one could use:

int OW_get( const char * path, char **buffer, size_t *buffer_length ) {
        char *q;
        size_t p;
        int r;
#define CHUNK 1024
        for (q = 0, p = 0;;) {
                q = realloc(q, p+CHUNK);
                if (!q) return __owc_err_func("OW_get",errno);
                r = FS_read(path,q+p,CHUNK,p);
                if (r < 0) {
                        (void)free(q); /* some free() clear errno */
                        return __owc_err_func("OW_get",r);
                }
                if (r < 1) break;
                if (r < p) {
                        /* assumes r==p if more */
                        p += r;
                        break;
                }
        }
        if (buffer_length)*buffer_length=p;
        if (buffer)*buffer=q; else (void)free(q);
        return 0;               
#undef CHUNK
}

Note the returns changed to refer to __owc_err_func() for error
conditions.

int _ow_error_default(const char *s,int r) {
        if (r > 0) { /* errno */
                perror(s);
                exit(255);
        }
        /* other critical errors? */
        return r;
}
int _ow_error_ansi(const char *s, int r) { return r; }
int (*__owc_err_func)(const char *,int r) = _ow_error_default;

void OW_errors(int(*f)(const char *,int));

int OW_get_buffer(const char *path, char *buffer, size_t size, size_t
off)
{
        int r = FS_read(path,buffer,size,off);
        if (r == 0) return 0;
        return __ow_err_func(r);
}

So blocking/completions isn't a requirement, and might make good
additions to the low-level protocol (when we start talking about file
descriptors) -- AND could benefit TCL and Perl as well.

But note here, that while _YOU_ and _I_ can write these things like
this, people who are using the specified API probably cannot. If they
can, they might as well use OW_get_buffer() and they'll know what
they're doing. If not, they'll use OW_get() which at least WORKS LIKE
the perl and tcl and other apis (or how they could...)

> There is no reason why a C program can't call libow itself, rather than using 
> libowcapi as a wrapper. In fact, libowcapi shows how to get started.

....

> If you have interest and a need for the C-API, feel free to modify or start 
> another C wrapper targetted at a different set of users. Serg and Peter have 
> taken owtcl and owpython under their respective wings .

I'd be happy to. But it sounds like there's some resistance to my think
on this that I'd like to work out first :)

-- 
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/owfs-developers

Reply via email to