iofunc_open_default ()

Is prototyped as:

extern int iofunc_open_default(resmgr_context_t *__ctp, io_open_t *__msg, iofunc_attr_t *__attr, void *__extra);

in <sys/iofunc.h>

I’m wondering if the third argument, the “attr”, should really be prototyped as
the extensible “overridable” attr type? The reasoning is, logically I’m binding
the “entire” extended attribute type to the OCB, not just the “regular” attr structure,
even though it may “appear” that I’m just binding the attr.

Prolly a semantics issue; just wanted to raise it and get it addressed…

Here’s a code snippet to illustrate, using extended attributes structures (see last line):

int
captivefs_io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
char fname [_POSIX_PATH_MAX];
char *p;
int nels, i;
eas_t *attr; // the extended attributes structure

strcpy (fname, msg → connect.path);

p = strtok (fname, “/”);
attr = handle;
while (p != NULL) {
nels = attr → type.dirblock ? attr → type.dirblock → nels : 0;
for (i = 0; i < nels; i++) {
if (!strcmp (attr → type.dirblock → els _-> name, p)) { // found it!
if (!S_ISDIR (attr → attr.mode)) {
return (ENOTDIR); // can’t “cd” into it if it’s not a directory
}
attr = attr → type.dirblock → els → attr; // effectively, “cd” into the directory
break;
}
}
if (i == nels) {
return (ENOENT); // couldn’t find it, so go away.
}
p = strtok (NULL, “/”) ; // get next pathname element
}

return (iofunc_open_default (ctp, msg, attr, extra)); // done, bind this OCB to the extended attributes structure that was found
}

Compiler whines about:

captivefs.c:80: warning: passing arg 3 of `iofunc_open_default’ from incompatible pointer type

Thanks,
-RK
\

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com._

Robert Krten <nospam83@parse.com> wrote:

Is prototyped as:

extern int iofunc_open_default(resmgr_context_t *__ctp, io_open_t *__msg, iofunc_attr_t *__attr, void *__extra);

in <sys/iofunc.h

I’m wondering if the third argument, the “attr”, should really be prototyped as
the extensible “overridable” attr type? The reasoning is, logically I’m binding
the “entire” extended attribute type to the OCB, not just the “regular” attr structure,
even though it may “appear” that I’m just binding the attr.

Prolly a semantics issue; just wanted to raise it and get it addressed…

I don’t agree.

iofunc_open_default() relys on the __attr point to “iofunc_attr_t *”,
it can not be “void *” or “struct myattr { int a}” or …

Change the prototype to (… IOFUNC_ATTR_T, ) is not acceptable,
because I could define “IOFUNC_ATTR_T” to something that won’t
have a iofunc_attr_t in it, as long as I don’t use any _default
function; and in same source I could have another manager just
use normal iofunc_open_default().

So to your source, you either have to cast it, or pass
&attr->real_attr to iofunc_open_default().

-xtang

Here’s a code snippet to illustrate, using extended attributes structures (see last line):

int
captivefs_io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
char fname [_POSIX_PATH_MAX]; > char *p; > int nels, i; > eas_t *attr; // the extended attributes structure
strcpy (fname, msg → connect.path);

p = strtok (fname, “/”);
attr = handle;
while (p != NULL) {
nels = attr → type.dirblock ? attr → type.dirblock → nels : 0;
for (i = 0; i < nels; i++) {
if (!strcmp (attr → type.dirblock → els > → name, p)) { // found it!
if (!S_ISDIR (attr → attr.mode)) {
return (ENOTDIR); // can’t “cd” into it if it’s not a directory
}
attr = attr → type.dirblock → els > → attr; // effectively, “cd” into the directory
break;
}
}
if (i == nels) {
return (ENOENT); // couldn’t find it, so go away.
}
p = strtok (NULL, “/”) ; // get next pathname element
}

return (iofunc_open_default (ctp, msg, attr, extra)); // done, bind this OCB to the extended attributes structure that was found
}

Compiler whines about:

captivefs.c:80: warning: passing arg 3 of `iofunc_open_default’ from incompatible pointer type

Thanks,
-RK

Xiaodan Tang <xtang@qnx.com> wrote:

Robert Krten <> nospam83@parse.com> > wrote:

