wangt0907
wangt0907

Reputation: 247

C program of accessing device file don't work

I have seen device file can be accessed directly in Linux and I want to have a try. I have a free disk partition without any file system. My test code is below. I expect to get output read data: 199 when I run the program at the second time. But actually, I get output read data: 0 twice. No errors emerge during the program. I have no idea where is wrong.
Thanks for your time.

Test Code:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main(){
    int num = 0;
    int fd = open("/dev/sda6", O_RDWR);

    if(fd == -1){
        fprintf(stderr, "open device failed, errno : %s(%d) \n", 
            strerror(errno), errno);
        return 1;
    }

    ssize_t ret = read(fd, &num, sizeof(int));
    if(ret != sizeof(int)){
        fprintf(stderr, "read fails, errno : %s(%d) \n", 
            strerror(errno), errno);
        return 1;
    }
    printf("read data: %d\n", num);

    num = 199;
    ret = write(fd, &num, sizeof(int));
    if(ret != sizeof(int)){
        fprintf(stderr, "write fails, errno : %s(%d) \n", 
            strerror(errno), errno);
        return 1;
    }
    close(fd);

    return 0;
}

Upvotes: 2

Views: 1930

Answers (2)

quantummind
quantummind

Reputation: 2136

You do not seek in your program, so what it does: Read the first 4 bytes of the device, then write the second 4 bytes.

Try

lseek(fd,0,SEEK_SET);

before write if you want to write at the beginning of fole.

Upvotes: 2

The read and write start reading/writing at the implicit file offset stored in the descriptor, and increment it by the number of bytes read/written. Therefore, you would now read bytes 0 .. 3, and then write bytes 4 .. 7.

Instead of read and write and messing with lseek et al, use the POSIX standard pread and pwrite that do not use the implicit file offset in the descriptor but take explicit file offsets from the beginning of a file in the call.

#include <unistd.h>
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

...

ssize_t ret = pread(fd, &num, sizeof(int), 0);
ssize_t ret = pwrite(fd, &num, sizeof(int), 0);

Upvotes: 3

Related Questions