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);
}
}
--
⑨