Passing struct to device driver through IOCTL

假装没事ソ 提交于 2019-12-10 22:18:08

问题


I am trying to pass a struct from user space to kernel space. I had been trying for many hours and it isn't working. Here is what I have done so far..

int device_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg){

int ret, SIZE;


switch(cmd){

    case PASS_STRUCT_ARRAY_SIZE:

        SIZE = (int *)arg;
        if(ret < 0){
            printk("Error in PASS_STRUCT_ARRAY_SIZE\n");
            return -1;  
        }
        printk("Struct Array Size : %d\n",SIZE);
        break;

    case PASS_STRUCT:


        struct mesg{
            int pIDs[SIZE];
            int niceVal;
        };

        struct mesg data;

        ret = copy_from_user(&data, arg, sizeof(*data));
        if(ret < 0){
            printk("PASS_STRUCT\n");
            return -1;  
        }

        printk("Message PASS_STRUCT : %d\n",data.niceVal);
        break;

    default :
        return -ENOTTY;
}

return 0;
  }

I have trouble defining the struct. What is the correct way to define it? I want to have int pIDs[SIZE]. Will int *pIDs do it(in user space it is defined like pIDs[SIZE])?

EDIT:

With the above change I get this error? error: expected expression before 'struct' any ideas?


回答1:


There are two variants of the structure in your question.

 struct mesg1{
  int *pIDs;
  int niceVal;
 };

 struct mesg2{
  int pIDs[SIZE];
  int niceVal;
 };

They are different; in case of mesg1 you has pointer to int array (which is outside the struct). In other case (mesg2) there is int array inside the struct.

If your SIZE is fixed (in API of your module; the same value used in user- and kernel- space), you can use second variant (mesg2).

To use first variant of structure (mesg1) you may add field size to the structure itself, like:

 struct mesg1{
  int pIDs_size;
  int *pIDs;
  int niceVal;
 };

and fill it with count of ints, pointed by *pIDs.

PS: And please, never use structures with variable-sized arrays in the middle of the struct (aka VLAIS). This is proprietary, wierd, buggy and non-documented extension to C language by GCC compiler. Only last field of struct can be array with variable size (VLA) according to international C standard. Some examples here: 1 2

PPS:

You can declare you struct with VLA (if there is only single array with variable size):

 struct mesg2{
  int niceVal;
  int pIDs[];
 };

but you should be careful when allocating memory for such struct with VLA



来源:https://stackoverflow.com/questions/12130689/passing-struct-to-device-driver-through-ioctl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!