您的位置:首页 > 运维架构 > Linux

Linux用户态编程-伪终端(一)

2016-01-24 19:07 597 查看
最近在看telnet终端登陆的相关程序,了解到了telnet登陆的进程安排。对照UNIX环境高级编程对其中使用伪终端的部分进行了一些学习。

首先,telnet登陆的典型安排如下:



1.telnet client通过connect连接telnet server

2.telnet server 调用accept接受连接请求,并fork子进程1处理与client之间的连接。同时打开伪终端主设备

3.子进程1再fork子进程调用login,同时打开伪终端从设备

4.login处理完验证等处理后,exec登陆shell

5.登陆shell利用伪终端从设备和子进程1之间进行通信

下面是打开伪终端的代码:

ptym_open用于打开伪终端主设备,并通过参数输出对应的伪终端从设备名称

ptys_open用伪终端从设备名打开从设备

grantpt用于更改从设备的节点的权限为用户读写,组写。

unlockpt函数用于准予对伪终端从设备的访问,从而允许应用程序打开该设备。阻止其他进程打开从设备后,建立该设备的应用程序有机会在使用主,从设备之间正确地初始化

这些设备。

有一些用编译宏控制打开的函数,这些函数在Linux系统上一般是存在的,如果对应的系统上支持这些函数,可以通过编译宏将这些函数关闭。如果对应的系统上不存在,可以

用编译宏打开这些函数,同时可以了解这些函数的实现机制。

#include "apue.h"

#include <fcntl.h>

#ifndef _HAS_OPENPT

INT posix_openpt(INT iFlag)

{

INT iFdMaster;

iFdMaster = open("/dev/ptmx",iFlag);

return iFdMaster;

}

#endif

#ifndef _HAS_PTSNAME

CHAR *ptsname(int iFd)

{

int iSlave;

STATIC CHAR szPtsName[16];

if(ioctl(iFd,TIOCGPTN,&iSlave) < 0)

{

return NULL;

}

szPtsName[0] = 0;

snprintf(szPtsName,sizeof(szPtsName),"/dev/pts/%d",iSlave);

return szPtsName;

}

#endif

#ifndef _HAS_GRANTPT

INT grantpt(int iMaster)

{

CHAR *pcPtsName;

pcPtsName = ptsname(iMaster);

return (chmod(pcPtsName,S_IRUSR|S_IWUSR|S_IWGRP);

}

#endif

#ifndef _HAS_UNLOCKPT

INT unlockpt(int iMaster)

{

INT iLock = 0;

return (ioctl(iMaster,TIOCSPTLCK,&iLock));

}

#endif

INT ptym_open(CHAR *pcPtsName,INT iNameLen)

{

CHAR *pcName;

INT iMaster;

strncpy(pcPtsName,"/dev/ptmx",iNameLen);

pcPtsName[iNameLen - 1] = 0;

iMaster = posix_openpt(O_RDWR);

if(iMaster < 0)

{

return -1;

}

if(grantpt(iMaster) < 0)

{

close(iMaster);

return -2;

}

if(unlockpt(iMaster) < 0)

{

close(iMaster);

return -3;

}

if((pcName = ptsname(iMaster)) == NULL)

{

close(iMaster);

return -4;

}

strncpy(pcPtsName,pcName,iNameLen);

pcPtsName[iNameLen - 1] = 0;

return iMaster;

}

INT ptys_open(const CHAR *pcName)

{

int iSlave;

if((iSlave = open(pcName,O_RDWR))<0)

{

return -5;

}

return iSlave;

}

INT main()

{

CHAR szPtsName[16];

INT iMaster,iSlave;

iMaster = ptym_open(szPtsName,sizeof(szPtsName));

if(iMaster < 0)

{

printf("ptym_open err [%d]\n",iMaster);

return iMaster;

}

printf("ptym_open success %s\n",szPtsName);

iSlave = ptys_open(szPtsName);

if(iSlave < 0)

{

printf("ptys_open err [%d]\n",iSlave);

return iSlave;

}

sleep(10);

close(iMaster);

close(iSlave);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: