Re: how to use the function copyout()

From: Scott Long (scottl_at_samsco.org)
Date: 07/26/05

  • Next message: Scott Long: "Re: how to use the function copyout()"
    Date: Mon, 25 Jul 2005 17:42:31 -0600
    To: Felix-KM@yandex.ru
    
    

    Felix-KM wrote:

    > I can't understand how to use the function copyout().
    > It is necessary to write the data from a device driver to the
    > array defined in user program.
    > I do it this way:
    >
    > #define IOCTL_GET_B _IOWR("F", 127, 0x4)
    >

    What you've declared here is an ioctl that will copy in 4 bytes of
    user data on entry, and copy out 4 bytes back out on exit. The argument
    that you supply to the ioctl(2) must be a pointer to a 4 byte word that
    you want to copy. This probably isn't what you want. Based on your
    code snippets, you want:

    #define IOCTL_GET_B _IOW("F", 127, unsigned short)

    static int my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int
    flag, struct thread *td)
    {
            unsigned short data;
    [...]

            case IOCTL_GET_B:
                    *(unsigned short *)arg = data;
                    break;
    [...]

    Similar code will work for all integral types, as well as simple
    structures. The generic ioctl layer will handle all of the copying
    magic for you. Copying compound structures (ones that have pointers
    to other data that you also want to copy) require explicit copyin
    or copyout operations on the pointers that are embedded into the
    struct. Likewise, copying arbitrary data that isn't a structure or
    integral type (like an array) also requires an explicit copy operation.
    You could do something like the following:

    struct mysubdata {
            int foo;
            int bar;
    };

    struct mystruct {
            struct mysubdata *msd;
    };

    #define IOCTL_SET_COMPOUNT_STRUCT _IOR("F", 123, struct mystruct)
    #define IOCTL_SET_BIGDATA _IO("F", 124")

    static int my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int
    flag, struct thread *td)
    {
            struct mystruct *ms;
            struct mysubdata msd;
            char *bigdata *bd;

    [...]

            case IOCTL_SET_COMPOUNT_STRUCT:
                    ms = *(struct mystruct *)arg;
                    copyin(ms->msd, &msd, sizeof(struct mysubdata));
                    break;
            case IOCTL_SET_BIGDATA:
                    bd = malloc(65536, M_DEVBUF, M_WAITOK);
                    copyin(arg, bd, 65536);
                    break;
    [...]

    Note that the BIGDATA ioctl doesn't copy in anything on its own. For
    ioctls like this, it's often convenient to pass a structure anyway that
    contains the size of the data to be copied in and a pointer to the data,
    like so:

    struct mybigdata {
            int datasize;
            char *bigdata;
    }

    #define IOCTL_SET_BIGDATA _IOR("B", 123, struct mybigdata)

            case IOCTL_GET_BIGDATA:
                    mbd = *(struct mybigdata *)arg;
                    bd = malloc(mbd->datasize, M_DEVBUF, M_WAITOK);
                    copyin(mbd->bigdata, bd, mbd->datasize);
                    break;

    Does this make sense? Fell free to contact me with questions on this or
    anything else.

    Scott

    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


  • Next message: Scott Long: "Re: how to use the function copyout()"

    Relevant Pages

    • Re: how to use the function copyout()
      ... > flag, struct thread *td) ... The generic ioctl layer will handle all of the copying ... > contains the size of the data to be copied in and a pointer to the data, ...
      (freebsd-hackers)
    • Re: Another spinoza challenge
      ... You should test against the int type's limits: ... typedef struct complex ... a pointer to an integer ... A macro is preferable because it is replaced by inline code, ...
      (comp.lang.c)
    • Re: how to store list of varying types
      ... represent that with those in the struct definitions? ... pointer null, and the second one the CString object. ... then have to finish constructing the packet by copying the two data objects ... start with an upper-case letter (so, I would use DataElement ...
      (microsoft.public.vc.mfc)
    • Re: N1298 - try/finally for C
      ... Do you mean that "struct throwInfo" should be optional? ... that exception handling would be supported only on implementations ... If the standard mandates an integer as throw argument, ... should be an integer wide enough to encode a pointer if necessary. ...
      (comp.std.c)
    • Re: [RFC][PATCH 1/4] cgroup: support per cgroup subsys state ID (CSS ID)
      ... Patch for Per-CSS(Cgroup Subsys State) ID and private hierarchy code. ... This patch attaches unique ID to each css and provides following. ... returns pointer to struct cgroup_subysys_state of id. ... using a pointer introduces no such restriction. ...
      (Linux-Kernel)