开发者

What's wrong with these system calls?

开发者 https://www.devze.com 2023-01-18 23:47 出处:网络
I\'m at a loss debugging this code. I copied the example from a guide, is this file being improperly indexed?

I'm at a loss debugging this code. I copied the example from a guide, is this file being improperly indexed?

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <st开发者_JS百科dlib.h>
#include <string.h>
#include <math.h>

char *inicio(void);

main(void)
{
  char *c;
  int fd, sz, i;    
  c = inicio();

  fd = open("input.in", O_RDONLY);
  if (fd < 0) { perror("r1"); exit(1); }

  sz = read(fd, c, 10);
  printf("We have opened input.in, and have called read(%d, c, 10).\n", fd);
  printf("read has read %d bytes.\n", sz);
  printf("The bytes are these: %s\n", c);

  i = lseek(fd, 0, SEEK_CUR);
  printf("lseek(%d, 0, SEEK_CUR) returns the current location on the file being %d\n\n", fd, i);

  printf("We now look for the start of the file and call read(%d, c, 10)\n",fd);
  lseek(fd, 0, SEEK_SET);
  sz = read(fd, c, 10);

  printf("The reading returns the following bytes: %s\n", c);

  printf("We now execute lseek(%d, -6, SEEK_END). and return %d\n",fd, (int) lseek(fd, -6, SEEK_END));
  printf("Executing read(%d, c, 10), we get the following bytes: ", fd);

  sz = read(fd, c, 10);

  printf("Finally, we execute lseek(%d, -1, SEEK_SET).  This returns -1.\n", fd);
  printf("perror() indicates the fault:\n");
  fflush(stdout);

  i = lseek(fd, -1, SEEK_SET);
  perror("l1");
}

char *inicio(void)
{
  char *bytes;
  int j;
  bytes = (char *) calloc(100, sizeof(char));
  for(j=0;j<100;j++){bytes[j]=rand()%32+1;}
  return bytes;
}

the input file is:

 Jim Plank
 Claxton 221


If you seek to a negative offset from the start of the file, you get an error - there are no accessible bytes before the beginning of the file.

Also, you should always check or capture the results of system calls, rather than relying on errno being set. The C library never sets errno to zero (other than when the process/thread starts). It can be set to a non-zero value even if the function succeeded. On Solaris, it is routine for errno to be set after writing to a file because the file is not a terminal and the library attempts an operation that only succeeds on a terminal.


Working code, minus memory allocation via 'malloc()'. It explicitly prints only the number of characters read ('<<%.*s>>' limits the length to the size given; the angle brackets make it easy to see the data that is being printed).

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

int main(void)
{
    char c[100];
    int fd, sz, i;

    fd = open("input.in", O_RDONLY);
    if (fd < 0)
    {
         perror("Error from open(\"input.in\", O_RDONLY)");
         exit(1);
     }

    sz = read(fd, c, 10);
    printf("Opened input.in (fd = %d)\n", fd);
    printf("We called read(fd, c, 10) and read %d bytes: <<%.*s>>\n",
           sz, sz, c);

    i = lseek(fd, 0, SEEK_CUR);
    printf("lseek(fd, 0, SEEK_CUR) returns the current offset of %d\n", i);

    printf("We seek to start of the file and call read(fd, c, 10)\n");
    i = lseek(fd, 0, SEEK_SET);
    if (i != 0)
        perror("Error from lseek(fd, 0, SEEK_SET)\n");

    sz = read(fd, c, 10);
    if (sz < 0)
        perror("Error from read(fd, c, 10)\n");
    printf("We read the following bytes: <<%.*s>>\n", sz, c);

    printf("We now execute lseek(fd, -6, SEEK_END) which returns %d\n", 
           (int) lseek(fd, -6, SEEK_END));
    printf("Executing read(fd, c, 10), we get the following bytes: ");

    sz = read(fd, c, 10);
    if (sz < 0)
        perror("Error from read(fd, c, 10)\n");
    printf("<<%.*s>>\n", sz, c);

    printf("Finally, we execute lseek(fd, -1, SEEK_SET) which returns -1\n");
    fflush(stdout);

    if ((i = lseek(fd, -1, SEEK_SET)) < 0)
        perror("Error from lseek(fd, -1, SEEK_SET)");
    printf("i = %d\n", i);
    return 0;
}

Output:

Opened input.in (fd = 3)
We called read(fd, c, 10) and read 10 bytes: <<Jim Plank
>>
lseek(fd, 0, SEEK_CUR) returns the current offset of 10
We seek to start of the file and call read(fd, c, 10)
We read the following bytes: <<Jim Plank
>>
We now execute lseek(fd, -6, SEEK_END) which returns 16
Executing read(fd, c, 10), we get the following bytes: <<n 221
>>
Finally, we execute lseek(fd, -1, SEEK_SET) which returns -1
Error from lseek(fd, -1, SEEK_SET): Invalid argument
i = -1


printf("The bytes are these: %s\n", c);

Access violation (guaranteed one). You don't have a '\0' terminator.

Same goes for:

printf("The reading returns the following bytes: %s\n", c);


What exactly do you expect at the -1th position of the file? Maybe you wanted SEEK_CUR or SEEK_END instead of SEEK_SET.


c[sz] = '\0';

after the read calls.

0

精彩评论

暂无评论...
验证码 换一张
取 消