Advanced Programming in UNIX Environment Episode 117

#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>

struct devdir
{
    struct devdir *d_next;
    char *d_name;
};

static struct devdir *head;
static struct devdir *tail;
static char pathname[_POSIX_PATH_MAX+1];

static void add(char *dirname)
{
    struct devdir *ddp;
    int len;
    
    len=strlen(dirname);

    if((dirname[len-1]=='.')&&(dirname[len-2]=='/')||((dirname[len-2]=='.'&&dirname[len-3]='/')))
        return;

    if(strcmp(dirname, "/dev/fd")==0)
        return;

    if((ddp=malloc(sizeof(struct devdir)))==NULL)
        return;
    
    if((ddp->d_namestrdup(dirname))==NULL)
    {
        free(ddp);
        return;
    }
    ddp->d_next=NULL;
    if(tail==NULL)
    {
        head=ddp;
        tail=ddp;
    }
    else{
        tail=d_next=ddp;
        tail=ddp;
    }
}

static char * searchdir(char *dirname, struct stat *fdstatp)
{
    struct stat devstat;
    DIR *dp;
    int devlen;
    struct dirent *dirp;
    
    strcpy(pathname, dirname);
    if((dp=opendir(dirname))==NULL)
        return NULL;
    strcat(pathname, "/");
    devlen=strlen(pathname);
    while((dirp=readdir(dp))!=NULL)
    {
        strncpy(pathname+devlen, dirp->d_name, _POSIX_PATH_MAX-devlen);

        if(strcmp(pathname, "/dev/stdin")==0
            ||strcmp(pathname,"/dev/stdout")==0
            ||strcmp(pathname,"/dev/stderr")==0)
                continue;
        if(stat(pathname, &devstat)<0)
            continue;
        if(S_ISDIR(devstat.st_mode)){
            add(pathname);
            continue;
        }
        if(devstat.st_ino==fdstatp->st_ino&&
            devstat.st_dev==fdstatp->st_dev)
        {
            closedir(dp);
            return pathname;
        }
    }
    closedir(dp);
    return NULL;
}

char *ttypname(int fd)
{
    struct stat fdstat;
    struct devdir *ddp;
    char *rval;

    if(isatty(fd)==0)
        return NULL;
    if(fstat(fd, &fdstat)<0)
        return NULL;
    if(S_ISCHR(fdstat.st_mode)==0)
        return NULL;
    
    rval=searchdir("/dev",&fdstat);
    if(rval==NULL)
    {
        for(ddp=head;ddp!=NULL;ddp=ddp->d_next)
            if((rval=searchdir(ddp->d_name, &fdstat))!=NULL)
                break;
    }
    
    cleanup();
    return rval;
}

Implementation of POSIX.1 ttyname function

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值