使用系统调用实现unix cat命令
对于我的操作系统课程,我的任务是通过系统调用(无 scanf 或 printf)实现 Unix 的 cat 命令。这是我到目前为止得到的:(
感谢回复进行编辑)
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
main(void)
{
int fd1;
int fd2;
char *buffer1;
buffer1 = (char *) calloc(100, sizeof(char));
char *buffer2;
buffer2 = (char *)calloc(100, sizeof(char));
fd1 = open("input.in", O_RDONLY);
fd2 = open("input2.in", O_RDONLY);
while(eof1){ //<-lseek condition to add here
read (fd1, buffer1, /*how much to read here?*/ );
write(1, buffer1, sizeof(buffer1)-1);
}
while (eof2){
read (fd2,buffer2, /*how much to read here?*/);
write(1, buffer2, sizeof(buffer2)-1);
}
}
我看到的示例仅显示读取已知字节数。我不知道每个读取的文件有多少字节,那么如何指定读取的最后一个参数?
For my OS class I have the assignment of implementing Unix's cat command with system calls (no scanf or printf). Here's what I got so far:
(Edited thanks to responses)
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
main(void)
{
int fd1;
int fd2;
char *buffer1;
buffer1 = (char *) calloc(100, sizeof(char));
char *buffer2;
buffer2 = (char *)calloc(100, sizeof(char));
fd1 = open("input.in", O_RDONLY);
fd2 = open("input2.in", O_RDONLY);
while(eof1){ //<-lseek condition to add here
read (fd1, buffer1, /*how much to read here?*/ );
write(1, buffer1, sizeof(buffer1)-1);
}
while (eof2){
read (fd2,buffer2, /*how much to read here?*/);
write(1, buffer2, sizeof(buffer2)-1);
}
}
The examples I have seen only show read with a known number of bytes. I don't know how much bytes each of the read files will have, so how do I specify read's last paramether?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
读
到缓冲区之前,您必须分配一个缓冲区。在堆栈上(最简单)或使用mmap
。perror
是一个复杂的库函数,而不是系统调用。exit
不是 Linux 上的系统调用。但_exit
是。写入
的字节数不要超过您之前读取
的字节数。编辑:这是我的代码,仅使用系统调用。错误处理有些有限,因为我不想重新实现
perror
。read
into a buffer, you have to allocate one. Either on the stack (easiest) or withmmap
.perror
is a complicated library function, not a system call.exit
is not a system call on Linux. But_exit
is.write
more bytes than you haveread
before.Edit: Here is my code, using only system calls. The error handling is somewhat limited, since I didn't want to re-implement
perror
.您需要读取缓冲区中能够容纳的尽可能多的字节。现在,你还没有缓冲区,你得到的只是一个指向缓冲区的指针。那没有初始化为任何东西。先有鸡还是先有蛋,因此您也不知道要读取多少字节。
创建一个缓冲区。
You need to read as many bytes as will fit in the buffer. Right now, you don't have a buffer yet, all you got is a pointer to a buffer. That isn't initialized to anything. Chicken-and-egg, you therefore don't know how many bytes to read either.
Create a buffer.
通常不需要一口气读完整个文件。选择与主机操作系统内存页面大小相同或倍数的缓冲区大小是一个好方法。页面大小的 1 或 2 倍可能就足够了。
使用太大的缓冲区实际上可能会导致程序运行更差,因为它们会给虚拟内存系统带来压力并可能导致分页。
There is usually no need to read the entire file in one gulp. Choosing a buffer size that is the same or a multiple of the host operating system's memory page size is a good way to go. 1 or 2 X the page size is probably good enough.
Using buffers that are too big can actually cause your program to run worse because they put pressure on the virtual memory system and can cause paging.
您可以使用
open
、fstat
、mmap
、madvise
和write
来制作非常高效的 cat 命令。如果特定于 Linux,您可以使用
open
、fstat
、fadvise
和splice
来创建更高效的 cat 命令。建议调用将指定 SEQUENTIAL 标志,该标志将告诉内核对文件进行积极的预读。
如果您想对系统的其余部分保持礼貌并尽量减少缓冲区高速缓存的使用,则可以以 32 MB 左右的块进行复制,并在已读取的部分上使用建议 DONTNEED 标志。
注意:
以上仅当源是文件时才有效。如果 fstat 无法提供大小,那么您必须回退到使用分配的缓冲区和
读取
、写入
。您也可以使用splice
。You could use
open
,fstat
,mmap
,madvise
andwrite
to make a very efficient cat command.If Linux specific you could use
open
,fstat
,fadvise
andsplice
to make an even more efficient cat command.The advise calls are to specify the SEQUENTIAL flags which will tell the kernel to do aggressive read-ahead on the file.
If you like to be polite to the rest of the system and minimize buffer cache use, you can do your copy in chunks of 32 megabytes or so and use the advise DONTNEED flags on the parts already read.
Note:
The above will only work if the source is a file. If the fstat fails to provide a size then you must fall back to using an allocated buffer and
read
,write
. You can usesplice
too.在读取文件之前,使用 stat 函数查找文件的大小。或者,您可以读取块直到获得 EOF。
Use the stat function to find the size of your files before you read them. Alternatively, you can read chunks until you get an EOF.