[oe-commits] org.oe.dev pty: add Andrews tty forwarder

koen commit openembedded-commits at lists.openembedded.org
Thu Nov 1 16:02:55 UTC 2007


pty: add Andrews tty forwarder

Author: koen at openembedded.org
Branch: org.openembedded.dev
Revision: 7fe4c06ce30cce4695a8e59d2e11f23206fd87c0
ViewMTN: http://monotone.openembedded.org/revision/info/7fe4c06ce30cce4695a8e59d2e11f23206fd87c0
Files:
1
packages/gsm/pty
packages/gsm/pty/pty.c
packages/gsm/pty_0.0.bb
Diffs:

#
# mt diff -r67a297cfbe76997f34d17285c62fb29571b443b7 -r7fe4c06ce30cce4695a8e59d2e11f23206fd87c0
#
# 
# 
# add_dir "packages/gsm/pty"
# 
# add_file "packages/gsm/pty/pty.c"
#  content [7a2613f0b781a75de9ea3f481fc8d3790867d26e]
# 
# add_file "packages/gsm/pty_0.0.bb"
#  content [8ac2b04ce6b9a1f198e37c508f7a21b989c2d21c]
# 
============================================================
--- packages/gsm/pty/pty.c	7a2613f0b781a75de9ea3f481fc8d3790867d26e
+++ packages/gsm/pty/pty.c	7a2613f0b781a75de9ea3f481fc8d3790867d26e
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007 OpenedHand, Ltd.
+ * Contact: <andrew at o-hand.com>
+ *
+ * This file is licensed under the terms of GNU GPL v2.
+ *
+ * $ pty [<hostname|ip> <port>]
+ * Opens a new pseudo terminal and forwards data between standard input
+ * and the pty and between the pty and standard output.  If a hostname and
+ * port number are given, reads and writes to the socket instead of
+ * standard input or output.  Path to the slave pty is printed on standard
+ * error.
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#define CHECK(val, name)	\
+	if (val == -1) {	\
+		fprintf(stderr, #name ": %s (%i)\n", strerror(errno), errno);\
+		return -errno;	\
+	}
+
+#define min(a, b)	((a) < (b) ? (a) : (b))
+#define max(a, b)	((a) > (b) ? (a) : (b))
+
+static int forward2(int in0, int out0, int in1, int out1) {
+	int inpos = 0, inlen = 0, outpos = 0, outlen = 0, ret, n;
+	fd_set rfds, wfds;
+	char in[0x100], out[0x100];
+
+	n = max(max(in0, in1), max(out0, out1)) + 1;
+	while (1) {
+		FD_ZERO(&rfds);
+		FD_ZERO(&wfds);
+		if (inlen < sizeof(in))
+			FD_SET(in0, &rfds);
+		if (outlen < sizeof(out))
+			FD_SET(in1, &rfds);
+		if (inlen)
+			FD_SET(out0, &wfds);
+		if (outlen)
+			FD_SET(out1, &wfds);
+		CHECK(select(n, &rfds, &wfds, 0, 0), select);
+
+		if (FD_ISSET(in0, &rfds)) {
+			ret = (inpos + inlen) & (sizeof(in) - 1);
+			ret = read(in0, in + ret,
+					sizeof(in) - max(ret, inlen));
+			CHECK(ret, read(0));
+			if (!ret)
+				return 0;
+			inlen += ret;
+		}
+		if (FD_ISSET(in1, &rfds)) {
+			ret = (outpos + outlen) & (sizeof(out) - 1);
+			ret = read(in1, out + ret,
+					sizeof(out) - max(ret, outlen));
+			if (ret > 0)
+				outlen += ret;
+		}
+		if (FD_ISSET(out0, &wfds)) {
+			ret = write(out0, in + inpos,
+					min(sizeof(in) - inpos, inlen));
+			CHECK(ret, write(pty));
+			inlen -= ret;
+			inpos += ret;
+			inpos &= sizeof(in) - 1;
+		}
+		if (FD_ISSET(out1, &wfds)) {
+			ret = write(out1, out + outpos,
+					min(sizeof(out) - outpos, outlen));
+			CHECK(ret, write(1));
+			outlen -= ret;
+			outpos += ret;
+			outpos &= sizeof(out) - 1;
+		}
+	}
+
+	return pause();
+}
+
+int main(int argc, char *argv[], char **envp) {
+	int sock, fd;
+	struct sockaddr_in sa;
+	struct hostent *hi;
+
+	fd = posix_openpt(O_RDWR | O_NOCTTY);
+	CHECK(fd, open);
+	CHECK(grantpt(fd), grantpt);
+	CHECK(unlockpt(fd), unlockpt);
+
+	fprintf(stderr, "%s\n", ptsname(fd));
+#if 0
+	/* Connect stdin & stdout with a pty */
+	CHECK(close(0), close(0));
+	CHECK(close(1), close(1));
+	CHECK(dup(fd), dup(0));
+	CHECK(dup(fd), dup(1));
+	return pause();
+#endif
+	if (argc != 3)
+		return forward2(0, fd, fd, 1);
+
+#if 0
+	/* Connect a sub-process with a pty */
+	for (len = 0, i = 1; i < argc; i ++)
+		len += strlen(argv[i]) + 4;
+	param = malloc(len);
+	strcpy(param, argv[1]);
+	for (i = 2; i < argc; i ++)
+		sprintf(param + strlen(param), " \"%s\"", argv[i]);
+	i = fileno(popen(param, O_RDWR));
+	CHECK(i, popen);
+	free(param);
+	return forward2(i, fd, fd, i);
+#endif
+
+	/* Connect a TCP socket with a pty */
+	hi = gethostbyname(argv[1]);
+	if (!hi) {
+		errno = h_errno;
+		CHECK(-1, gethostbyname);
+	}
+	sa.sin_family = hi->h_addrtype;
+	memcpy(&sa.sin_addr.s_addr, hi->h_addr_list[0], hi->h_length);
+	sa.sin_port = htons(strtol(argv[2], 0, 0));
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+
+	CHECK(sock, socket);
+	CHECK(connect(sock, (struct sockaddr *) &sa, sizeof(sa)), connect);
+	return forward2(sock, fd, fd, sock);
+}
============================================================
--- packages/gsm/pty_0.0.bb	8ac2b04ce6b9a1f198e37c508f7a21b989c2d21c
+++ packages/gsm/pty_0.0.bb	8ac2b04ce6b9a1f198e37c508f7a21b989c2d21c
@@ -0,0 +1,15 @@
+DESCRIPTION = "Forwards a socket to a tty"
+LICENSE = "GPLv2"
+
+SRC_URI = "file://pty.c"
+
+do_compile() {
+        cp ${WORKDIR}/*.c ${S}/
+	${CC} pty.c -o pty -I${STAGING_INCDIR} -L${STAGING_LIBDIR}
+}
+
+do_install() {
+        install -d ${D}${bindir}
+	install -m 0755 pty ${D}${bindir}/
+}
+






More information about the Openembedded-commits mailing list