2009-12-05 122 views
1

在内核空间,我有以下几点:从内核空间复制char *的二维数组到用户空间?

char * myData[MAX_BUF_SIZE][2]; 

我需要定义一个内核方法并将这些数据复制到用户空间,所以我将如何去定义这个方法?我有以下,但我不太确定我在做什么。

asmlinkage int sys_get_my_data(char __user ***data, int rowLen, int bufferSize) { 
    if (rowLen < 1 || bufferSize < 1 || rowLen > MAX_BUF_SIZE || bufferSize 
      > MAX_BUF_SIZE) { 
     return -1; 
    } 

    if(copy_to_user(data, myData, rowLen * bufferSize * dataCounter * 2)) 
    { 
     printk(KERN_EMERG "Copy to user failure for get all minifiles\n"); 
     return -1; 
    } 

    return 0; 
} 

帮助?

+0

一切都指向以空字符结尾的字符串。真的,myData表示相互对应的两个值。也就是说,它包含对数据为 myData [i] [0]和myData [i] [1],它们都是以空字符结尾的字符串。我不害怕在这里浪费数据操作,所以如果我可以复制整块固定大小的内存,那很好。 – 2009-12-05 22:38:54

+0

我不完全明白你的问题,你已经定义了一个新的系统调用权吗? copy_to_user将数据从内核指针复制到用户空间缓冲区中。 – 2009-12-05 22:39:55

+0

fileDataMap来自哪里?不应该是我的数据? – mrduclaw 2009-12-05 22:46:54

回答

2

根据您的评论,这些char *值指向以nul结尾的字符串。

现在,您不能仅仅将整个fileDataMap内存块复制到用户空间 - 这只会为用户空间提供一堆指向内核空间的char *值,因此它实际上无法使用它们。你需要将字符串本身复制到用户空间,而不仅仅是指针(这是一个“深层复制”)。

现在,有几种方法可以解决这个问题。最简单的方法是将所有字符串一个接一个地打包成用户空间中的大数组char。它再向上到用户空间通过块扫描,重建指针:

asmlinkage int sys_get_my_data(char __user *data, size_t bufferSize) 
{ 
    size_t i; 

    for (i = 0; i < MAX_BUF_SIZE; i++) { 
     size_t s0_len = strlen(fileDataMap[i][0]) + 1; 
     size_t s1_len = strlen(fileDataMap[i][1]) + 1; 

     if (s0_len + s1_len > bufferSize) { 
      return -ENOSPC; 
     } 

     if (copy_to_user(data, fileDataMap[i][0], s0_len)) { 
      return -EINVAL; 
     } 

     data += s0_len; 
     bufferSize -= s0_len; 

     if (copy_to_user(data, fileDataMap[i][1], s1_len)) { 
      return -EINVAL; 
     } 

     data += s1_len; 
     bufferSize -= s1_len; 
    } 

    return 0; 
} 

这是否有总是MAX_BUF_SIZE字符串对只会工作,因为用户空间将需要知道它是多少字符串期待接收以便能够安全地扫描它们。如果情况并非如此,则必须以某种方式返回该信息 - 也许系统调用的返回值可能是字符串对的数量?

如果你想内核重建用户空间中的指针表,你必须像上面那样复制字符串,然后填写指针表 - 用户空间必须通过两个缓冲区,一个用于字符串本身,一个为指针。

相关问题