- 浏览: 141078 次
文章分类
最新评论
尽管控制终端的名字在多数 UNIX 系统上都是 /dev/tty,不过为了可移植性,POSIX.1 还是提供了一个可用来确定控制终端名字的运行时函数 ctermid。
如果参数 ptr 非空,则被认为是一个指向长度至少为 L_ctermid 字节(定义在 <stdio.h> 中)的数组的指针,终端名也会被存储在该数组中。若 ptr 是一个空指针,则由函数为数组(通常作为静态变量)分配空间。
ctermid 函数的实现大致如下。
isatty 和 ttyname 也是常用的终端函数。如果文件描述符引用一个终端设备,则 isatty 返回真。ttyname 返回的则是该文件描述符打开的终端设备的路径名。
下面代码是 isatty 的实现。我们只使用了一个终端专用函数,并查看其返回值来确认。
测试结果如下:
ttyname 函数的实现就比较长,因为它要搜索所有设备表项来寻找匹配项。
这里通过读取 /dev 目录来寻找具有相同设备号和 i 节点编号的表项。另外,终端名可能在 /dev 的子目录中,所以也需要搜索。这里还跳过了少数几个可能会产生不正确结果或奇怪结果的目录:/dev/.、/dev/.. 和 /dev/fd。同时也跳过了一些别名:/dev/stdin、/dev/stdout 和 /dev/stderr,因为它们是 /dev/fd 目录中文件的符号链接。
运行结果如下:
#include <stdio.h> char *ctermid(char *ptr); /* 返回值:若成功,返回指向终端名的指针;否则,返回指向空字符串的指针 */
如果参数 ptr 非空,则被认为是一个指向长度至少为 L_ctermid 字节(定义在 <stdio.h> 中)的数组的指针,终端名也会被存储在该数组中。若 ptr 是一个空指针,则由函数为数组(通常作为静态变量)分配空间。
ctermid 函数的实现大致如下。
#include <stdio.h> #include <string.h> static char ctermName[L_ctermid]; char *myCtermid(char *ptr){ if(ptr == NULL) ptr = ctermName; return strcpy(ptr, "/dev/tty"); }
isatty 和 ttyname 也是常用的终端函数。如果文件描述符引用一个终端设备,则 isatty 返回真。ttyname 返回的则是该文件描述符打开的终端设备的路径名。
#include <unistd.h> int isatty(int fd); /* 返回值:若为终端设备,返回 1;否则,返回 0 */ char *ttyname(int fd); /* 返回值:指向终端路径名的指针;若出错,返回 NULL */
下面代码是 isatty 的实现。我们只使用了一个终端专用函数,并查看其返回值来确认。
#include <stdio.h> #include <termios.h> int myIsatty(int fd){ struct termios ts; return (tcgetattr(fd, &ts) != -1); // true if no error (is a tty) } int main(void){ printf("fd 0: %s\n", myIsatty(0)? "tty": "not a tty"); printf("fd 1: %s\n", myIsatty(1)? "tty": "not a tty"); printf("fd 2: %s\n", myIsatty(2)? "tty": "not a tty"); return 0; }
测试结果如下:
$ ./myIsatty.out fd 0: tty fd 1: tty fd 2: tty $ ./myIsatty.out </etc/passwd 2>/dev/null fd 0: not a tty fd 1: tty fd 2: not a tty
ttyname 函数的实现就比较长,因为它要搜索所有设备表项来寻找匹配项。
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.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){ int 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; struct devdir *ddp = malloc(sizeof(struct devdir)); if(ddp == NULL) return; if((ddp->d_name=strdup(dirname)) == NULL){ free(ddp); return; } ddp->d_next = NULL; if(head == NULL){ head = ddp; tail = ddp; }else{ tail->d_next = ddp; tail = ddp; } } static void cleanup(void){ struct devdir *nddp; while(head != NULL){ nddp = head->d_next; free(head->d_name); free(head); head = nddp; } tail = NULL; } static char *searchdir(char *dirname, struct stat *fdstat){ strcpy(pathname, dirname); strcat(pathname, "/"); int len = strlen(pathname); DIR *dirp = opendir(dirname); struct dirent *itemp; while((itemp=readdir(dirp)) != NULL){ strncpy(pathname+len, itemp->d_name, _POSIX_PATH_MAX-len); /* skip aliases */ if(strcmp(pathname, "/dev/stdin")==0 || strcmp(pathname, "/dev/stdout")==0 || strcmp(pathname, "/dev/stderr")==0) continue; struct stat itemstat; if(stat(pathname, &itemstat) < 0) continue; if(S_ISDIR(itemstat.st_mode)){ add(pathname); continue; } if((itemstat.st_ino==fdstat->st_ino) && (itemstat.st_dev==fdstat->st_dev)){ closedir(dirp); return pathname; } } closedir(dirp); return NULL; } char *myTtyname(int fd){ if(isatty(fd) == 0) return NULL; struct stat fdstat; if(fstat(fd, &fdstat)<0 || S_ISCHR(fdstat.st_mode)==0) return NULL; char *name = searchdir("/dev", &fdstat); if(name == NULL){ struct devdir *ddp; for(ddp=head; ddp!=NULL; ddp=ddp->d_next) if((name=searchdir(ddp->d_name, &fdstat)) != NULL) break; } cleanup(); return name; } void test(int fd){ char *name = NULL; if(isatty(fd)){ if((name=myTtyname(fd)) == NULL) name = "undefined"; }else{ name = "not a tty"; } printf("fd %d: %s\n", fd, name); } int main(void){ test(STDIN_FILENO); test(1); test(2); exit(0); }
这里通过读取 /dev 目录来寻找具有相同设备号和 i 节点编号的表项。另外,终端名可能在 /dev 的子目录中,所以也需要搜索。这里还跳过了少数几个可能会产生不正确结果或奇怪结果的目录:/dev/.、/dev/.. 和 /dev/fd。同时也跳过了一些别名:/dev/stdin、/dev/stdout 和 /dev/stderr,因为它们是 /dev/fd 目录中文件的符号链接。
运行结果如下:
# ./myTtyname.out </dev/console 2>/dev/null fd 0: /dev/console fd 1: /dev/pts/1 fd 2: not a tty
发表评论
-
打开伪终端设备
2018-07-09 20:50 1249在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1535伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 792多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 944终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
波特率和行控制函数
2018-05-22 07:53 935虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 707tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 810终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 433终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 575在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 944在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 612在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 490消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 481有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 413FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 383管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 879readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 451POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 588记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 433UNIX 系统中,守护进程遵循下列通用惯例。 ... -
守护进程编写规则与出错记录
2017-12-26 01:53 450在编写守护进程程 ...
相关推荐
在IT行业中,终端标识是确保网络安全性、进行设备管理和数据保护的重要环节。本文将深入探讨“行业分类-设备装置-实现终端标识的方法、系统及管理平台”这一主题,旨在为读者提供全面的理解和实践指导。 首先,终端...
标题 "电信设备-关联证件信息与移动终端标识信息的方法及装置.zip" 提供的信息表明,这个压缩包包含的内容是关于电信行业中如何将个人证件信息与移动设备(如智能手机)的唯一标识信息相互关联的技术方案。...
【移动智能终端补充设备标识体系统一调用SDK】是中国信息通信研究院泰尔终端实验室与移动安全联盟共同研发的一款软件开发工具包,主要用于移动应用开发者访问移动智能终端的补充设备标识体系。该SDK遵循电信终端产业...
【移动智能终端补充设备标识体系统一调用SDK开发者说明文档v1.81】是为中国信息通信研究院泰尔终端实验室和移动安全联盟所编写的,文档详细介绍了如何使用SDK来实现移动智能终端的设备标识体系统调用。此SDK遵循电信...
协议中的数据格式有严格的结构,例如GPS信息帧包含信息标识、终端标志、日期时间等字段,而透传数据帧则包括信息标识、发送方标志、数据帧标志、数据帧长度和内容。 总的来说,铱星终端点对多点协议是实现远程通信...
销售点POS终端应用规范++终端唯一标识技术方案(V1.2)
【移动智能终端补充设备标识体系统一调用SDK开发者说明文档v1.0.291】是中国信息通信研究院泰尔终端实验室和移动安全联盟共同提供的SDK,旨在为开发者提供集成设备厂商接口的能力,以便获取移动智能终端的补充设备...
移动智能终端补充设备标识体系统一调用SDK是一款由中国信息通信研究院泰尔终端实验室和移动安全联盟共同开发的工具,旨在统一移动设备的标识管理,提高网络安全和隐私保护。该SDK遵循电信终端产业协会(TAF)和移动...
1. **终端个人化数据**:描述了终端需要个性化设置的数据项,如终端标识等。 2. **终端公私钥**:介绍了用于加密和解密的关键数据——公钥和私钥的管理方式。 3. **终端个人化流程**:给出了终端进行个人化配置的...
- **GPS信息输出**:当接收到GPS数据时,终端以固定的20字节格式通过串口输出,包含信息标识、发送方终端标志、日期、UTC时间、纬度、经度、速度、方向和高度等信息。 - **透传数据包输出**:远端终端的用户数据...
10. 终端主密钥下载联机报文:报文包含多个域,例如消息类型、位图、系统跟踪号、日期、时间、终端标识码、批次号等。这些报文域在主密钥更换过程中起着关键的请求与响应作用。 11. 传输密钥卡的使用方法:具体步骤...
- 对于第二个电话接口(TEL2),同样勾选“使能物理终端标识”,在物理终端标识处输入“A1”,关联物理端口选择“2”。 3. **保存设置**:完成每个端口的设置后,都需要点击保存按钮使其生效。 #### 四、配置保存...
《TSCA 002-2018 集装箱智能终端编码与标识规范》是中国在物联网技术应用于集装箱运输领域的一项重要标准。它旨在通过规范化的编码和标识系统,提高集装箱物流的信息化水平,提升货物追踪的准确性和效率,确保全球...
- 被动扫描:利用User-Agent信息,即浏览器发送的标识,ND ACE在用户打开浏览器时被动获取设备的操作系统、版本等信息。 - 主动扫描:使用Nmap工具,能主动发现并扫描终端,获取详细的指纹信息,如IP地址、产品...
地址设置涉及低八位和高八位的地址位,其中高八位的第4位是双向终端标志位,第6、7、8位用于地区县代码。设置地址通常使用计算器将十进制地址转换为二进制,然后根据二进制表示来调整地址开关。 此外,还需要设置...
- 例如,对于定位请求消息,需包含终端标识、请求类型等信息。 - **错误处理**: - 设计健壮的错误检测与恢复机制,确保在出现异常情况时能够正确处理并恢复正常操作。 - 如在网络中断后重新建立连接、数据丢失后...
移动智能终端补充设备标识体系统一调用SDK是一款由中国信息通信研究院泰尔终端实验室和移动安全联盟共同研发的工具,主要服务于移动应用开发者。这个SDK遵循电信终端产业协会(TAF)和移动安全联盟(MSA)联合制定的...
中国电信发布的这份AI终端白皮书标志着其在人工智能领域的重要战略部署和规划。白皮书重点介绍了中国电信对AI手机终端的理解与需求,并从AI算力、AI能力和AI应用方面对人工智能手机进行了规范化定义。在当前的行业...
【手持终端程序与卡西欧条码终端编程详解】 在当今的物流、零售、仓储等行业中,手持终端已经成为数据采集和管理的重要工具。卡西欧作为知名的电子设备制造商,其手持终端产品因其可靠性和易用性而备受青睐。本文将...
本标准对接入银联自建POS中心(如中国银联POS收单处理平台)的销售点终端应遵循的应用层规范进行了定义,包括终端管理功能、交易功能、终端界面、交易处理流程以及终端与POS中心之间的交易接口等。