0

私はそのような機能を持っています

static ssize_t read_mydevice(struct file *filp, char* buf, size_t count, loff_t* ppos) {

 char *text = "Device is empty\n";
    int len = strlen(text);


    if (*ppos != 0)
            return 0;


    if(count>bytesindev) count=bytesindev;
    if(bytesindev==0) {

        if (copy_to_user(buf, text, len))
                 return -EINVAL;
     } else {
        while(count>0) {
        if (copy_to_user(buf++, msg_Ptr, (unsigned long) 1)) {
                 return -EINVAL;
                } else {
                    strcpy(msg_Ptr, (msg_Ptr+1));
                    bytesindev-=1;
                    *(msg_Ptr+bytesindev) = '\0';
                }
                count-=1;
                printk(KERN_INFO "%d\n", count);
            }
            printk(KERN_INFO "%s\n", buf);
     }
    /*
     * Tell the user how much data we wrote.
     */
    *ppos = len;

    return len;

 }

問題は、ユーザーがメッセージ全体を取得できないことです。それは常に最初の 13 ~ 16 の兆候であり、ループが何度も行われることになっています。最初、copy_to_user に渡される 3 番目の引数はメッセージ全体の長さでしたが、このソリューションも適切に機能しませんでした。何か案は?この関数は、ユーザーが要求したバッファの一部 (バッファに最初に書き込まれたバイト数、FIFO のようなもの) をユーザーに提供する必要があります。データは、以前にデバイスに送信されている必要があります。それは書くための関数です:

static ssize_t
write_mydevice(struct file *filp, const char *buff, size_t len, loff_t * off)
{
if(bytesindev+len>limit) {
    if(limit-bytesindev<=0) {
        printk(KERN_ALERT "Device is full.\n");
            return -EINVAL;
    } else {
        printk(KERN_INFO "Device almost full.\n");
        strncat(msg_Ptr, buff, limit-bytesindev);
        bytesindev+=limit-bytesindev;
        return limit-bytesindev;
    }
} else {
    //printk(KERN_INFO "Device working\n");
    strncat(msg_Ptr, buff, len);
    bytesindev+=len;
    return len;
} 
}
4

2 に答える 2

2

コードの意図は完全にはわかりませんが、少なくとも 1 つの問題があります。strcpy 呼び出しは無効です。オーバーラップするバッファでの動作は保証されていません:

strcpy(msg_Ptr, (msg_Ptr+1));

意図した結果になるかもしれませんが、未定義の動作です。strcpyを参照

于 2012-06-15T16:54:31.397 に答える
0

問題は、読み取り関数が間違った値を返すことでした。送信されたメッセージの長さではなく、常にテキストの長さを返します。

于 2012-06-16T08:43:18.037 に答える