0

我按照此处/dev的教程(chardev.c)创建了一个节点,我尝试/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()失败?

4

3 回答 3

5

open接受一个整数作为第二个参数(你把它和 混淆了fopen)。你的open行应该是:

fd = open("/dev/chardev", O_RDWR);

添加和删​​除代码时它工作或失败的原因必须与地址的不可预测值有关,这可能恰好是何时删除"rw"的有效值。openmemset

于 2011-09-07T03:40:10.750 回答
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);
}

您的代码运行正确,因为第二个参数只是一个设置了位值的整数,它具有特定的解释。您传递一个地址(加载的可执行文件中字符串的基地址),它也是一个整数,并且设置了一些特定的字段和一些未设置的字段。无法判断这些位是通过正确地 ORing 标志设置的,还是碰巧设置了特定位的随机整数。因此,该函数将通过检查是否设置了哪个位来解释随机整数,并根据分配给每个位的解释工作。

此外,从文件中读取时,您不会检查读取是否成功。如果随机整数恰好具有读取文件集的正确位,那么它将正确读取。

于 2011-09-07T03:44:52.510 回答
1

要么你的编译器没有警告你它应该做的事情,要么你忽略了它给你的警告。

其他人已经告诉过你open()' 的第二个参数是一个 int;传递字符串文字是不正确的。

open(2)手册页说您需要:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

您的编译器至少应该open()警告您该函数没有可见的声明。嗯,我刚刚检查过;我很失望地看到 gcc 默认不这样做。(在 C99 中,调用没有可见声明的函数是违反约束的,但大多数编译器默认不支持 C99,如果有的话。)

您可能正在使用 gcc。启用更多警告(以 开头-Wall -Wextra)并注意编译器告诉您的内容。并阅读您使用的任何函数的手册页,以查看需要哪些标题。

于 2011-09-07T04:16:09.437 回答