git: 9front

Download patch

ref: 227af20381a8d3e21f23815893c939969d82d89e
parent: f071cbe5b2c20bf1f526194daaab7fe51211bd54
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Tue Oct 9 11:15:57 EDT 2012

vncv: snarfvers race, silly walks, add -l option for clipboard charset

--- a/sys/man/1/vnc
+++ b/sys/man/1/vnc
@@ -51,6 +51,10 @@
 .I encodings
 ]
 [
+.B -l
+.I charset
+]
+[
 .B -k
 .I keypattern
 ]
@@ -166,6 +170,12 @@
 .BR raw .
 The encodings should be given as a single space-separated argument
 (quoted when using the shell).
+.TP
+.B -l \fIcharset
+sets the character set (see
+.IR tcs (1))
+used by the server to encode clipboard text. The default is
+.B utf-8.
 .TP
 .B -k \fIkeypattern
 add 
--- a/sys/src/cmd/vnc/vncv.c
+++ b/sys/src/cmd/vnc/vncv.c
@@ -2,7 +2,8 @@
 #include "vncv.h"
 #include <libsec.h>
 
-char*	encodings = "copyrect hextile corre rre raw mousewarp";
+char*		charset = "utf-8";
+char*		encodings = "copyrect hextile corre rre raw mousewarp";
 int		bpp12;
 int		shared;
 int		verbose;
@@ -10,6 +11,7 @@
 int		mousefd;
 int		tls;
 
+
 static int	vncstart(Vnc*, int);
 
 enum
@@ -36,7 +38,7 @@
 
 	pid = getpid();
 	for(i = 0; i < NProcs; i++)
-		if(pids[i] != pid)
+		if(pids[i] != 0 && pids[i] != pid)
 			postnote(PNPROC, pids[i], killkin);
 }
 
@@ -72,7 +74,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-csv] host[:n]\n");
+	fprint(2, "usage: vncv [-e encodings] [-k keypattern] [-l charset] [-csv] host[:n]\n");
 	exits("usage");
 }
 
@@ -79,8 +81,8 @@
 void
 main(int argc, char **argv)
 {
-	int p, fd, dfd, cfd, shared;
-	char *keypattern, *addr;
+	int p, dfd, cfd, shared;
+	char *keypattern, *addr, *label;
 	Point d;
 	TLSconn conn;
 
@@ -105,6 +107,9 @@
 	case 'k':
 		keypattern = EARGF(usage());
 		break;
+	case 'l':
+		charset = EARGF(usage());
+		break;
 	default:
 		usage();
 	}ARGEND;
@@ -132,7 +137,8 @@
 	if(vncstart(vnc, shared) < 0)
 		sysfatal("init failure: %r");
 
-	if(initdraw(0, 0, "vncv") < 0)
+	label = smprint("vnc %s", serveraddr);
+	if(initdraw(0, 0, label) < 0)
 		sysfatal("initdraw: %r");
 	display->locking = 1;
 	unlockdisplay(display);
@@ -173,22 +179,15 @@
 	}
 	pids[2] = p;
 
-	fd = open("/dev/label", OWRITE);
-	if(fd >= 0){
-		fprint(fd, "vnc %s", serveraddr);
-		close(fd);
-	}
-	if(access("/dev/snarf", AEXIST) >= 0){
-		switch(p = rfork(RFPROC|RFMEM)){
-		case -1:
-			sysfatal("rfork: %r");
-		default:
-			break;
-		case 0:
-			atexit(shutdown);
-			readkbd(vnc);
-			exits(nil);
-		}
+	switch(p = rfork(RFPROC|RFMEM)){
+	case -1:
+		sysfatal("rfork: %r");
+	default:
+		break;
+	case 0:
+		atexit(shutdown);
+		readkbd(vnc);
+		exits(nil);
 	}
 	pids[3] = p;
 
--- a/sys/src/cmd/vnc/vncv.h
+++ b/sys/src/cmd/vnc/vncv.h
@@ -11,6 +11,7 @@
 extern	uchar	zero[];
 
 /* vncv.c */
+extern	char		*charset;
 extern	char		*encodings;
 extern	int		bpp12;
 extern	Vnc*		vnc;
--- a/sys/src/cmd/vnc/wsys.c
+++ b/sys/src/cmd/vnc/wsys.c
@@ -169,6 +169,42 @@
 	}
 }
 
