这些系统调用出了什么问题?

时间:2010-10-05 14:38:13

标签: c system-calls

我无法调试此代码。我从指南中复制了该示例,该文件是否被错误地编入索引?

#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 个答案:

答案 0 :(得分:3)

如果从文件的开头寻找负偏移量,则会出现错误 - 文件开头之前没有可访问的字节。

此外,您应始终检查或捕获系统调用的结果,而不是依赖于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 :(得分:1)

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

访问冲突(保证一个)。您没有'\0'终止符。

同样适用于:

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

答案 2 :(得分:1)

您对文件第-1位的期望是什么?也许你想要SEEK_CUR或SEEK_END而不是SEEK_SET。

答案 3 :(得分:-1)

c[sz] = '\0';
读取电话后