1.方法1:close then open
第一步是close(0),即将标准输入的连接挂断,这里调用close(0)将标准输入与终端设备的连接切断,切断后当前文件描述符数组中的第一个元素现在处于空闲状态。
最后,使用open(filename,O_RDONLY)打开一个想连接到stdin上的文件。当前的最低可用文件描述符是0,因此所打开的文件被连接到标准输入上去。
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
main(){
int fd;
char line[100];
/*read and print three lines*/
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
/*redirect input */
close(0);
fd = open("/etc/passwd",O_RDONLY);
if(fd!=0){
fprintf(stderr,"Could not open data as fd 0\n");
exit(1);
}
/*read and print three lines*/
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
}
2.方法2 :使用open..close..dup..close
Unix 系统调用dup建立指向已经存在的文件描述符的第二个连接
1.open(file)
第一步是打开stdin将要重定向的文件。这个调用返回一个文件描述符,这个文件描述符并不是0,因为0在当前已经被打开。
2.close(0)
下一步是将文件描述符0关闭。文件描述符0现在已经空闲了。
3.dup(fd)
系统调用dup(fd)将文件描述符fd做了复制。此次复制使用最低可用文件描述符号。因此,获得的文件描述符是0,这样,就将磁盘文件与文件描述符0连接起来了。
4.close(fd)
最后使用close(fd)来关闭文件的原始连接,只留下文件描述符0的连接。
代码:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define CLOSE_DUP
/*#define USE_DUP2*/
main(){
int fd;
int newfd;
char line[100];
/*read and print three lines*/
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
/*redirect input */
fd = open("/etc/passwd",O_RDONLY);
if(fd!=0){
fprintf(stderr,"Could not open data as fd 0\n");
exit(1);
}
#ifdef CLOSE_DUP
close(0);
newfd=dup(fd);
#else
newfd=dup2(fd,0);
#endif
if(newfd!=0){
fprintf(stderr,"Clould not duplicate fd to 0\n");
exit(1);
}
close(fd);
/*read and print three lines*/
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
fgets(line,100,stdin);printf("%s",line);
}