自己实现的tee命令
操作系统
题目
tee命令是从标准输入中读取数据,直至文件结尾,随后将数据写入标准输出和命令行参数所指定的文件。请使用I/O系统调用实现tee命令。并实现-a选项。
代码
#include <ctype.h>
#include "tlpi_hdr.h"
#include <stdbool.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
char ch;
bool append = FALSE;
char buf[1024] = {0};
char end = EOF;
int outfilefd, ret;
ssize_t len;
/* 读取选项 */
while ((ch = getopt(argc, argv, "a")) != -1)
{
switch (ch)
{
case 'a':
// printf("option append\n");
append = TRUE; //在文件后面追加数据
break;
default:
usageErr(" [-a] filename\n");
break;
}
}
if (append && argc == 3) //追加模式且有操作文件
{
/* !!!!!使用了O_APPEND和O_TRUNC时,默认还是从头开始,并且使用lseek也没有用处 */
outfilefd = open(argv[2], O_RDWR | O_CREAT | O_APPEND , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); //读写输出文件
if (outfilefd == -1)
errExit("open faild\n");
while (1)
{
len = read(STDIN_FILENO, buf, 1024);
if (len != -1)
{
if (len == 0)
{
close(outfilefd);
exit(EXIT_SUCCESS);
}
write(STDOUT_FILENO, buf,len);
write(outfilefd, buf, len);
memset(buf, 0, 1024);
}
}
}
if (append && argc == 2) //追加模式但无操作文件
{
while (1)
{
len = read(STDIN_FILENO, buf, 1024);
if (len != -1)
{
if (len == 0)
{
exit(EXIT_SUCCESS);
}
write(STDOUT_FILENO, buf, len);
memset(buf, 0, 1024);
}
}
}
if (!append && argc == 2) //非追加模式且有操作文件
{
outfilefd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); //读写输出文件
if (outfilefd == -1)
errExit("open file\n");
while (1)
{
len = read(STDIN_FILENO, buf, 1024);
if (len != -1)
{
if (len == 0)
{
close(outfilefd);
exit(EXIT_SUCCESS);
}
write(STDOUT_FILENO, buf, len);
write(outfilefd, buf, len);
memset(buf, 0, 1024);
}
}
}
if (!append && argc == 1) //非追加模式 无操作文件
{
while (1)
{
len = read(STDIN_FILENO, buf, 1024);
if (len != -1)
{
if (len == 0)
{
exit(EXIT_SUCCESS);
}
write(STDOUT_FILENO, buf, len);
memset(buf, 0, 1024);
}
}
}
exit(EXIT_SUCCESS);
}总结
打开文件的句柄不能弄错。 我之前的出错代码如下:
ret = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); //读写输出文件 if (ret == -1) errExit("open file\n"); . . . . . write(outfilefd, buf, len);习惯性的用ret来表示返回值,但是这里的返回值是文件句柄。
O_APPEND和O_TRUNC不能一起使用 至少在当你想在追加的时候不能使用,当使用这截断打开,此时不仅追加没用用,lseek(fd,0,SEEK_END)也会没有用。