(简而言之)它是如何工作的?
(In brief) How it works?
大家好
我需要你的帮助
我是 Zed,我有一个原始问题,看看这个函数:
void cat_stdin(void)
{
char c[1] //c;
while (read(0, c//&c, 1) > 0)
write(1, c//&c, 1);
}
它是如何工作的? write 和 read 系统调用在做什么?
这段代码就像:cat -
抱歉我是法国菜鸟
与我分享你的知识,我卡住了:/
您发布的答案存在一些问题。
值得注意的是,cat_stdout
和 cat_stdin
可以是一个将输入文件描述符作为参数的函数(例如 cat_stream
)。
它一次只传输一个字节,所以很慢。
这是我从头开始编码的版本 [带注释]。它处理大多数情况并具有错误检查功能。它可能会帮助您改进自己的版本:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
int
cat_stream(int fd)
{
ssize_t rlen;
ssize_t wlen;
int err = 0;
char *cur;
char buf[64 * 1024];
// NOTE: the buffer size can be _any_ length, but 64KB is optimal for many
// filesystem files or devices
while (1) {
// read a chunk of input
rlen = read(fd,buf,sizeof(buf));
// end of file
if (rlen == 0)
break;
// error
if (rlen < 0) {
err = errno;
fprintf(stderr,"cat_stream: read error -- %s\n",strerror(err));
break;
}
// write out all data read in current chunk -- loop until all data
// read in this chunk has been output, even if it could _not_ be
// output in a single write call, advancing the pointer into the
// buffer [and shortening the remaining length]
cur = buf;
for (; rlen > 0; rlen -= wlen, cur += wlen) {
wlen = write(1,cur,rlen);
// handle error
if (wlen < 0) {
err = errno;
fprintf(stderr,"cat_stream: write error -- %s\n",strerror(err));
break;
}
}
}
// restore errno after fprintf so caller can use it [if desired]
if (err)
errno = err;
return err;
}
int
main(int argc,char **argv)
{
const char *file;
int fd;
int err = 0;
// skip over program name
--argc;
++argv;
// no arguments means stdin -- fake a "-" entry
if (argc <= 0) {
++argc;
--argv;
argv[0] = "-";
}
// loop on all input files
for (; argc > 0; --argc, ++argv) {
file = *argv;
// copy stdin
if (strcmp(file,"-") == 0) {
cat_stream(0);
continue;
}
// open the explicit input file
fd = open(file,O_RDONLY);
if (fd < 0) {
err = errno;
fprintf(stderr,"cat: unable to open '%s' -- %s\n",
file,strerror(err));
break;
}
// cat the open file stream
err = cat_stream(fd);
// close the input file
close(fd);
// stop on error
if (err)
break;
}
// regardless of the error, just return 1
if (err)
err = 1;
return err;
}
大家好 我需要你的帮助
我是 Zed,我有一个原始问题,看看这个函数:
void cat_stdin(void)
{
char c[1] //c;
while (read(0, c//&c, 1) > 0)
write(1, c//&c, 1);
}
它是如何工作的? write 和 read 系统调用在做什么? 这段代码就像:cat -
抱歉我是法国菜鸟
与我分享你的知识,我卡住了:/
您发布的答案存在一些问题。
值得注意的是,cat_stdout
和 cat_stdin
可以是一个将输入文件描述符作为参数的函数(例如 cat_stream
)。
它一次只传输一个字节,所以很慢。
这是我从头开始编码的版本 [带注释]。它处理大多数情况并具有错误检查功能。它可能会帮助您改进自己的版本:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
int
cat_stream(int fd)
{
ssize_t rlen;
ssize_t wlen;
int err = 0;
char *cur;
char buf[64 * 1024];
// NOTE: the buffer size can be _any_ length, but 64KB is optimal for many
// filesystem files or devices
while (1) {
// read a chunk of input
rlen = read(fd,buf,sizeof(buf));
// end of file
if (rlen == 0)
break;
// error
if (rlen < 0) {
err = errno;
fprintf(stderr,"cat_stream: read error -- %s\n",strerror(err));
break;
}
// write out all data read in current chunk -- loop until all data
// read in this chunk has been output, even if it could _not_ be
// output in a single write call, advancing the pointer into the
// buffer [and shortening the remaining length]
cur = buf;
for (; rlen > 0; rlen -= wlen, cur += wlen) {
wlen = write(1,cur,rlen);
// handle error
if (wlen < 0) {
err = errno;
fprintf(stderr,"cat_stream: write error -- %s\n",strerror(err));
break;
}
}
}
// restore errno after fprintf so caller can use it [if desired]
if (err)
errno = err;
return err;
}
int
main(int argc,char **argv)
{
const char *file;
int fd;
int err = 0;
// skip over program name
--argc;
++argv;
// no arguments means stdin -- fake a "-" entry
if (argc <= 0) {
++argc;
--argv;
argv[0] = "-";
}
// loop on all input files
for (; argc > 0; --argc, ++argv) {
file = *argv;
// copy stdin
if (strcmp(file,"-") == 0) {
cat_stream(0);
continue;
}
// open the explicit input file
fd = open(file,O_RDONLY);
if (fd < 0) {
err = errno;
fprintf(stderr,"cat: unable to open '%s' -- %s\n",
file,strerror(err));
break;
}
// cat the open file stream
err = cat_stream(fd);
// close the input file
close(fd);
// stop on error
if (err)
break;
}
// regardless of the error, just return 1
if (err)
err = 1;
return err;
}