0

This is a program that I wrote to check bytes between a file and a disk.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#define BYTES_TO_READ 64

int main(int argc, char **argv)
{
  int device = open("/dev/sdz", O_RDWR);
  if(device < 0)
  {
      printf("Device opening error\n");
      return 1;
  }
  int file = open("test.txt", O_RDONLY);
  if(file < 0)
  {
      printf("File opening error\n");
      return 2;
  }
  int byte, device_loc, file_loc;
  char *buff_device, *buff_file;
  for(byte = 0; byte<BYTES_TO_READ; byte++)
  {
      device_loc = lseek(device, byte, SEEK_SET); /* SEG FAULT */
      file_loc = lseek(file, byte, SEEK_SET);
      printf("File location\t%d",file_loc);
      printf("Device location\t%d",device_loc);
      read(device, buff_device, 1);
      read(file, buff_file, 1);
      if( (*buff_device) == (*buff_file) )
      {
          printf("Byte %d same", byte);
      }
      else
      {
          printf("Bytes %d differ: device\t%d\tfile\t%d\n",byte, *buff_device, *buff_file);
      }
  }
  return 0;
}

Please don't ask why I'm comparing sdz and a file. This is exactly what I wanted to do: write a file directly to a disk and read it back.

sdz is a loop back device, with is a link to /dev/loop0. For now It doesn't matter if file and disk differ, but I want my program to work. By some debugging, I have found where the segmentation fault is happening, but I couldn't figure out why.

Long story short: Why this gives me segmentation fault?

Thanks in advance

vfsoraki
  • 2,186
  • 1
  • 20
  • 45

2 Answers2

2

These are writing to random locations in memory:

read(device, buff_device, 1);
read(file, buff_file, 1);

as buff_device and buff_file are uninitialized pointers. Use a char type and pass their addresses instead.

char buff_device;
char buff_file;

/* Check return value of read before using variables. */
if (1 == read(device, &buff_device, 1) &&
    1 == read(file, &buff_file, 1))
{
    if (buff_device == buff_file)
    /* snip */
}
else
{
    /* Report read failure. */
}
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • I though `read` would allocate memory, then put its address into buffers provided to function. So it does not, yes? – vfsoraki Feb 27 '14 at 15:27
  • 1
    @thelastblack, no it does not allocate memory. – hmjd Feb 27 '14 at 15:28
  • 1
    @thelastblack Just a thought experiment: if `read()` did allocate memory, how would that affect `buff_device`? `buff_device` is a pointer (to la la land at present) and that _value_ is given to `read()`. Whatever `read()` does with its _copy_ of that _value_ would not affect the original `buff_device`. – chux - Reinstate Monica Feb 27 '14 at 15:48
  • 2
    @chux, correct. If `read()` was to allocate memory then a pointer to a pointer would need passed as the argument so the caller could see the change. – hmjd Feb 27 '14 at 15:49
  • @chux When I think of it, you guys are totally correct. I'm not much of a C programmer. I mostly do scripting, which does not involve pointers :D Thanks for clarification – vfsoraki Feb 27 '14 at 16:06
  • Could you please have a look at question's comments and answer me if you could? – vfsoraki Feb 27 '14 at 16:10
  • @thelastblack, what question? – hmjd Feb 27 '14 at 16:10
  • This question that you answered! This question, please have a look at comments below the question itself. – vfsoraki Feb 27 '14 at 16:13
  • @thelastblack, I am afraid I don't know that. Sorry. – hmjd Feb 27 '14 at 16:14
1

Change :

char *buff_device, *buff_file;

to

char buff_device[1], buff_file[1];
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115