Is prototyped as:

extern int iofunc_open_default(resmgr_context_t *__ctp, io_open_t *__msg, iofunc_attr_t *__attr, void *__extra);

in <sys/iofunc.h

I’m wondering if the third argument, the “attr”, should really be prototyped as
the extensible “overridable” attr type? The reasoning is, logically I’m binding
the “entire” extended attribute type to the OCB, not just the “regular” attr structure,
even though it may “appear” that I’m just binding the attr.

Prolly a semantics issue; just wanted to raise it and get it addressed…

I don’t agree.

iofunc_open_default() relys on the __attr point to “iofunc_attr_t *”,
it can not be “void *” or “struct myattr { int a}” or …

Change the prototype to (… IOFUNC_ATTR_T, ) is not acceptable,
because I could define “IOFUNC_ATTR_T” to something that won’t
have a iofunc_attr_t in it, as long as I don’t use any _default
function; and in same source I could have another manager just
use normal iofunc_open_default().

So to your source, you either have to cast it, or pass
&attr->real_attr to iofunc_open_default().

I agree with your point about “I could define ‘IOFUNC_ATTR_T’ to something that won’t have an iofunc_attr_t”, but that goes against everything that’s in the documentation about
how the attributes structure must be the first member of an extended attributes structure…

Anyway, I’ll just pass the “real” attribute structure – just wanted to check that I wasn’t missing something.
Thanks Xiaodan!

Cheers,
-RK

-xtang

Here’s a code snippet to illustrate, using extended attributes structures (see last line):

int
captivefs_io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
char fname [_POSIX_PATH_MAX]; > char *p; > int nels, i; > eas_t *attr; // the extended attributes structure
strcpy (fname, msg → connect.path);

p = strtok (fname, “/”);
attr = handle;
while (p != NULL) {
nels = attr → type.dirblock ? attr → type.dirblock → nels : 0;
for (i = 0; i < nels; i++) {
if (!strcmp (attr → type.dirblock → els > → name, p)) { // found it!
if (!S_ISDIR (attr → attr.mode)) {
return (ENOTDIR); // can’t “cd” into it if it’s not a directory
}
attr = attr → type.dirblock → els > → attr; // effectively, “cd” into the directory
break;
}
}
if (i == nels) {
return (ENOENT); // couldn’t find it, so go away.
}
p = strtok (NULL, “/”) ; // get next pathname element
}

return (iofunc_open_default (ctp, msg, attr, extra)); // done, bind this OCB to the extended attributes structure that was found
}

Compiler whines about:

