目录
引例
实现cat命令
dup和dup2函数
文件重定向案例
引例
输入重定向
cat < mypasswd
输出重定向
cat > mytxt
追加输出重定向
cat >> mytxt
实现cat命令
在src/cat.c
#include "io.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char * argv[1)
{
int fd_in= STDIN_FILENO; //0
int fd_out = STDOUT_FILENO; //1
int i;
for(i = 1; i< argc; i++){
fd_in = open(argv[i], O_RDONLY);
if(fd_in <0){
perror("open error");
continue;
}
copy(fd_in, fd_out);
close(fd_in);
}
if(argc == 1) copy (fd_in, fd_out);
}
dup和dup2函数
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
返回: 成功返回新文件描述符,出错返回-1
功能: 文件描述符的复制
参数
oldfd:原先的文件描述符newfd:新的文件描述符
把oldfd文件表项的指针复制给newfd就是把oldfd的指向复制一份到newfd(原来newid指向的文件被关闭),如此一来,再向newfd写输入就如同向oldfd写输入一样了。由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用newfd参数指定新描述符的数值。
如果newfd已经打开,则先将其关闭。如若oldfd等于newfd,则dup2返回newfd,而不关闭它。
在进程间通信时可用来改变进程的标准输入和标准输出设备
文件重定向案例
#include "io.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
/*
*bin/mcat + iotek.txt(+为输入重定向)
*bin/mcat - iotek.txt(-为输出重定向)
*/
int main(int argc, char * argv[1)
{
int fd_in, fd_out;
int flag = 0;
int i;
for(i = 1; i < argc;i++){
if(!strcmp("+", argv[il)){
fd_in = open(argv[++il, O_RDONLY);
if(fd_in <0){
perror("open error");
exit(1);
}
//将标准输入重定向到文件
if(dup2(fd_in, STDIN_FILENO)!= STDIN_FILENO){
perror("dup2 error");
exit(1);
}
close(fd_in);
}else if(!strcmp("-", argv[i])){
fd_out = open (argv[++i],O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd_out < 0){
perror("open error");
exit(1);
//将标准输出重定向到文件
if(dup2(fd_out, STDOUT_FILENO)!= STDOUT_FILENO){
perror("dup2 error");
exit(1);
}
close(fd_out);
}else{
flag = 1;
fd_in = open(argv[i], O_RDONLY);
if (fd in < 0){
perror ("open error"); exit(1);
}
if(dup2(fd_in, STDIN_FILENO)!= STDIN_FILENO){
perror("dup2 error");
exit(1);
}
copy(STDIN_FILENO, STDOUT_FILENO);
close(fd_in);
}
if(!flag)
copy(STDIN_FILENO, STDOUT_FILENO);
return 0;
}
图示
输入重定向示意图
输出重定向示意图
文件描述符复制案例(重定向)部分代码
int i = 1;
for(; i < argc; i++){
if(!strcmp(argv[i], "+")){
if(fd = open(argv[++i], O_RDONLY)<0){
sys_err("open");
}else{
if(dup2(fd, STDIN_FILENO) != STDIN_FILENO){
sys_err("dup2");
}
close(fd);
}
}else if(!strcmp(argv[i], "-")){
int fd = open(argv[++i],O_WRONLY|O_CREAT|O_TRUNC, 0777);
if(fd < 0){sys_err("open");
}else{
if(dup2(fd, STDOUT_FILENO) != STDOUT_FILENO){
sys_err("open");
}
close(fd);
}
}else{fprintf(stderr, "usage: %s [+] file1 [-] file2\n", argv[0]);
exit(1);
}
}
copy(STDIN_FILENO, STDOUT_FILENO);
return 0;
}