Что не так с этими системными вызовами? - PullRequest
0 голосов
/ 05 октября 2010

Я затрудняюсь отладки этого кода.Я скопировал пример из руководства, этот файл неправильно проиндексирован?

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.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;
}

входной файл:

 Jim Plank
 Claxton 221

Ответы [ 4 ]

3 голосов
/ 05 октября 2010

Если вы ищете отрицательное смещение от начала файла, вы получаете ошибку - нет доступных байтов до начала файла.

Кроме того, вы всегда должны проверять или фиксировать результаты системных вызовов, а не полагаться на установленную errno. Библиотека C никогда не устанавливает errno на ноль (кроме случаев, когда процесс / поток запускается). Может быть установлено ненулевое значение, даже если функция выполнена успешно. В Solaris обычно устанавливается errno после записи в файл, поскольку файл не является терминалом, а библиотека пытается выполнить операцию, которая завершается успешно только на терминале.


Рабочий код, за вычетом выделения памяти через 'malloc ()'. Он явно печатает только количество прочитанных символов («<<%.*s>>» ограничивает длину указанным размером; угловые скобки облегчают просмотр данных, которые печатаются).

#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;
}

Выход:

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
1 голос
/ 05 октября 2010

Что именно вы ожидаете в -1-й позиции файла?Может быть, вы хотели SEEK_CUR или SEEK_END вместо SEEK_SET.

1 голос
/ 05 октября 2010

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

Нарушение прав доступа (гарантированное).У вас нет '\0' терминатора.

То же самое для:

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

0 голосов
/ 07 декабря 2013
c[sz] = '\0';

после чтения звонков.

...