亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1554 | 回復(fù): 0
打印 上一主題 下一主題

ioctl函數(shù)總是搶先調(diào)用,求助 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2010-05-29 18:02 |只看該作者 |倒序瀏覽
大家好,我照LDD3寫了一個驅(qū)動,然后寫了一個用戶空間應(yīng)用去測試,然后就出現(xiàn)了一個很奇怪的問題,主要是針對ioctl的。
我的驅(qū)動是一個虛擬的,里面是一個鏈接表,寫操作就向鏈表填加項,讀就是讀鏈表字符。ioctl的SCULL_IOCSET是向鏈表頭加一個項,SCULL_IOCGET讀鏈表每一個字符。SCULL_IOCCLEAR清空鏈表。

用戶空間應(yīng)用先是一個write函數(shù),寫26個英文字母,然后讀出來,這都沒出錯,但是后來我讀之后加入ioctl函數(shù),然后問題就發(fā)生了。我發(fā)現(xiàn)ioctl函數(shù)總是先于write和read函數(shù)被執(zhí)行,這是為什么呢?
shell執(zhí)行結(jié)果如下:

[root@mini2440 /]# ./ioctl
Writting to scull0 :abcdefghijklmnopqrstuvwxyz...
cmd is 0x6b01,SCULL_IOCSET is 0x40046b02       //
cmd is 0x40016b02,SCULL_IOCSET is 0x40046b02//
cmd is 0x80016b03,SCULL_IOCSET is 0x40046b02//這三句是內(nèi)核驅(qū)動模塊中ioctl函數(shù)的打印結(jié)果。
Write OP Successful! 28 characters written.
Read from scull0 :abcdefghijklmnopqrstuvwxyz,OP successful!
Starting ioctl!......................................................
After clear ioctl:
set the first value 'm',then it reads:

What I get is :

求大俠幫解釋一下,如果需要的話,下面是我的代碼。先行謝了。
我的用戶空間程序代碼:
  1. #include <fcntl.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <linux/ioctl.h>
  5. #define SCULL_IOC_MAGIC  'k'  
  6. #define SCULL_IOCMAXCDMNR 3
  7. #define SCULL_IOCCLEAR  _IO(SCULL_IOC_MAGIC,1)
  8. #define SCULL_IOCSET  _IOW(SCULL_IOC_MAGIC,2,char)
  9. #define SCULL_IOCGET _IOR(SCULL_IOC_MAGIC,3,char)

  10. int  main()
  11. {
  12.   int ret;
  13.   int i;
  14.   int fd=open("/dev/scull0",O_RDWR);
  15.   char buf[28]="abcdefghijklmnopqrstuvwxyz";
  16.   char buff[28];
  17.   
  18.   printf("Writting to scull0 :%s...\n",buf);
  19.   
  20.   if(sizeof(buf)==write(fd,buf,sizeof(buf)))
  21.     printf("Write OP Successful! %d characters written.\n",sizeof(buf));
  22.   else
  23.     printf("Write error!\n");

  24.   if(sizeof(buf)==read(fd,buff,sizeof(buf)))
  25.     printf("Read from scull0 :%s,OP successful!\n",buff);
  26.   else
  27.     printf("Read error!\n");




  28.   
  29.   printf("Starting ioctl!......................................................\n");
  30.   ioctl(fd,SCULL_IOCCLEAR);
  31.   strcpy(buff,"");
  32.   read(fd,buff,sizeof(buf));
  33.   printf("After clear ioctl:%s\n",buff);
  34.   
  35.   buf[0]='m';
  36.   ioctl(fd,SCULL_IOCSET,&buf[0]);
  37.   read(fd,buff,sizeof(buf));
  38.   printf("set the first value 'm',then it reads:\n");
  39.   printf("%s\n",buff);
  40.   
  41.   
  42.   buff[0]=0;
  43.   ioctl(fd,SCULL_IOCGET,buff[0]);
  44.   printf("What I get is :%c\n",buff[0]);
  45.   
  46.   

  47.   
  48.   return 0;
  49. }
