亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

終端I/O之終端標識

2024-06-28 13:27:42
字體:
來源:轉載
供稿:網友
終端I/O之終端標識

歷史沿襲至今,在大多數UNIX系統中,控制終端的名字是/dev/tty. POSIX.1提供了一個運行時函數,可被用來確定控制終端的名字。

#include <stdio.h>

char *ctermid(char *ptr);

返回值:若成功則返回指向控制終端名的指針,若出錯則返回指向空字符串的指針

如果ptr非空,則它被認為是一個指針,指向長度至少為L_ctermid字節的數組,進程的控制終端名存放在該數組中。常量L_ctermid定義在<stdio.h>中。若ptr是一個空指針,則該函數為數組(通常作為靜態變量)分配空間。同樣,進程的控制終端名存放在該數組中。

在這兩種情況中,該數組的起始地址被作為函數值返回。因為大多數UNIX系統都使用/dev/tty作為控制終端名,所以此函數的主要作用是幫助提高向其他操作系統的可移植性。

?

實例:ctermid函數

程序清單18-3 POSIX.1 ctermid函數的實現

#include <stdio.h>

#include <string.h>

?

static char ctermid_name[L_ctermid];

?

char *

ctermid(char *str)

{

????if(str == NULL)

????????str = ctermid_name;

????return(strcpy(str, "/dev/tty"));????/* strcpy() returns str */

}

?

注意,因為我們無法確定調用者緩沖區的大小,所以也就不能防止過度使用該緩沖區。

?

另外兩個與終端標識有關的函數是isatty和ttyname。前者在文件描述符引用一個終端設備時返回真,而后者則返回在該文件描述符上打開的終端設備的路徑名。

#include <unisd.h>

int isatty(int filedes);

返回值:若為終端設備則返回1(真),反則返回0(假)

?

char *ttyname(int filedes);

返回值:指向終端路徑名的指針,若出錯則返回NULL

?

實例:isatty函數

程序清單18-4 POSIX.1 isatty函數的實現

#include <termios.h>

?

int

isatty(int fd)

{

????struct termios????ts;

????

????return(tcgetattr(fd, &ts) != -1);????/* true if no error (is a tty) */

}

?

程序清單18-5測試isatty函數

#include "apue.h"

?

int

main(void)

{

????PRintf("fd 0: %s/n", isatty(0) ? "tty" : "not a tty");

????printf("fd 1: %s/n", isatty(1) ? "tty" : "not a tty");

????printf("fd 2: %s/n", isatty(2) ? "tty" : "not a tty");

????exit(0);

}

?

運行程序清單18-5中的程序時,我們可以得到下面的結果:

?

實例:ttyname函數

程序清單18-6 POSIX.1 ttyname函數的實現

#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);

????/*????

????* Skip ., .., and /dev/fd.

????*/

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

????????(dirname[len - 2] == '.' && dirname[len-3] == '/')))

????????return;

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

????????return;

????ddp = malloc(sizeof(struct devdir));

????if(ddp == NULL)

????????return;

????

????ddp->d_name = strdup(dirname);

????if(ddp->d_name == NULL)

????{

????????free(ddp);

????????return;

????}

????ddp->d_next = NULL;

????if(tail == NULL)

????{

????????head = ddp;

????????tail = ddp;

????}

????else

????{

????????tail->d_next = ddp;

????????tail = ddp;

????}

}

?

static void

cleanup(void)

{

????struct devdir????*ddp, *nddp;

????

????ddp = head;

????while(ddp != NULL)

????{

????????nddp = ddp->d_next;

????????free(ddp->d_name);

????????free(ddp);

????????ddp = nddp;

????}

????head = NULL;

????tail = NULL;

}

?

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);

????????/*

????????* Skip aliases.

????????*/

????????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)????/* found a match */

????????{

????????????closedir(dp);

????????????return(pathname);

????????}

????}

????closedir(dp);

????return(NULL);

}

?

char *

ttyname(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);

}

