简体   繁体   English

我在用read()和write()做错了什么?

[英]What am I doing wrong with read() and write()?

I'm trying to do some beginner kernel module/user level program communications. 我正在尝试进行一些初学者的内核模块/用户级程序通信。 I got the suggestion earlier to use fdopen() which worked well, but I've found out I'm required to use open() , read() and write() instead. 我早些时候建议使用fdopen()效果很好,但是我发现我需要使用open()read()write()来代替。 I read the man pages for these and thought I converted the fopen,fgets,fputs to these correctly and my program compiles, but I'm not getting the desired output. 我阅读了这些手册页,以为我将fopen,fgets,fputs正确地转换为这些,并且我的程序得以编译,但是我没有得到想要的输出。

I have a timer where if I enter ./userprogram -s (int) (name) eg ./userprogram -s 5 hello , after 5 seconds it will print hello to the console by communicating with my kernel module. 我有一个计时器,如果我输入./userprogram -s (int) (name)例如./userprogram -s 5 hello ,则在5秒钟后,它将通过与我的内核模块通信将hello打印到控制台。 After I've switched to these new functions it instead prints /lib/ld-uClibc.so.0 (and seems to wait ~5 seconds regardless now). 在我切换到这些新功能之后,它改为打印/lib/ld-uClibc.so.0 (似乎现在要等待约5秒钟)。 Do I also need to change how my kernel level code works? 我还需要更改内核级代码的工作方式吗? I thought I'd just be able to change the user level program and the kernel module would continue to work as it did before. 我以为我只需要更改用户级别的程序,内核模块就可以像以前一样继续工作。 Here's what I tried wit the original code that worked commented out: 这是我尝试用注释掉的原始代码进行的操作:

// open file
int pFile;
pFile = open("/dev/mytimer", O_RDWR);
if (pFile < 0) {
    fprintf (stderr, "mytimer module isn't loaded\n");
    return 1;
}

// Check if timer set
if (argc >= 4 && strcmp(argv[1], "-s") == 0) {
    lenNum = strlen(argv[2]);
    lenName = strlen(argv[3]);
    char *ptr = malloc(lenNum+lenName+4);
    strncat(ptr, argv[1], 2);//flag
    strncat(ptr," ", 1);
    strncat(ptr, argv[2], lenNum);//timer length
    strncat(ptr," ", 1);
    strncat(ptr, argv[3], lenName);//message

    /* fputs(ptr, pFile); */
    write(pFile, ptr, sizeof(ptr));
    /*
    while (fgets(line, 256, pFile) != NULL) {
        printf("%s", line);
    } */
    while (read(pFile, ptr, sizeof(ptr)) != 0) {
        printf("%s", line);
    }   

Any suggestions are appreciated. 任何建议表示赞赏。

[I] thought I converted the fopen,fgets,fputs to these correctly 我以为我将fopen,fgets,fputs正确地转换为这些

... but you were mistaken. ...但是你弄错了。 There is no one-line write() -based equivalent to fputs() , and no one-line read() -based equivalent to fgets() . 没有基于单行write()的等效于fputs() ,也没有基于单行read()的等效于fgets() The stream-based I/O functions do a lot of work that you have to do yourself when you use low-level read() s and write() s. 当使用低级read()write()时,基于流的I / O函数需要做很多工作。

Some of the differences are: 一些区别是:

  • read() does not supply string termination. read()不提供字符串终止。 You have to do that yourself. 你必须自己做。
  • write() does not pay attention to string termination. write()不注意字符串终止。 If you want it to stop at string terminators then you have to control that via the number of bytes you ask it to transfer. 如果希望它在字符串终止符处停止,则必须通过要求它传输的字节数来控制它。
  • read() and write() are neither one guaranteed to transfer the full number of bytes requested in one call. 不能保证read()write()不能在一个调用中传输请求的全部字节数。 If you want to transfer a specific number of bytes then you have to be prepared to loop. 如果要传输特定数量的字节,则必须准备循环。
  • read() does not automatically stop at any particular character, including newline read()不会自动停在任何特定字符处,包括换行符
  • Most streams provide for buffering, invisibly to you. 大多数流为您提供了无形的缓冲。 If you want to buffer your read() s and write() s then you have to handle it yourself (but those functions are well suited for it). 如果要缓冲read()write()则必须自己处理(但是那些函数非常适合)。

In your particular case, however, you have also committed a semantic error. 但是,在您的特定情况下,您还犯了语义错误。 The third argument to both write() and read() is the the maximum number of bytes to transfer -- often the size of the buffer -- but sizeof(ptr) is the size of your pointer itself, not the size of the space to which it points. write()read()的第三个参数是要传输的最大字节数-通常是缓冲区的大小-但是sizeof(ptr)是指针本身的大小,而不是空间的大小它指向。

sizeof(ptr) is probably 4 or 8 (ie sizeof(char *) ), not the length of the data you want to write. sizeof(ptr)可能是4或8(即sizeof(char *) ),而不是您要写入的数据的长度。

And the way you construct the data is extremely cumbersome. 而且,构造数据的方式非常麻烦。 Why not use a single sprintf() , or, if you have it, asprintf() , which even mallocs the memory: 为什么不使用单个sprintf() ,或者,如果有的话,请使用asprintf() ,它甚至会分配内存:

char *ptr;
int i;

i = asprintf (&ptr, "%s %s %s", argv[1], argv[2], argv[3]);
write (pFile, ptr, i);
free(ptr);

Ain't that sweet and concise? 那不是那么甜蜜和简洁吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM