linux - kid3 - Pasar struct al controlador del dispositivo a través de IOCTL
editar tags mp3 linux (1)
Estoy tratando de pasar una estructura desde el espacio de usuario al espacio del kernel. He estado intentando durante muchas horas y no está funcionando. Esto es lo que he hecho hasta ahora ...
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;
}
Tengo problemas para definir la estructura. ¿Cuál es la forma correcta de definirlo? Quiero tener int pIDs [SIZE]. ¿Los int * pID lo harán (en el espacio de usuario se define como pIDs [SIZE])?
EDITAR:
Con el cambio anterior, ¿recibo este error? error: expresión esperada antes de ''struct'' alguna idea?
Hay dos variantes de la estructura en su pregunta.
struct mesg1{
int *pIDs;
int niceVal;
};
struct mesg2{
int pIDs[SIZE];
int niceVal;
};
Ellos son diferentes; en el caso de mesg1
tiene puntero a la matriz int (que está fuera de la estructura). En otro caso ( mesg2
) hay una matriz int dentro de la estructura.
Si su TAMAÑO es fijo (en API de su módulo, el mismo valor utilizado en usuario y kernel-espacio), puede usar la segunda variante ( mesg2
).
Para usar la primera variante de estructura ( mesg1
), puede agregar el size
campo a la estructura misma, como:
struct mesg1{
int pIDs_size;
int *pIDs;
int niceVal;
};
y llénelo con la cuenta de enteros, apuntada por *pIDs
.
PD: Y por favor, nunca use estructuras con arreglos de tamaño variable en el medio de la estructura (también conocido como VLAIS). Es una extensión propietaria, extraña, defectuosa y no documentada del lenguaje C por el compilador de GCC. Solo el último campo de struct puede ser una matriz con tamaño variable (VLA) de acuerdo con el estándar internacional C. Algunos ejemplos aquí: 1 2
PPS:
Puedes declarar que estás estructurando con VLA (si solo hay una única matriz con tamaño variable):
struct mesg2{
int niceVal;
int pIDs[];
};
pero debe tener cuidado al asignar memoria para dicha estructura con VLA