C程序使用Unix系统调用I / O.

时间:2015-04-14 02:07:30

标签: c unix

我的教授让我写一个简单的C程序,然后让我用Unix系统调用转换。我尝试改变周围的值,但没有任何工作。

要求: 编写一个新的C程序newcat,它与oldcat完全相同,但对I / O使用以下UNIX系统调用。

int read(int fd, char *buf, int n);
int write(int fd, char *buf, int n);
int open(char *name, int accessmode, int permission);
int close(int fd);

要打开要读取的文件,可以使用fcntl.h头文件中定义的符号常量O_RDONLY来指定访问模式。只需传递0即可获得许可。也就是说,代码将如下所示:

fd = open (filename, O_RDONLY, 0); 

您将需要以下头文件:sys / types.h,unistd.h和fcntl.h

#include <stdio.h>
/* oldcat: Concatenate files */
int main(int argc, char *argv[])
{
   void filecopy(FILE *, FILE *); /* prototype for function */
   int fd = open(*fp, O_RDONLy,0)
   char *prog = argv[0]; /* program name for errors */
   if (argc == 1) /* no args; copy standard input */
      filecopy(0, 1);
  else 
      while (--argc > 0)
         if (fd == -1) {
            fprintf(stderr, "%s: can't open %s\n", prog, *argv);
            return(-1);
         } else {
            filecopy(fp, 1);
            fclose(fp);
     }
  return(0);
}
/* filecopy: copy file ifp to ofp */
void filecopy(FILE *ifp, FILE *ofp)
{
   int c;
   while ((c = getc(ifp)) != EOF)
      putc(c, ofp);
}

这是写作的想法吗?它仍然无法编译:

#include <stdio.h>
/* oldcat: Concatenate files */
int main(int argc, char *argv[])
{
   void filecopy(int ifp, int ifo); 

   int fd = open(*File,O_RDONLY,0);  //is this correct?
   char *prog = argv[0]; 
   if (argc == 1) /* no args; copy standard input */
      filecopy(0, 1); //is this correct?
  else 
      while (--argc > 0)
         if ((fd == -1)  //is this correct?{
            fprintf(stderr, "%s: can't open %s\n", prog, *argv); 
            return(-1);
         } else {
            filecopy(*FILE, 1);//is this correct?
            close(*FILE);//is this correct?
     }
  return(0);
}
/* filecopy: copy file ifp to ofp */
void filecopy(FILE *ifp, FILE *ofp)//NO CLUE HOW THIS SHOULD BE
{
   int c;
   while (c = read(fd ,&something,1)//What is &ch/&something?
      putc(c, ofp);
}

3 个答案:

答案 0 :(得分:3)

假设您的oldcat使用C标准库调用(如fopen),那么将这些调用映射到UNIX调用就很简单了。

高层:

fopen  -> open
fread  -> read
fwrite -> write
fclose -> close

例如,使用以下命令打开输入文件时

FILE *fIn = fopen ("jargon.txt", "r");

你可以改用:

int inFd = open ("jargon.txt", O_RDONLY, 0);

其他调用非常相似,在C标准库和UNIX系统调用级别具有类似的功能。有关这些调用的详细信息通常可以通过在您的shell中输入man 2 open之类的内容或通过将man open插入您最喜欢的搜索引擎来从联机帮助页获取。

唯一&#34;棘手&#34;映射是指你使用getchar/putchar式调用来进行实际的读写操作,但是当你意识到(例如)读取一个字符在功能上与读取一个块大小相同时,这也很容易:

int c = getc (fIn);

或:

char c;
int numread = read (inFd, &c, 1);

对于您添加的问题:

  

所以要打开一个文件:if(fd = open(fp,O_RDONLY,0);)== NULL)

不完全。 fopen函数在出错时返回NULL,因为它返回指向FILE结构的指针。

较低级别调用使用文件描述符而不是文件句柄,前者是一个小整数值。所以,而不是:

FILE *fp = fopen ("nosuchfile", "r");
if (fp == NULL) doSomethingIntelligent();

你会做类似的事情:

int fd = open ("nosuchfile", O_RDONLY, 0);
if (fd == -1) doSomethingIntelligentUsing (errno);

就你需要改变什么而言,以下是我的头脑(所以可能不是完全详尽但应该是一个非常好的开始):

  • 添加所需的标题。
  • 完全停止使用FILE*,而是使用int
  • fopen/fclose次来电转换为open/close。这包括函数名称,不同参数不同的返回类型。
  • 修改filecopy以使用文件描述符而不是文件句柄。
  • 在致电1时使用stdout代替filecopy(后者为FILE *)。

作为如何执行此操作的示例,以下程序testprog.c将自行读取并将每个字符回显到标准输出:

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

int main (void) {
    int num, ch, inFd;

    // Open as read only.

    inFd = open ("testprog.c", O_RDONLY, 0);
    if (inFd == -1)
        printf ("\n**Error %d opening file\n", errno);

    // Get and output esach char until EOF/error.

    while ((num = read (inFd, &ch, 1) != 0) == 1)
        putchar (ch);

    // Detect error.

    if (num != 0)
        printf ("\n**Error %d reading file\n", errno);

    // Close file and exit.

    close (inFd);

    return 0;
}

答案 1 :(得分:1)

请注意,linux sys calls中的manual文档存在于man pages man中,您可以在linux系统中的bash shell中使用read命令进行访问。由于UNIX和Linux与您感兴趣的系统调用非常相似(可能是等效的),您可以查看Linux中这些系统调用的手册页。

write中解释了所有四个opencloseman pagesman 2 read man 2 write man 2 open man 2 close linux系统调用。您可以通过在shell中键入以下命令来访问这些系统调用的手册页:

{{1}}

这些应该可以指导你正确的方向。

答案 2 :(得分:0)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
/* newcat: Concatenate files */
int main(int argc, char *argv[])
    {
   void filecopy(int ifp, int ofp); /* prototype for function */

   int fd;
   char *prog = argv[0]; /* program name for errors */
   if (argc == 1) /* no args; copy standard input */
  filecopy(0,1);
   else 
      while (--argc > 0)
         fd = open(*++argv , O_RDONLY,0);
         if ( fd == -1) {
            fprintf(stderr, "%s: can't open %s\n", prog, *argv);
            return(-1);
         } else {
            filecopy(fd, 1);
           close(fd);
         }
   return(0);
}
/* filecopy: copy file ifp to ofp */
void filecopy(int ifp, int ofp)
{
   int c;
   while (read(ifp,&c,ofp ) != 0)
      write(ofp,&c,ofp);
}