我已按照教程here (chardev.c)在/dev
中创建了一个节点,我尝试使用以下代码访问我创建的/dev/chardev
中的设备:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h> //perror(), errno
#include <string.h>
#define RSIZE 50
int main()
{
int fd,err_save;
char receive_buff[RSIZE];
//open device and check for error msg
fd = open("/dev/chardev", "rw");
err_save = errno;
if (fd < 0)
{
perror("open perror");
printf("error opening device, fd = %d, err_save = %d \n", fd,err_save);
}
else
{printf("Device opened\n");}
//read device and check for error msg
//memset(receive_buff, 0, sizeof(receive_buff)); //<--- strange
read(fd, receive_buff, RSIZE);
err_save = errno;
if (fd < 0)
{
perror("read perror");
printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
}
else
{
printf("Device read successful : %s\n",receive_buff);}
//close device and check for error msg
fd = close(fd);
err_save = errno;
if (fd < 0)
{
perror("close perror");
printf("error closing device, fd = %d, err_save = %d \n", fd,err_save);
}
else
{printf("Device closed\n");}
return 0;
}
成功的结果:
Device opened
Device read successful : I already told you 7 times Hello world!
w�0 ����
Device closed
但是,当memset(receive_buff, 0, sizeof(receive_buff));
取消注释时,我会收到以下信息:
open perror: File exists
error opening device, fd = -1, err_save = 17
read perror: Bad file descriptor
error reading device, fd = -1, err_save = 9
close perror: Bad file descriptor
error closing device, fd = -1, err_save = 9
问题:额外的memset()
如何导致open()
失败?
答案 0 :(得分:5)
open
将整数作为第二个参数(您将其与fopen
混淆)。您的open
行应为:
fd = open("/dev/chardev", O_RDWR);
在添加和删除代码时它工作或失败的原因必须是"rw"
地址的不可预测值,这可能恰好是open
memset
的有效值删除。
答案 1 :(得分:2)
您需要在open
的第二个参数中传递一个整数,在您的情况下,它是O_RDWR
。电话应该是:
fd = open ("/dev/chardev", O_RDWR);
阅读手册:man 2 open
。链接:http://linux.die.net/man/2/open
<强>更新强>
您错误地检查了读取错误。你的代码:
read(fd, receive_buff, RSIZE);
err_save = errno;
if (fd < 0)
{
perror("read perror");
printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
}
如果读取错误read
,则调用将返回-1
,因此您应检查read
的返回值,而不是fd
。成功:
read_bytes = read(fd, receive_buff, RSIZE);
err_save = errno;
if (read_bytes < 0)
{
perror("read perror");
printf("error reading device, fd = %d, err_save = %d \n", fd,err_save);
}
您的代码正确运行,因为第二个参数只是一个整数,其位值设置,具有特定的解释。您传递一个地址(加载的可执行文件中字符串的基址),它也是一个整数,并且设置了一些特定字段,一些未设置。如果通过对标志进行正确的OR运算来设置这些位是不可能的,或者是一个恰好具有特定位的随机整数。因此,该函数将通过检查是否设置了哪个位来解释随机整数,并按照分配给每个位的解释工作。
同时从文件中读取时,不检查读取是否成功。如果随机整数恰好具有用于读取文件集的正确位,则它将正确读取。
答案 2 :(得分:1)
要么你的编译器没有警告你它应该做的事情,要么你忽略了它给你的警告。
其他人已经告诉过你open()
的第二个参数是int;传递字符串文字不正确。
open(2)
手册页说明您需要:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
您的编译器应该至少警告过您open()
函数没有可见的声明。嗯,我刚检查过;我很失望地看到gcc默认不这样做。 (在C99中,调用没有可见声明的函数是违反约束的,但是大多数编译器默认情况下不支持C99,如果有的话。)
你可能正在使用gcc。启用更多警告(以-Wall -Wextra
开头)并注意编译器告诉您的内容。并阅读手册页,了解您用于查看所需标题的任何函数。