(3)基于Linux的伪终端
Linux提供访问伪终端的BSD方法,所以可以使用上面代码中同样的函数在Linux上面进行工作。然而,Linux也支持使用/dev/ptmx的伪终端克隆接口(这不是STREAMS设备)。克隆接口要求额外的步骤来辨别和解锁一个slave设备。在Linux上面我们可以使用访问伪终端设备的函数参见下面的代码。
用于Linux的伪终端打开函数
#include "apue.h"
#include <fcntl.h>
#ifndef _HAS_OPENPT
int posix_openpt(int oflag)
{
int fdm;
fdm = open("/dev/ptmx", oflag);
return(fdm);
}
#endif
#ifndef _HAS_PTSNAME
char * ptsname(int fdm)
{
int sminor;
static char pts_name[16];
if (ioctl(fdm, TIOCGPTN, &sminor) < 0)
return(NULL);
snprintf(pts_name, sizeof(pts_name), "/dev/pts/%d", sminor);
return(pts_name);
}
#endif
#ifndef _HAS_GRANTPT
int grantpt(int fdm)
{
char *pts_name;
pts_name = ptsname(fdm);
return(chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP));
}
#endif
#ifndef _HAS_UNLOCKPT
int unlockpt(int fdm)
{
int lock = 0;
return(ioctl(fdm, TIOCSPTLCK, &lock));
}
#endif
int ptym_open(char *pts_name, int pts_namesz)
{
char *ptr;
int fdm;
/*
* Return the name of the master device so that on failure
* the caller can print an error message. Null terminate
* to handle case where string length > pts_namesz.
*/
strncpy(pts_name, "/dev/ptmx", pts_namesz);
pts_name[pts_namesz - 1] = '\0';
fdm = posix_openpt(O_RDWR);
if (fdm < 0)
return(-1);
if (grantpt(fdm) < 0) { /* grant access to slave */
close(fdm);
return(-2);
}
if (unlockpt(fdm) < 0) { /* clear slave's lock flag */
close(fdm);
return(-3);
}
if ((ptr = ptsname(fdm)) == NULL) { /* get slave's name */
close(fdm);
return(-4);
}
/*
* Return name of slave. Null terminate to handle case
* where strlen(ptr) > pts_namesz.
*/
strncpy(pts_name, ptr, pts_namesz);
pts_name[pts_namesz - 1] = '\0';
return(fdm); /* return fd of master */
}
int ptys_open(char *pts_name)
{
int fds;
if ((fds = open(pts_name, O_RDWR)) < 0)
return(-5);
return(fds);
}
在Linux上面PTY slave设备已经被tty组拥有,所以我们grantpt中需要做的只是保证权限的正确。
网友评论