此處用到的方法是讀/dev目錄,尋找具有相同設備號和i節點編號的表項。每個文件系統有一個唯一的設備號(stat結構中的st_dev字段http://www.CUOXin.com/nufangrensheng/p/3501385.html),文件系統中的每個目錄項有一個唯一的i節點號(stat結構中的st_ino字段)。在此函數中假定當找到一個匹配的設備號和匹配的i節點號時,就找到了所希望的目錄項。

我們的終端名可能在/dev的子目錄中。于是,需要搜索在/dev之下的整個文件系統子樹。我們跳過了很多產生不正確或奇怪結果的目錄,它們是/dev/.,/dev/..和/dev/fd。我么也跳過了一些別名,即/dev/stdin、/dev/stdout以及/dev/stderr,它們是對在/dev/fd目錄中文件的符號鏈接。

?

程序清單18-7 測試ttyname函數

#include "apue.h"

?

int

main(void)

{

????char *name;

?

????if(isatty(0))

????{

????????name = ttyname(0);

????????if(name == NULL)

????????????name = "undefined";

????}

????else

????{

????????name = "not a tty";

????}

????printf("fd 0: %s/n", name);

?

????if(isatty(1))

????{

????????name = ttyname(1);

????????if(name == NULL)

????????????name = "undefined";

????}

????else

????{

????????name = "not a tty";

????}

????printf("fd 1: %s/n", name);

?

????if(isatty(2))

????{

????????name = ttyname(2);

????????if(name == NULL)

????????????name = "undefined";

????}

????else

????{

????????name = "not a tty";

????}

????printf("fd 2: %s/n", name);

????

????exit(0);

}

?

運行該程序得到:

文件描述符0、1和2都指向了同一終端/dev/tty1.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性xxxxx| 亚洲欧美在线播放| 九九视频直播综合网| 欧美日韩在线免费观看| 亚洲久久久久久久久久久| 中文字幕在线成人| 97碰碰碰免费色视频| 亚洲天堂男人的天堂| 国产成人精品a视频一区www| 欧美激情按摩在线| 狠狠久久五月精品中文字幕| 国产精品美女无圣光视频| 精品国产999| 久久精品国产欧美亚洲人人爽| 久久久久久亚洲精品| 欧美尤物巨大精品爽| 成人情趣片在线观看免费| 日韩欧美视频一区二区三区| 国产精品久久二区| 欧美午夜女人视频在线| 欧美激情a∨在线视频播放| 亚洲精品日韩激情在线电影| 日韩在线小视频| 亚洲美女av黄| 久久中文字幕视频| 亚洲精品乱码久久久久久按摩观| 国产精品18久久久久久首页狼| 欧美高清在线观看| 亲爱的老师9免费观看全集电视剧| 国产精品色午夜在线观看| 国产精品日韩欧美大师| 这里只有精品在线播放| 国产成人精品在线视频| 欧美精品免费在线观看| 亚洲国内精品在线| 高清欧美性猛交xxxx| 亚洲欧美资源在线| 大胆欧美人体视频| 精品国产福利在线| 亚洲国产成人精品女人久久久| 国产在线播放不卡| 亚洲成人av中文字幕| 97超级碰在线看视频免费在线看| 亚洲欧美国产va在线影院| 最近2019好看的中文字幕免费| 亚洲欧美一区二区三区久久| 青青草原一区二区| 欧美精品videosex牲欧美| 九九热最新视频//这里只有精品| 欧美日韩亚洲一区二| 国产日韩精品在线| 欧美老女人性视频| 欧美精品成人91久久久久久久| 国产偷国产偷亚洲清高网站| 日韩av快播网址| 亚洲电影在线观看| 日本精品一区二区三区在线| 8090成年在线看片午夜| 韩剧1988在线观看免费完整版| 欧美极品少妇xxxxⅹ喷水| 欧美xxxx综合视频| 国产精品女主播| 亚洲精品电影网在线观看| 亚洲女同精品视频| 欧美高清视频免费观看| 国产日韩中文字幕| 日韩欧美国产视频| 久久国内精品一国内精品| 97碰碰碰免费色视频| 国内成人精品一区| 亚洲片在线观看| 国产精品色午夜在线观看| 国产亚洲成av人片在线观看桃| 亚洲天堂免费视频| 一区二区三区视频免费| 一本大道香蕉久在线播放29| 久久综合久中文字幕青草| 久久成人亚洲精品| 亚洲精品国产suv| 精品国产乱码久久久久久虫虫漫画| 久久精品国产精品亚洲| 亚洲精品成人av| 日韩一区二区三区国产| 免费97视频在线精品国自产拍| 国产精品福利在线| 久久久久久com| 欧美色欧美亚洲高清在线视频| 亚洲欧美日韩在线高清直播| 日韩欧美在线看| 国产日韩欧美视频在线| 91在线免费看网站| 播播国产欧美激情| 亚洲色图欧美制服丝袜另类第一页| 日韩成人激情视频| 欧美性色xo影院| 成人情趣片在线观看免费| 日韩精品免费综合视频在线播放| 日本不卡视频在线播放| 亚洲精品免费网站| 91av中文字幕| 亚洲最大的网站| 91精品国产自产在线老师啪| 精品一区电影国产| 98午夜经典影视| 日韩av综合中文字幕| 日韩一区视频在线| 欧美国产日韩一区| 9.1国产丝袜在线观看| 欧美日韩黄色大片| 亚洲热线99精品视频| 久久网福利资源网站| 国产亚洲精品美女久久久| 91精品国产成人www| 国产91精品黑色丝袜高跟鞋| 疯狂做受xxxx欧美肥白少妇| 欧美性猛交xxxx乱大交极品| 色在人av网站天堂精品| 国产精品白嫩美女在线观看| 亚洲成人激情在线| 国产精品入口夜色视频大尺度| 国产精品久久久久久久一区探花| 亚洲男人第一网站| 亚洲国产日韩一区| 久久免费福利视频| 国产一区二区三区在线免费观看| 91九色国产视频| 亚洲国产成人在线播放| 国产日韩欧美视频在线| 91人成网站www| 国产99久久精品一区二区| 久久久久久999| 亚洲第一国产精品| 国产福利精品视频| 精品视频9999| 欧美性xxxxxx| 国产精品久久久久秋霞鲁丝| 亚洲精品97久久| 国产一区视频在线播放| yw.139尤物在线精品视频| 欧美激情中文网| 98精品国产自产在线观看| 精品亚洲夜色av98在线观看| 亚洲一区二区三区毛片| 欧美高清videos高潮hd| 国产精品永久免费在线| 亚洲女人天堂色在线7777| 国产97人人超碰caoprom| 超薄丝袜一区二区| 欧美视频不卡中文| 欧美国产中文字幕| 国产精品老牛影院在线观看| 午夜伦理精品一区| 日韩av黄色在线观看| 久久久免费在线观看| 九色成人免费视频| 日韩中文字幕在线看| 欧美日韩国产黄| 欧美日韩国产区| 国产成人拍精品视频午夜网站| 国产精品一区二区在线| 欧美激情视频三区| 在线色欧美三级视频| 亚洲亚裔videos黑人hd| 欧美中在线观看|