pty.c

来自「linux 内核源代码」· C语言 代码 · 共 168 行

C
168
字号
/* * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <string.h>#include <termios.h>#include <sys/stat.h>#include "chan_user.h"#include "kern_constants.h"#include "os.h"#include "um_malloc.h"#include "user.h"struct pty_chan {	void (*announce)(char *dev_name, int dev);	int dev;	int raw;	struct termios tt;	char dev_name[sizeof("/dev/pts/0123456\0")];};static void *pty_chan_init(char *str, int device, const struct chan_opts *opts){	struct pty_chan *data;	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);	if (data == NULL)		return NULL;	*data = ((struct pty_chan) { .announce  	= opts->announce,				     .dev  		= device,				     .raw  		= opts->raw });	return data;}static int pts_open(int input, int output, int primary, void *d,		    char **dev_out){	struct pty_chan *data = d;	char *dev;	int fd, err;	fd = get_pty();	if (fd < 0) {		err = -errno;		printk(UM_KERN_ERR "open_pts : Failed to open pts\n");		return err;	}	if (data->raw) {		CATCH_EINTR(err = tcgetattr(fd, &data->tt));		if (err)			goto out_close;		err = raw(fd);		if (err)			goto out_close;	}	dev = ptsname(fd);	sprintf(data->dev_name, "%s", dev);	*dev_out = data->dev_name;	if (data->announce)		(*data->announce)(dev, data->dev);	return fd;out_close:	close(fd);	return err;}static int getmaster(char *line){	struct stat buf;	char *pty, *bank, *cp;	int master, err;	pty = &line[strlen("/dev/ptyp")];	for (bank = "pqrs"; *bank; bank++) {		line[strlen("/dev/pty")] = *bank;		*pty = '0';		/* Did we hit the end ? */		if ((stat(line, &buf) < 0) && (errno == ENOENT))			break;		for (cp = "0123456789abcdef"; *cp; cp++) {			*pty = *cp;			master = open(line, O_RDWR);			if (master >= 0) {				char *tp = &line[strlen("/dev/")];				/* verify slave side is usable */				*tp = 't';				err = access(line, R_OK | W_OK);				*tp = 'p';				if (!err)					return master;				close(master);			}		}	}	printk(UM_KERN_ERR "getmaster - no usable host pty devices\n");	return -ENOENT;}static int pty_open(int input, int output, int primary, void *d,		    char **dev_out){	struct pty_chan *data = d;	int fd, err;	char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";	fd = getmaster(dev);	if (fd < 0)		return fd;	if (data->raw) {		err = raw(fd);		if (err) {			close(fd);			return err;		}	}	if (data->announce)		(*data->announce)(dev, data->dev);	sprintf(data->dev_name, "%s", dev);	*dev_out = data->dev_name;	return fd;}const struct chan_ops pty_ops = {	.type		= "pty",	.init		= pty_chan_init,	.open		= pty_open,	.close		= generic_close,	.read		= generic_read,	.write		= generic_write,	.console_write	= generic_console_write,	.window_size	= generic_window_size,	.free		= generic_free,	.winch		= 0,};const struct chan_ops pts_ops = {	.type		= "pts",	.init		= pty_chan_init,	.open		= pts_open,	.close		= generic_close,	.read		= generic_read,	.write		= generic_write,	.console_write	= generic_console_write,	.window_size	= generic_window_size,	.free		= generic_free,	.winch		= 0,};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?