注,本人初涉linux,阅历有限,代码中固然会有许多弊端,请各位判官 批判 地看。
还有,不能保证完全正确,希望大家共同进步,告诉小弟多点编程小技巧,不胜感谢。
3.2编写一个于dup2()功能相同的函数,但不实用fcntl().
上网搜了一下,竟然搜到同实验室的大牛的代码,基于他的基础,我再写了个。
当然不能做到的是原子性,另外知道有一个ioctl,现在还没学到深入,到时再看看用这个函数能不能做。
这种实现方法不用fcntl的关键是用了/dev/fd/XXXX来代替检测其是否打开。
另外,一直dup的方法,比较挫...
/* TRY to build up a function just like dup2
* without using fcntl(),and it's base on
* DBcow's work.
* Jason@HIT
* 31/12/2008
*/
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int myDup2(int fd, int fd2);
int main()
{
int fd = open("./myDup.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR);
if (fd == -1)
{
perror("open file error");
exit(-1);
}
// fd = 1000000;//invalid fd
int afd = myDup2(fd ,5);
printf("afd = %d/n", afd);
if (write(afd, "hello/n", 7) !=7)
{
perror("write file error");
}
close(fd);
close(afd);
return 0;
}
int myDup2(int fd, int fd2)
{
int fds[fd2];
int tmpfd;
int i;
if (fd2 < 0
#ifdef OPEN_MAX
|| fd2 >= OPEN_MAX
#endif
)// invalid value
{
perror ("EBADF");
return -1;
}
/* Check if FD is kosher. But how to check it without fcntl? */
char fdname[20];
char fdpath[50];
sprintf(fdname,"%d", fd);
strcpy(fdpath, "/dev/fd/");
strcat(fdpath,fdname);
// printf("the path is : |%s|/n",fdpath);
if (tmpfd = open(fdpath, O_RDONLY)==-1)
{
perror("fd");
exit(-1);
}
if (fd == fd2)
return fd2;
/* This is not atomic */
int save = errno;
(void) close(fd2);
errno = save;
for (i = 0; i < fd2; ++i)//set all -1
{
fds[i] = -1;
}
i = 0;
while (tmpfd = dup(fd)){
if (tmpfd == fd2)
break;
fds[i++] = tmpfd;
}
for ( ; i >= 0; i--)
fds[i]==-1||close(fds[i]);
return fd2;
}
//+++++++++++++++++++++++++++++++++
下面是第三题,能较好的体现三者关系吧,
详见附录C
dup()以后并没有在内核给相应的文件描述符分配一个表项,其实fd[0]和fd[1]的关系就有点点像是两个指针指向同样一个东东。又由于文件状态标志是保存在内核的,所以,其中一个fd调用了fcntl(....SET..)
的时候,会影响另外一个的,但fd[2]中由于内核另外给了它一个表项,所以不受影响。
给代码:
/*
* a code to check the relationship
* and differences between open()
* and duo();
* By Jason@HIT
* 31/12/2008
* */
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int showstate(int* state, int* fd, int len)
{
int i;
for (i=0; i<len; i++)
{
state[i] = fcntl(fd[i], F_GETFL);
if (state[i]==-1)
{
perror("fcntl err");
}
printf("For fd%d,it's state is:%d/n", i,state[i]);
}
return 0;
}
int main()
{
int fd[3], i;
int state[3];
fd[0] = open("./test.txt", O_RDWR|O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR);
if (fd[0]==-1)
{
perror("open0");
}
fd[1] = dup(fd[0]);
if (fd[1]==-1)
{
perror("dup()");
}
fd[2] = open("test.txt", O_WRONLY|O_APPEND);
if (fd[2]==-1)
{
perror("open2");
}
printf("Original:/n");
showstate(state, fd, 3);
fcntl(fd[0], F_SETFL, O_NONBLOCK);
printf("set fd[0]:/n");
showstate(state, fd, 3);
fcntl(fd[1], F_SETFL, O_FSYNC);
printf("set fd[1]:/n");
showstate(state, fd, 3);
return 0;
}
//++++++++++++++++++++++++++++
Unix环境高级编程 第三章习题答案
最新推荐文章于 2020-09-28 09:37:39 发布