rtems_bsdnet_fdToSocket()

Till Straumann strauman at slac.stanford.edu
Fri Feb 13 00:17:29 UTC 2009


Chris Johns wrote:
> Joel Sherrill wrote:
>> Till Straumann wrote:
>>> Chris Johns wrote:
>>>  
>>>> Till Straumann wrote:
>>>>   
>>>>> IMHO rtems_bsdnet_fdToSocket() doesn't
>>>>> verify thoroughly enough that the file
>>>>> descriptor passed in is really a socket.
>>>>>
>>>>> If you e.g., try getsockname() on a fd
>>>>> that was opened on a termios device then
>>>>> a crash may result.
>>>>>
>>>>> I propose to let rtems_bsdnet_fdToSocket()
>>>>> test not only that iop->data1 is NULL but
>>>>> to add an additional test.
>>>>>
>>>>> Either
>>>>> 1) add a new flag LIBIO_FLAGS_ISSOCK
>>>>>    which is set by rtems_bsdnet_makeFdForSocket()
>>>>>    and tested by rtems_bsdnet_fdToSocket()
>>>>> 1a) instead of one flag we could use a few
>>>>>    more bits and create a LIBIO_FLAGS_IOP_TYPE
>>>>>    bitmask (in case the need for other special
>>>>>    cases besides sockets arises in the future).
>>>>>    The test would then look like
>>>>>
>>>>>    if ( LIBIO_FLAGS_IOP_TYPE(iop->flags) != 
>>>>> LIBIO_FLAGS_IOP_TYPE_SOCK ) {
>>>>>        errno = ENOTSOCK;
>>>>>        return NULL;
>>>>>    }
>>>>>
>>>>>    Sidenote: IMO, if data1 == NULL then errno should
>>>>>              also be ENOTSOCK instead of EBADF.
>>>>>
>>>>>       
>>>> The LIBIO flags do not describe the fd rather they deal with what 
>>>> you can do. I do not like the type of fd being added to the flags.
>>>>
>>>> NetBSD has a type field in the fp referenced by the fd:
>>>>     
>>> Problemo being that libio has no such thing. It has
>>> absolutely no knowledge about what is attached to
>>> 'data', 'data1', 'file-info'.
>>>
>>> Where do you see an equivalent to fp_type in the iop
>>> or how would you propose that, given a iop, the
>>> code can figure out what kind of object
>>> is attached to e.g., 'data1' ?
>>>
>
> I am suggesting we add a type field. 
OK - then we're on the same page. I thought you didn't like the idea of
knowledge about a file type built into a 'iop'. If the type is encoded
in 'flags' or in a dedicated field doesn't matter too much, IMHO since
it would be accessed via a macro or inline, i.e., the user setting or
querying the type wouldn't have to know how/where is is kept.

rtems_libio_iop_set_type(iop, type)

type   rtems_libio_iop_get_type(iop)

> This makes the way we test common and does not depend on the way the 
> other fields in the struct are used. I see the other ways as possible 
> maintenance issues. That is the tests for a specific type cannot 
> overlap and all need to be in a common location. Making the test 
> common is even better, ie check the type field. This is a limited 
> number of types.
>
> Again NetBSD has:
> $ less sys/sys/file.h
>   .....
> /*
>  * Kernel descriptor table.
>  * One entry for each open kernel vnode and socket.
>  */
> struct file {
>         LIST_ENTRY(file) f_list;        /* list of active files */
>         int             f_flag;         /* see fcntl.h */
>         int             f_iflags;       /* internal flags */
> #define DTYPE_VNODE     1               /* file */
> #define DTYPE_SOCKET    2               /* communications endpoint */
> #define DTYPE_PIPE      3               /* pipe */
> #define DTYPE_KQUEUE    4               /* event queue */
> #define DTYPE_MISC      5               /* misc file descriptor type */
> #define DTYPE_CRYPTO    6               /* crypto */
> #define DTYPE_NAMES \
>     "0", "file", "socket", "pipe", "kqueue", "misc", "crypto"
>         int             f_type;         /* descriptor type */
>   ......
>
> I also like the iflags field. If we make a change to add fields I 
> would like the iflags field added.
>
>>> Do you like testing the 'handlers' better?
>
> No. It exposes the lower layers to the upper layers and means more 
> globals.
I couldn't agree more.
>
> There could also be other complexity like something having more than 
> one possible set of handlers. The DOSFS has this for dir and file 
> handlers.
Agreed, again.

T.
>
>>>   
>> Looking at libcsupport/src/libio_socket.c, that's the only
>> thing you can currently rely on.
>>
>> Might not be a bad generic check.  Worth a libio macro
>> like rtems_libio_handlers_match?
>
> It mixes layers. What handlers do you need to match with.
>
> Regards
> Chris
>
>>
>> --joel
>>> T.
>>>  
>>>> int
>>>> getsock(struct filedesc *fdp, int fdes, struct file **fpp)
>>>> {
>>>>         struct file     *fp;
>>>>
>>>>         if ((fp = fd_getfile(fdp, fdes)) == NULL)
>>>>                 return (EBADF);
>>>>
>>>>         FILE_USE(fp);
>>>>
>>>>         if (fp->f_type != DTYPE_SOCKET) {
>>>>                 FILE_UNUSE(fp, NULL);
>>>>                 return (ENOTSOCK);
>>>>         }
>>>>         *fpp = fp;
>>>>         return (0);
>>>> }
>>>>
>>>> I would prefer this.
>>>>
>>>> Regards
>>>> Chris
>>>>
>>>>   
>>>>> 2) alternatively, rtems_bsdnet_fdToSocket() could
>>>>>    test if iop->handlers == socket_handlers.
>>>>>
>>>>>    socket_handlers would then have to become a globally
>>>>>    visible symbol (right now a static variable).
>>>>>
>>>>>    Unfortunately, this would introduce some asymmetry
>>>>>    (fdToSocket() refers to global symbol, makeFdForSocket
>>>>>    gets pointer to handlers passed in).
>>>>>
>>>>> If nobody objects or has a better idea then I would
>>>>> implement 1a), create a PR and commit to 4.9 and HEAD.
>>>>>
>>>>> RFC
>>>>> -Till
>>>>> _______________________________________________
>>>>> rtems-users mailing list
>>>>> rtems-users at rtems.com
>>>>> http://rtems.rtems.org/mailman/listinfo/rtems-users
>>>>>       
>>>
>>> _______________________________________________
>>> rtems-users mailing list
>>> rtems-users at rtems.com
>>> http://rtems.rtems.org/mailman/listinfo/rtems-users
>>>   
>>
>>




More information about the users mailing list