2015-04-10 1 views
2

Я пишу простой драйвер.Почему мой вызов IOCTL работает с copy_from_user, но не с get_user?

Здесь я учусь ioctl звонки, они отработаны в copy_to_user и copy_from_user части, но не в get_user и put_user части. Он работает, если я отправляю некоторые данные этими функциями; Проблема в том, когда я должен просто передать целое или символьное значение:

long ioctl_funcs(struct file *filp,unsigned int cmd, unsigned long arg) 
{ 

int ret=0; 
int len=10; 
char val='d'; 
char valplusone='d'; 

switch(cmd) { 

case IOCTL_HELLO: 
printk(KERN_INFO "Hello ioctl world"); 

case READ_IOCTL:  
     copy_to_user((char *)arg, buf, 200); 
    //works fine 
     break; 

case WRITE_IOCTL: 
     copy_from_user(buf, (char *)arg, len); 
     //works fine 
     buf[6]=' '; 
     buf[7]='t'; 
     buf[8]='o'; 
     buf[9]='o'; 
     buf[10]='\n';  
     break; 

case READ_ONE: 
     printk(KERN_ALERT "valplusone (put user)is %c \n",valplusone); 
     put_user(valplusone,(char __user *) arg); 

    //problem  
break; 

case WRITE_ONE: 
     if(access_ok(VERIFY_WRITE,(void*)arg,sizeof(char))!=1) 
{ 
printk(KERN_ALERT "access not ok\n"); 
return -EFAULT; 
} 
else{ 

     printk(KERN_ALERT "****arg %l",arg); 
     get_user(val,(char __user *)arg); 
valplusone='t'; 
printk(KERN_ALERT "val (get user)is %c\n",val); 
break; 
} 

} 

return ret; 

} 

в вышеуказанной части она отлично работает для копии пользовательской копии от пользователя, но не в случае get_user put_user теперь на стороне пользователя код :

char sent,received; 
if(retval=ioctl(fd, WRITE_ONE, sent) < 0) 
     perror("third ioctl"); 
printf("you sent %c\nretval is %d\n",sent,retval); 

if(ioctl(fd, READ_ONE, received) < 0) 
     perror("fourth ioctl"); 
printf("you got %c",received); 
----------------------------------- 

ответ

2

Необходимо передать адреса, а не значения. Пример:

if (ioctl(fd, READ_ONE, &received) < 0) 
… 
Смежные вопросы