2

読み取り動作を確認するために、この小さなコードを作成しました。 

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

int main ()
{
  ssize_t ret;
  int fd;
  char str[30] = {0};
  off_t lret

  fd = open("./sample", O_RDWR);
  printf("File descriptor = %d\n",fd);

  lret = lseek(fd,LONG_MAX,SEEK_SET);
  printf("%ld\n",lseek(fd, 0, SEEK_CUR));

  ret = read(fd, str, 20);
  if (ret == -1) {
     perror("read error");
  }
  else {
     printf("%ld\n",ret);
     printf("%s\n",str);
  }

  ret = write(fd, "bye", 3);
  if (ret == -1) {
     perror("write error");
  }
  else
     printf("%ld\n",ret);

  printf("%ld\n",lseek(fd, 0, SEEK_CUR));
  close (fd);

  return 0;
}

出力は次のとおりです。

$ cat sample
HELLO$ ./a.out
File descriptor = 3
4294967295
read error: Invalid argument
write error: Invalid argument
4294967295
$ ll sample
-rw-r--r--. 1 bruce stud 5 Jan 14 17:25 sample

しかし、lseekステートメントをに変更すると

ret = lseek(fd,5,SEEK_SET);

読み取りは0を返します

$ ./a.out
File descriptor = 3
5
0

3
8
$ cat sample
HELLObye$ ll sample
-rw-r--r--. 1 bruce stud 8 Jan 14 17:26 sample

なぜreadはこのように動作するのですか?

4

2 に答える 2

2

lseekによって返される値は、off_tではなく、であることに注意してくださいsize_t。違いは、off_tが署名されていることです。符号付きの値を取得して符号なしにすると、大きな正の数のように見えます。

「LONG_MAX」は実際にはではなく42949672952147483647(2 ^ 31-1)またははるかに大きい数であると思います。したがって、4294967295は-1から来ます[これは2 ^ 32-1であり、実際には32ビット数学の-1と同じです]。

つまり、からエラーが発生しlseekます。

于 2013-01-14T22:59:41.133 に答える
1

奇妙なエラーが発生します。実際に使用しているOSは何ですか?if (ret == -1) perror("lseek error");エラーチェックを改善するために、最初のlseekの直後にチェックを追加しました。

Linuxでは次のようになります。

File descriptor = 3
lseek error: Invalid argument
0
5
HELLO
3
8

OpenBSDで私は見ます:

File descriptor = 3
9223372036854775807
read error: File too large
write error: File too large
9223372036854775807

...どちらも妥当な応答のようです

于 2013-01-14T22:52:29.937 に答える