Unix环境高级编程 第三章习题答案

注,本人初涉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;
}
//++++++++++++++++++++++++++++

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值