I've created a node in /dev
by following the tutorial here (chardev.c), I tried to access the device in /dev/chardev
I created by using the following code :
#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");
prin开发者_StackOverflowtf("error closing device, fd = %d, err_save = %d \n", fd,err_save);
}
else
{printf("Device closed\n");}
return 0;
}
successful result:
Device opened
Device read successful : I already told you 7 times Hello world!
w�0 ����
Device closed
However, when memset(receive_buff, 0, sizeof(receive_buff));
is uncommented, I get the following:
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
Question: How does the additional memset()
causes the open()
to fail ?
open
takes an integer as the second parameter (you're getting it confused with fopen
). Your open
line should be:
fd = open("/dev/chardev", O_RDWR);
The reason it works or fails as code is added and removed has to to with the unpredictable value of the address of "rw"
, which could happen to be a valid value for open
when memset
is removed.
You need to pass an integer in the second parameter of open
, In your case it is O_RDWR
. The call should be:
fd = open ("/dev/chardev", O_RDWR);
Read manual: man 2 open
. Link: http://linux.die.net/man/2/open
UPDATE
You incorrectly check for read errors. Your code:
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);
}
If there is a read error read
call will return -1
therefore you should check the return value of read
and not the fd
. Make it:
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);
}
Your code runs correctly because the second parameter is simply an integer with its bit values set, which has specific interpretation. You pass an address (the base address of the string in the loaded executable), which is also an integer, and has some specific fields set and some unset. It is impossible to tell that if the bits were set by correctly ORing the flags or was a random integer which happens to have specific bits set. Therefore the function will interpret the random integer by checking which bit is set or not and work as per the interpretation assigned to each bit.
Also when reading from the file you do not check if the read was successful. If in case the random integer happens to have the correct bits for reading the file set, then it will read correctly.
Either your compiler isn't warning you about things it should, or you're ignoring the warnings it does give you.
Others have already told you that open()
's second argument is an int; passing a string literal is incorrect.
The open(2)
man page says that you need:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
Your compiler should have at least warned you that there's no visible declaration for the open()
function. Hmm, I just checked; I'm disappointed to see that gcc doesn't do this by default. (In C99, calling a function with no visible declaration is a constraint violations, but most compilers don't support C99 by default, if at all.)
You're probably using gcc. Enable more warnings (start with -Wall -Wextra
) and pay attention to what the compiler tells you. And read the man pages for any functions you use to see what headers are required.
精彩评论