Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 
  4 */
  5
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <unistd.h>
  9#include <errno.h>
 10#include <fcntl.h>
 11#include <string.h>
 12#include <termios.h>
 13#include <sys/stat.h>
 14#include "chan_user.h"
 15#include <os.h>
 16#include <um_malloc.h>
 
 
 17
 18struct pty_chan {
 19	void (*announce)(char *dev_name, int dev);
 20	int dev;
 21	int raw;
 22	struct termios tt;
 23	char dev_name[sizeof("/dev/pts/0123456\0")];
 24};
 25
 26static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
 27{
 28	struct pty_chan *data;
 29
 30	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 31	if (data == NULL)
 32		return NULL;
 33
 34	*data = ((struct pty_chan) { .announce  	= opts->announce,
 35				     .dev  		= device,
 36				     .raw  		= opts->raw });
 37	return data;
 38}
 39
 40static int pts_open(int input, int output, int primary, void *d,
 41		    char **dev_out)
 42{
 43	struct pty_chan *data = d;
 44	char *dev;
 45	int fd, err;
 46
 47	fd = get_pty();
 48	if (fd < 0) {
 49		err = -errno;
 50		printk(UM_KERN_ERR "open_pts : Failed to open pts\n");
 51		return err;
 52	}
 53
 54	if (data->raw) {
 55		CATCH_EINTR(err = tcgetattr(fd, &data->tt));
 56		if (err)
 57			goto out_close;
 58
 59		err = raw(fd);
 60		if (err)
 61			goto out_close;
 62	}
 63
 64	dev = ptsname(fd);
 65	sprintf(data->dev_name, "%s", dev);
 66	*dev_out = data->dev_name;
 67
 68	if (data->announce)
 69		(*data->announce)(dev, data->dev);
 70
 71	return fd;
 72
 73out_close:
 74	close(fd);
 75	return err;
 76}
 77
 78static int getmaster(char *line)
 79{
 80	struct stat buf;
 81	char *pty, *bank, *cp;
 82	int master, err;
 83
 84	pty = &line[strlen("/dev/ptyp")];
 85	for (bank = "pqrs"; *bank; bank++) {
 86		line[strlen("/dev/pty")] = *bank;
 87		*pty = '0';
 88		/* Did we hit the end ? */
 89		if ((stat(line, &buf) < 0) && (errno == ENOENT))
 90			break;
 91
 92		for (cp = "0123456789abcdef"; *cp; cp++) {
 93			*pty = *cp;
 94			master = open(line, O_RDWR);
 95			if (master >= 0) {
 96				char *tp = &line[strlen("/dev/")];
 97
 98				/* verify slave side is usable */
 99				*tp = 't';
100				err = access(line, R_OK | W_OK);
101				*tp = 'p';
102				if (!err)
103					return master;
104				close(master);
105			}
106		}
107	}
108
109	printk(UM_KERN_ERR "getmaster - no usable host pty devices\n");
110	return -ENOENT;
111}
112
113static int pty_open(int input, int output, int primary, void *d,
114		    char **dev_out)
115{
116	struct pty_chan *data = d;
117	int fd, err;
118	char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
119
120	fd = getmaster(dev);
121	if (fd < 0)
122		return fd;
123
124	if (data->raw) {
125		err = raw(fd);
126		if (err) {
127			close(fd);
128			return err;
129		}
130	}
131
132	if (data->announce)
133		(*data->announce)(dev, data->dev);
134
135	sprintf(data->dev_name, "%s", dev);
136	*dev_out = data->dev_name;
137
138	return fd;
139}
140
141const struct chan_ops pty_ops = {
142	.type		= "pty",
143	.init		= pty_chan_init,
144	.open		= pty_open,
145	.close		= generic_close,
146	.read		= generic_read,
147	.write		= generic_write,
148	.console_write	= generic_console_write,
149	.window_size	= generic_window_size,
150	.free		= generic_free,
151	.winch		= 0,
152};
153
154const struct chan_ops pts_ops = {
155	.type		= "pts",
156	.init		= pty_chan_init,
157	.open		= pts_open,
158	.close		= generic_close,
159	.read		= generic_read,
160	.write		= generic_write,
161	.console_write	= generic_console_write,
162	.window_size	= generic_window_size,
163	.free		= generic_free,
164	.winch		= 0,
165};
v3.1
 
  1/*
  2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  3 * Licensed under the GPL
  4 */
  5
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <unistd.h>
  9#include <errno.h>
 10#include <fcntl.h>
 11#include <string.h>
 12#include <termios.h>
 13#include <sys/stat.h>
 14#include "chan_user.h"
 15#include "kern_constants.h"
 16#include "os.h"
 17#include "um_malloc.h"
 18#include "user.h"
 19
 20struct pty_chan {
 21	void (*announce)(char *dev_name, int dev);
 22	int dev;
 23	int raw;
 24	struct termios tt;
 25	char dev_name[sizeof("/dev/pts/0123456\0")];
 26};
 27
 28static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
 29{
 30	struct pty_chan *data;
 31
 32	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 33	if (data == NULL)
 34		return NULL;
 35
 36	*data = ((struct pty_chan) { .announce  	= opts->announce,
 37				     .dev  		= device,
 38				     .raw  		= opts->raw });
 39	return data;
 40}
 41
 42static int pts_open(int input, int output, int primary, void *d,
 43		    char **dev_out)
 44{
 45	struct pty_chan *data = d;
 46	char *dev;
 47	int fd, err;
 48
 49	fd = get_pty();
 50	if (fd < 0) {
 51		err = -errno;
 52		printk(UM_KERN_ERR "open_pts : Failed to open pts\n");
 53		return err;
 54	}
 55
 56	if (data->raw) {
 57		CATCH_EINTR(err = tcgetattr(fd, &data->tt));
 58		if (err)
 59			goto out_close;
 60
 61		err = raw(fd);
 62		if (err)
 63			goto out_close;
 64	}
 65
 66	dev = ptsname(fd);
 67	sprintf(data->dev_name, "%s", dev);
 68	*dev_out = data->dev_name;
 69
 70	if (data->announce)
 71		(*data->announce)(dev, data->dev);
 72
 73	return fd;
 74
 75out_close:
 76	close(fd);
 77	return err;
 78}
 79
 80static int getmaster(char *line)
 81{
 82	struct stat buf;
 83	char *pty, *bank, *cp;
 84	int master, err;
 85
 86	pty = &line[strlen("/dev/ptyp")];
 87	for (bank = "pqrs"; *bank; bank++) {
 88		line[strlen("/dev/pty")] = *bank;
 89		*pty = '0';
 90		/* Did we hit the end ? */
 91		if ((stat(line, &buf) < 0) && (errno == ENOENT))
 92			break;
 93
 94		for (cp = "0123456789abcdef"; *cp; cp++) {
 95			*pty = *cp;
 96			master = open(line, O_RDWR);
 97			if (master >= 0) {
 98				char *tp = &line[strlen("/dev/")];
 99
100				/* verify slave side is usable */
101				*tp = 't';
102				err = access(line, R_OK | W_OK);
103				*tp = 'p';
104				if (!err)
105					return master;
106				close(master);
107			}
108		}
109	}
110
111	printk(UM_KERN_ERR "getmaster - no usable host pty devices\n");
112	return -ENOENT;
113}
114
115static int pty_open(int input, int output, int primary, void *d,
116		    char **dev_out)
117{
118	struct pty_chan *data = d;
119	int fd, err;
120	char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
121
122	fd = getmaster(dev);
123	if (fd < 0)
124		return fd;
125
126	if (data->raw) {
127		err = raw(fd);
128		if (err) {
129			close(fd);
130			return err;
131		}
132	}
133
134	if (data->announce)
135		(*data->announce)(dev, data->dev);
136
137	sprintf(data->dev_name, "%s", dev);
138	*dev_out = data->dev_name;
139
140	return fd;
141}
142
143const struct chan_ops pty_ops = {
144	.type		= "pty",
145	.init		= pty_chan_init,
146	.open		= pty_open,
147	.close		= generic_close,
148	.read		= generic_read,
149	.write		= generic_write,
150	.console_write	= generic_console_write,
151	.window_size	= generic_window_size,
152	.free		= generic_free,
153	.winch		= 0,
154};
155
156const struct chan_ops pts_ops = {
157	.type		= "pts",
158	.init		= pty_chan_init,
159	.open		= pts_open,
160	.close		= generic_close,
161	.read		= generic_read,
162	.write		= generic_write,
163	.console_write	= generic_console_write,
164	.window_size	= generic_window_size,
165	.free		= generic_free,
166	.winch		= 0,
167};