captivefs.c:80: warning: passing arg 3 of `iofunc_open_default’ from incompatible pointer type

Thanks,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Robert Krten <nospam83@parse.com> wrote:

Is prototyped as:

extern int iofunc_open_default(resmgr_context_t *__ctp, io_open_t *__msg, iofunc_attr_t *__attr, void *__extra);

in <sys/iofunc.h

I’m wondering if the third argument, the “attr”, should really be prototyped as
the extensible “overridable” attr type? The reasoning is, logically I’m binding
the “entire” extended attribute type to the OCB, not just the “regular” attr structure,
even though it may “appear” that I’m just binding the attr.

You mean you’d like the header to say that a function in the library has
a type that depends on a user-defined type?

Wouldn’t that be a lie?

Using a prototype that isn’t compatible with the function’s actual
definition is undefined behaviour according to the C standard. In
theory, a compiler could decide which register to pass the argument in
based on, for instance, the size of the structure it points to.

Of course, everybody knows that no compiler does anything like that, at
least not under QNX; but my point is that it would make it a very ugly
API if we officially admitted that our header tells a lie to the
compiler, even if everybody knows that the lie is harmless to all the
compilers that can possibly see this header.


Wojtek Lerch QNX Software Systems Ltd.

Wojtek Lerch <wojtek_l@yahoo.ca> wrote:

Robert Krten <> nospam83@parse.com> > wrote:

Is prototyped as:

extern int iofunc_open_default(resmgr_context_t *__ctp, io_open_t *__msg, iofunc_attr_t *__attr, void *__extra);

in <sys/iofunc.h

I’m wondering if the third argument, the “attr”, should really be prototyped as
the extensible “overridable” attr type? The reasoning is, logically I’m binding
the “entire” extended attribute type to the OCB, not just the “regular” attr structure,
even though it may “appear” that I’m just binding the attr.

You mean you’d like the header to say that a function in the library has
a type that depends on a user-defined type?

That’s already the case with the other functions in the <sys/iofunc.h>
type. Look at the way that we “override” the attributes structure today:

#define IOFUNC_ATTR_T struct my_new_one
#include <sys/iofunc.h>

Wouldn’t that be a lie?

Yup; and so’s the “standard” way of doing it today. I was just wondering
about the consistency of the lies… :slight_smile:

Using a prototype that isn’t compatible with the function’s actual
definition is undefined behaviour according to the C standard. In
theory, a compiler could decide which register to pass the argument in
based on, for instance, the size of the structure it points to.

Of course, everybody knows that no compiler does anything like that, at
least not under QNX; but my point is that it would make it a very ugly
API if we officially admitted that our header tells a lie to the
compiler, even if everybody knows that the lie is harmless to all the
compilers that can possibly see this header.

Yup; like I said in a previous post, I’ll be using “&attr.attr” to inform
the compiler and everyone that I’m really passing the attributes structure,
even though I “know” that the functions will be binding just a 32-bit
pointer, which I “know” I’ll be using later as the extended attribute type.
It’s all lies anyway :slight_smile:

Cheers,
-RK

\

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Robert Krten <nospam83@parse.com> wrote:

Wojtek Lerch <> wojtek_l@yahoo.ca> > wrote:
Robert Krten <> nospam83@parse.com> > wrote:

Is prototyped as:

extern int iofunc_open_default(resmgr_context_t *__ctp, io_open_t *__msg, iofunc_attr_t *__attr, void *__extra);

in <sys/iofunc.h

I’m wondering if the third argument, the “attr”, should really be prototyped as
the extensible “overridable” attr type? The reasoning is, logically I’m binding
the “entire” extended attribute type to the OCB, not just the “regular” attr structure,
even though it may “appear” that I’m just binding the attr.

You mean you’d like the header to say that a function in the library has
a type that depends on a user-defined type?

That’s already the case with the other functions in the <sys/iofunc.h
type. Look at the way that we “override” the attributes structure today:

#define IOFUNC_ATTR_T struct my_new_one
#include <sys/iofunc.h

Yeah, I know… I guess I’m just being a bit paranoid…

Wouldn’t that be a lie?

Yup; and so’s the “standard” way of doing it today. I was just wondering
about the consistency of the lies… > :slight_smile:

Actually, after a look it turns out less bad than I expected. The only
functions that directly depend on user-defined types (IOFUNC_ATTR_T,
IOFUNC_OCB_T, and RESMGR_HANDLE_T) are iofunc_ocb_calloc(),
iofunc_ocb_free(), iofunc_lock_calloc(), and resmgr_attach(). The rest
of places where those types are used are pointers inside structures,
which sounds safer to me for some reason…

Hey, I know: maybe it’s because I was subconsciously thinking about C++.
If those were C++ functions, changing the type of the argument means
that you’re talking about a completely different function – you have
to be really careful if you want to make sure that you’re not. But if
you just change the type of a pointer inside a structure, that’s much
safer…

Using a prototype that isn’t compatible with the function’s actual
definition is undefined behaviour according to the C standard. In
theory, a compiler could decide which register to pass the argument in
based on, for instance, the size of the structure it points to.

(BTW: I was a bit wrong here. The compiler must be able to generate
correct code for the function and for calls to the function without
knowing the size of the structure. But it could make the decision based
on the length of the structure tag. Which, of course, sounds really,
really unrealistic…)

Yup; like I said in a previous post, I’ll be using “&attr.attr” to inform
the compiler and everyone that I’m really passing the attributes structure,
even though I “know” that the functions will be binding just a 32-bit
pointer, which I “know” I’ll be using later as the extended attribute type.
It’s all lies anyway > :slight_smile:

Yes, but some of them are guaranteed to work by the C Standard. I think
typecasting a structure pointer to a different structure pointer and
back is safer than telling the compiler that a function takes a
different type of pointer than it actually does. But like I said, I
think I’m just being a bit paranoid…


Wojtek Lerch QNX Software Systems Ltd.