復(fù)制代碼
我的驅(qū)動程序代碼:
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/moduleparam.h>
  4. #include <linux/kdev_t.h>
  5. #include <linux/fs.h>
  6. #include <linux/cdev.h>
  7. #include <asm/uaccess.h>
  8. #include <linux/proc_fs.h>
  9. //#include <asm/semaphore.h>

  10. MODULE_LICENSE("Dual BSD/GPL");
  11. #define SCULL_USE_PROC
  12. #define MAX_PROC_IN 30
  13. #define SCULL_IOC_MAGIC  'k'  
  14. #define SCULL_IOCMAXCDMNR 3
  15. #define SCULL_IOCCLEAR  _IO(SCULL_IOC_MAGIC,1)
  16. #define SCULL_IOCSET  _IOW(SCULL_IOC_MAGIC,2,int)
  17. #define SCULL_IOCGET _IOR(SCULL_IOC_MAGIC,3,int)

  18. static int major=0;
  19. static int minor=0;
  20. static int  devCount=4;
  21. static char proc_in[MAX_PROC_IN]="";

  22. struct scull_buf{
  23.   char value;
  24.   struct scull_buf * next;
  25. };
  26. struct scull_dev{
  27.   struct cdev cdev;
  28.   struct  scull_buf  *bufHead;
  29.   struct semaphore sem;
  30. };

  31. struct scull_dev * scull;

  32. int scull_open(struct inode * inode ,struct file *filp)
  33. {
  34.   struct scull_dev *dev;
  35.   dev=container_of(inode->i_cdev,struct scull_dev,cdev);
  36.   filp->private_data=dev;//for later use in other methods.
  37.   return 0;
  38. }

  39. int scull_release(struct inode *inode,struct file *filp)
  40. {
  41.   return 0;
  42. }

  43. ssize_t scull_write(struct file *filp,const char __user *buff,size_t count,loff_t *offp)
  44. {
  45.   int i;
  46.   struct scull_dev * dev=filp->private_data;
  47.   struct scull_buf *bptr=NULL;

  48.   if (down_interruptible (&dev->sem))
  49.                 return -ERESTARTSYS;
  50.   
  51.   for(i=0;i<count;i++)
  52.   {
  53.     struct scull_buf *tmp=kmalloc(sizeof(struct scull_buf),GFP_KERNEL);
  54.    
  55.     if(!copy_from_user(&tmp->value,buff++,1))
  56.     {
  57.       tmp->next=NULL;
  58.       if(i==0)
  59.       {
  60.         dev->bufHead=tmp;
  61.         bptr=tmp;
  62.       }
  63.       else
  64.       {
  65.         bptr->next=tmp;
  66.         bptr=tmp;
  67.       }
  68.     }
  69.     else
  70.     {
  71.       printk(KERN_ALERT"Copy from user failed!\n");
  72.       return -EFAULT;
  73.     }
  74.   }

  75. up (&dev->sem);
  76. return count;
  77.   
  78. }

  79. ssize_t scull_read(struct file *filp,char __user *buff,size_t count,loff_t * offp)
  80. {
  81.   int i;
  82.   struct scull_dev * dev=filp->private_data;
  83.   struct scull_buf *bptr=dev->bufHead;
  84.   
  85.   if(down_interruptible(&dev->sem))
  86.     return -ERESTARTSYS;

  87.   for(i=0;i<count&&bptr!=NULL;i++)
  88.   {
  89.     if(!copy_to_user(buff++,&(bptr->value),1)==1)
  90.       bptr=bptr->next;
  91.     else
  92.     {
  93.       printk(KERN_INFO"Copy to user failed!");
  94.     }
  95.   }
  96.   up(&dev->sem);
  97.   return count;
  98. }

  99. int scull_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
  100. {
  101.   int err=0,ret=0;
  102.   struct scull_dev * dev=filp->private_data;
  103.   struct scull_buf * buf=dev->bufHead;

  104.   if(_IOC_TYPE(cmd)!=SCULL_IOC_MAGIC) return -ENOTTY;
  105.   if(_IOC_NR(cmd)>SCULL_IOCMAXCDMNR) return -ENOTTY;

  106. /*
  107.   if(_IOC_DIR(cmd)&_IOC_READ)
  108.     err=!access_ok(VERIFY_WRITE,(void __user *)arg ,_IOC_SIZE(cmd));
  109.   else if(_IOC_DIR(cmd)&_IOC_WRITE)
  110.     err=!access_ok(VERIFY_READ,(void __user *)arg, _IOC_SIZE(cmd));
  111.   if(err) return -ENOTTY;*/
  112. printk("cmd is 0x%x,SCULL_IOCSET is 0x%x\n",cmd,SCULL_IOCSET);
  113.   

  114.   switch (cmd)
  115.   {
  116.     case SCULL_IOCCLEAR:
  117.       while(buf!=NULL)
  118.       {
  119.         struct scull_buf * b;
  120.         b=buf->next;
  121.         kfree(buf);
  122.         buf=b;
  123.       }
  124.       break;
  125.       
  126.     case SCULL_IOCSET:
  127.     {
  128.       struct scull_buf *b;
  129.      // while(buf!=NULL&&buf->value!=0)
  130.         //buf=buf->next;
  131.      // b=buf->next;
  132.       b=kmalloc(sizeof(struct scull_buf),GFP_KERNEL);
  133.       ret=__get_user(b->value,(char __user *)arg);
  134.       b->next=buf->next;
  135.       kfree(buf);
  136.       buf=b;
  137.       printk("%c........",b->value);
  138.     }
  139.     break;
  140.     case SCULL_IOCGET:
  141.     {
  142.       ret=__put_user(buf->value,(char __user *)arg);
  143.     }
  144.     break;
  145.     default:
  146.       return -ENOTTY;
  147.   }
  148.   dev->bufHead=buf;
  149.   return ret;
  150. }
  151.       
  152.       
  153.       
  154. #ifdef SCULL_USE_PROC
  155. static int proc_scull_read(char * buf,char **start,off_t offset,int len,int *eof,void *data)
  156. {
  157.   int i,count=0;
  158.   struct scull_buf * buff;
  159.   for(i=0;i<devCount;i++)
  160.   {
  161.     if((scull+i)->bufHead==NULL)
  162.       count+=sprintf(buf+count,"scull%d is empty.\n",i);
  163.     else
  164.     {
  165.       buff=(scull+i)->bufHead;
  166.       count+=sprintf(buf+count,"scull%d is :\n",i);
  167.       while(buff!=NULL)
  168.       {
  169.         count+=sprintf(buf+count,"%c",buff->value);
  170.         buff=buff->next;
  171.       }
  172.       count+=sprintf(buf+count,"\n");
  173.     }
  174.   }
  175.   
  176.   count+=sprintf(buf+count,"proc_in:%s",proc_in);
  177.   return count;
  178. }

  179. static ssize_t proc_scull_write(struct file *filp,const char __user * buf,unsigned long len,void *data)
  180. {
  181.   if(len<=MAX_PROC_IN)       
  182.     if(!copy_from_user(proc_in,buf,len))
  183.       printk(KERN_INFO"Write done!\n");
  184.   return len;
  185. }


  186. static struct proc_dir_entry * proc_scull_entry;   
  187. #endif

  188. struct file_operations scull_ops={
  189.   .owner=THIS_MODULE,
  190.   .open=scull_open,
  191.   .release=scull_release,
  192.   .write= scull_write,
  193.   .read=scull_read,
  194.   .ioctl=scull_ioctl,
  195. };

  196. static void scull_setup_cdev(struct scull_dev *dev,int index)
  197. {
  198.   int err;
  199.   dev_t devno=MKDEV(major,minor+index);
  200.   cdev_init(&dev->cdev,&scull_ops);
  201.   dev->cdev.owner=THIS_MODULE;
  202.   dev->bufHead=NULL;
  203.   //dev->cdev.ops=&scull_fops;//don't know about what it is like in other version of kernel,but in 2.6.30,this is not at all neccessary.
  204.   //it's already done by cdev_init.
  205.   err=cdev_add(&dev->cdev,devno,1);
  206.   /*fail gracefully if need be */
  207.   if(err)
  208.     printk(KERN_NOTICE"Error %d adding scull%d",err,index);
  209. }
  210. static int scull_init(void)
  211. {
  212.   int ret,i;
  213.   static dev_t devno;
  214.     if(major==0)
  215.   {
  216.     ret=alloc_chrdev_region(&devno ,minor,devCount,"scull");
  217.     major=MAJOR(devno);
  218.     minor=MINOR(devno);
  219.   }
  220.   else
  221.   {
  222.     devno=MKDEV(major,minor);
  223.     ret=register_chrdev_region(devno,devCount,"scull");
  224.   }
  225.   if(ret<0)
  226.   {
  227.     printk(KERN_WARNING "scull:can't get major %d\n",major);
  228.     return ret;
  229.   }
  230.   else
  231.      printk(KERN_ALERT"Dev_t registered:%d ,%d\n",major,minor);
  232.   scull=kmalloc(devCount*sizeof(struct scull_dev),GFP_KERNEL);
  233.   if(!scull)
  234.   {
  235.     ret=-ENOMEM;
  236.     printk(KERN_INFO"fail malloc for scull_dev\n");
  237.     goto fail_malloc;
  238.   }
  239.   memset(scull,0,devCount*sizeof(struct scull_dev));
  240.   
  241.   for(i=0;i<devCount;i++)
  242.   {
  243.     scull_setup_cdev(scull+i,i);
  244.     sema_init(&(scull+i)->sem,1);
  245.   }
  246.   
  247. #ifdef SCULL_USE_PROC
  248.   proc_scull_entry=create_proc_entry("scull",0,NULL);
  249.   if(proc_scull_entry)
  250.   {
  251.     proc_scull_entry->read_proc=proc_scull_read;
  252.     proc_scull_entry->write_proc=proc_scull_write;
  253.   }
  254.   else
  255.     printk(KERN_ERR"Proc file scull registration failed!\n");
  256. #endif
  257.   
  258.   fail_malloc:
  259.   unregister_chrdev_region(devno,devCount);
  260.   return 0;
  261. }
  262. static void scull_exit(void)
  263. {
  264.   static dev_t devno;
  265.   int i;
  266. #ifdef SCULL_USE_PROC
  267.   remove_proc_entry("scull",NULL);
  268. #endif
  269.   
  270.   for(i=0;i<devCount;i++)
  271.   {
  272.     cdev_del(&scull[i].cdev);
  273.   }
  274.   kfree(scull);
  275.   unregister_chrdev_region(devno,devCount);
  276. }

  277. module_param(major,int,S_IRUGO);
  278. module_init(scull_init);
  279. module_exit(scull_exit);
復(fù)制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP