我正在尝试做一些初学内核模块/用户级程序通信。我之前得到了使用fdopen()
效果很好的建议,但我发现我需要使用open()
,read()
和write()
代替。我阅读了这些的手册页,并认为我正确地将fopen,fgets,fput转换为这些并且我的程序编译,但我没有得到所需的输出。
我有一个计时器,如果我输入./userprogram -s (int) (name)
,例如./userprogram -s 5 hello
,5秒后,它将通过与我的内核模块通信将hello
打印到控制台。在我切换到这些新功能之后,它会打印/lib/ld-uClibc.so.0
(并且无论如何都要等待~5秒)。我是否还需要更改内核级代码的工作方式?我以为我只能更改用户级程序,内核模块将继续像以前一样工作。这是我尝试用原始代码注释掉的内容:
// 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);
}
任何建议都表示赞赏。
答案 0 :(得分:4)
[我]以为我正确地将fopen,fgets,fput转换成了这些
......但你错了。没有单行write()
- 相当于fputs()
,没有单行read()
- 相当于fgets()
。当您使用低级read()
和write()
时,基于流的I / O函数可以完成许多工作。
有些不同之处是:
read()
不提供字符串终止。你必须自己做。write()
不注意字符串终止。如果你想让它停在字符串终止符,那么你必须通过你要求它传输的字节数来控制它。read()
和write()
都不能保证传输一次调用中请求的完整字节数。如果要传输特定数量的字节,则必须准备循环。read()
不会自动停止任何特定字符,包括换行符read()
和write()
,那么你必须自己处理它(但这些功能非常适合它)。但是,在您的特定情况下,您还提交了语义错误。 write()
和read()
的第三个参数是要传输的最大字节数 - 通常是缓冲区的大小 - 但sizeof(ptr)
是指针本身的大小,而不是它指向的空间大小。
答案 1 :(得分:3)
sizeof(ptr)
可能是4或8(即sizeof(char *)
),而不是您要写入的数据的长度。
构建数据的方式非常繁琐。为什么不使用单个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那么甜美和简洁?