+static int
+tcs(int fd0, int fd1)
+{
+	int pfd[2];
+
+	if(strcmp(charset, "utf-8") == 0)
+		goto Dup;
+	if(pipe(pfd) < 0)
+		goto Dup;
+	switch(rfork(RFPROC|RFFDG|RFMEM)){
+	case -1:
+		close(pfd[0]);
+		close(pfd[1]);
+		goto Dup;
+	case 0:
+		if(fd0 < 0){
+			dup(pfd[0], 0);
+			dup(fd1, 1);
+			close(fd1);	
+		} else {
+			dup(pfd[0], 1);
+			dup(fd0, 0);
+			close(fd0);	
+		}
+		close(pfd[0]);
+		close(pfd[1]);
+		execl("/bin/tcs", "tcs", fd0 < 0 ? "-f" : "-t", charset, 0);
+		execl("/bin/cat", "cat", 0);
+		_exits(0);
+	}
+	close(pfd[0]);
+	return pfd[1];
+Dup:
+	return dup(fd0 < 0 ? fd1 : fd0, -1);
+}
+
 static int snarffd = -1;
 static ulong snarfvers;
 
@@ -176,14 +212,21 @@
 writesnarf(Vnc *v, long n)
 {
 	uchar buf[8192];
+	int fd, sfd;
 	long m;
-	Biobuf *b;
 
-	if((b = Bopen("/dev/snarf", OWRITE)) == nil){
+	vnclock(v);
+	if((sfd = create("/dev/snarf", OWRITE, 0666)) < 0)
+		fd = -1;
+	else {
+		fd = tcs(-1, sfd);
+		close(sfd);
+	}
+	if(fd < 0){
+		vncunlock(v);
 		vncgobble(v, n);
 		return;
 	}
-
 	while(n > 0){
 		m = n;
 		if(m > sizeof(buf))
@@ -190,11 +233,11 @@
 			m = sizeof(buf);
 		vncrdbytes(v, buf, m);
 		n -= m;
-
-		Bwrite(b, buf, m);
+		write(fd, buf, m);
 	}
-	Bterm(b);
+	close(fd);
 	snarfvers++;
+	vncunlock(v);
 }
 
 char *
@@ -201,7 +244,7 @@
 getsnarf(int *sz)
 {
 	char *snarf, *p;
-	int n, c;
+	int fd, n, c;
 
 	*sz =0;
 	n = 8192;
@@ -208,14 +251,17 @@
 	p = snarf = malloc(n);
 
 	seek(snarffd, 0, 0);
-	while ((c = read(snarffd, p, n)) > 0){
-		p += c;
-		n -= c;
-		*sz += c;
-		if (n == 0){
-			snarf = realloc(snarf, *sz + 8192);
-			n = 8192;
+	if((fd = tcs(snarffd, -1)) >= 0){
+		while((c = read(fd, p, n)) > 0){
+			p += c;
+			n -= c;
+			*sz += c;
+			if (n == 0){
+				snarf = realloc(snarf, *sz + 8192);
+				n = 8192;
+			}
 		}
+		close(fd);
 	}
 	return snarf;
 }
@@ -236,24 +282,22 @@
 	for(;;){
 		sleep(1000);
 
-		dir = dirstat("/dev/snarf");
-		if(dir == nil)	/* this happens under old drawterm */
-			continue;
-		if(dir->qid.vers > snarfvers){
+		vnclock(v);
+		dir = dirfstat(snarffd);
+		if(dir != nil && dir->qid.vers != snarfvers){
+			snarfvers = dir->qid.vers;
+
 			snarf = getsnarf(&len);
 
-			vnclock(v);
 			vncwrchar(v, MCCut);
 			vncwrbytes(v, "pad", 3);
 			vncwrlong(v, len);
 			vncwrbytes(v, snarf, len);
 			vncflush(v);
-			vncunlock(v);
 
 			free(snarf);
-
-			snarfvers = dir->qid.vers;
 		}
 		free(dir);
+		vncunlock(v);
 	}
 }
--