code: drawterm

Download patch

ref: ee5fc884bd37db9cba56d603b8d4e30b0cc78083
parent: d6701f937604395ceae97ea86d7bfcb427c7d99e
author: Russ Cox <rsc@swtch.com>
date: Mon Nov 7 20:35:49 EST 2005

fixes

--- a/Make.unix
+++ b/Make.unix
@@ -5,7 +5,7 @@
 AS=as
 RANLIB=ranlib
 CC=gcc
-CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -D_THREAD_SAFE $(PTHREAD)
+CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -D_THREAD_SAFE $(PTHREAD) -O2
 O=o
 OS=posix
 GUI=x11
--- a/Make.win32
+++ b/Make.win32
@@ -3,13 +3,13 @@
 # on another platform.  Otherwise the binaries are just
 # named gcc, etc.
 
-MING=mingw32-
+MING=i586-mingw32msvc-
 #MING=
 AR=$(MING)ar
 CC=$(MING)gcc
 AS=$(MING)as
 RANLIB=$(MING)ranlib
-CFLAGS=-Wall -Wno-missing-braces -I$(ROOT)/include -I$(ROOT) -I$(ROOT)/kern -c -D_X86_ -DIS_32 -DWINDOWS
+CFLAGS=-Wall -Wno-missing-braces -I$(ROOT)/include -I$(ROOT) -I$(ROOT)/kern -c -D_X86_ -DIS_32 -DWINDOWS -O2
 O=o
 FS=fs-win32
 IP=win32
@@ -16,7 +16,7 @@
 OS=win32
 GUI=win32
 LDFLAGS=-mwindows
-LDADD=-lkernel32 -ladvapi32 -lgdi32 -lmpr -lwsock32
+LDADD=-lkernel32 -ladvapi32 -lgdi32 -lmpr -lwsock32 -lmsvcrt -lmingw32
 TARG=drawterm.exe
 
 # Windows via MSVC
--- a/cpu.c
+++ b/cpu.c
@@ -380,9 +380,8 @@
 		return fd;
 
 	/* exchange random numbers */
-	srand(truerand());
 	for(i = 0; i < 4; i++)
-		key[i] = rand();
+		key[i] = fastrand();
 	if(write(fd, key, 4) != 4)
 		return -1;
 	if(readn(fd, key+12, 4) != 4)
--- a/gui-win32/Makefile
+++ b/gui-win32/Makefile
@@ -7,8 +7,7 @@
 	cload.$O\
 	draw.$O\
 	load.$O\
-	screen.$O\
-	wstrtoutf.$O
+	screen.$O
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- a/include/dtos.h
+++ b/include/dtos.h
@@ -5,6 +5,7 @@
 #	endif
 #elif defined(WINDOWS)
 #	include "9windows.h"
+#	define main mymain
 #else
 #	error "Define an OS"
 #endif
--- a/include/lib.h
+++ b/include/lib.h
@@ -15,11 +15,6 @@
 #define log2	liblog2
 #define log	liblog
 #define reboot	libreboot
-#define srand	dtsrand
-#define rand	dtrand
-#define nrand	dtnrand
-#define lrand	dtlrand
-#define lnrand	dtlnrand
 #undef timeradd
 #define timeradd	xtimeradd
 
@@ -239,13 +234,6 @@
 extern	int	fmtprint(Fmt*, char*, ...);
 extern	int	fmtvprint(Fmt*, char*, va_list);
 extern	void*	mallocz(ulong, int);
-
-extern	void	srand(long);
-extern	int	rand(void);
-extern	int	nrand(int);
-extern	long	lrand(void);
-extern	long	lnrand(long);
-extern	double	frand(void);
 
 extern	ulong	getcallerpc(void*);
 extern	char*	cleanname(char*);
--- a/kern/devcons.c
+++ b/kern/devcons.c
@@ -60,7 +60,6 @@
 char	*sysname;
 vlong	fasthz;
 
-static void	seedrand(void);
 static int	readtime(ulong, char*, int);
 static int	readbintime(char*, int);
 static int	writetime(char*, int);
@@ -985,30 +984,6 @@
 	devremove,
 	devwstat,
 };
-
-static	ulong	randn;
-
-static void
-seedrand(void)
-{
-	randomread((void*)&randn, sizeof(randn));
-}
-
-int
-xnrand(int n)
-{
-	if(randn == 0)
-		seedrand();
-	randn = randn*1103515245 + 12345 + fastticks(0);
-	return (randn>>16) % n;
-}
-
-int
-rand(void)
-{
-	xnrand(1);
-	return randn;
-}
 
 static uvlong uvorder = (uvlong) 0x0001020304050607ULL;
 
--- a/kern/devip-win32.c
+++ b/kern/devip-win32.c
@@ -46,13 +46,14 @@
 
 	fd = socket(AF_INET, type, 0);
 	if(fd < 0)
-		error(sys_errlist[errno]);
+		oserror();
 
 	one = 1;
-	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0)
-		print("setsockopt: %s", sys_errlist[errno]);
+	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
+		oserrstr();
+		print("setsockopt: %s\n", up->errstr);
+	}
 
-
 	return fd;
 }
 
@@ -68,7 +69,7 @@
 	hnputl(&sin.sin_addr.s_addr, raddr);
 
 	if(connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
-		error(sys_errlist[errno]);
+		oserror();
 }
 
 void
@@ -79,7 +80,7 @@
 
 	len = sizeof(sin);
 	if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0)
-		error(sys_errlist[errno]);
+		oserror();
 
 	if(sin.sin_family != AF_INET || len != sizeof(sin))
 		error("not AF_INET");
@@ -92,7 +93,7 @@
 so_listen(int fd)
 {
 	if(listen(fd, 5) < 0)
-		error(sys_errlist[errno]);
+		oserror();
 }
 
 int
@@ -104,7 +105,7 @@
 	len = sizeof(sin);
 	nfd = accept(fd, (struct sockaddr*)&sin, &len);
 	if(nfd < 0)
-		error(sys_errlist[errno]);
+		oserror();
 
 	if(sin.sin_family != AF_INET || len != sizeof(sin))
 		error("not AF_INET");
@@ -121,8 +122,10 @@
 	struct sockaddr_in sin;
 
 	one = 1;
-	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0)
-		print("setsockopt: %s", sys_errlist[errno]);
+	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
+		oserrstr();
+		print("setsockopt: %s", up->errstr);
+	}
 
 	if(su) {
 		for(i = 600; i < 1024; i++) {
@@ -133,7 +136,7 @@
 			if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) >= 0)	
 				return;
 		}
-		error(sys_errlist[errno]);
+		oserror();
 	}
 
 	memset(&sin, 0, sizeof(sin));
@@ -141,7 +144,7 @@
 	hnputs(&sin.sin_port, port);
 
 	if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
-		error(sys_errlist[errno]);
+		oserror();
 }
 
 int
--- a/kern/devip.c
+++ b/kern/devip.c
@@ -228,6 +228,7 @@
 	Conv *cv, *lcv;
 
 	omode &= 3;
+	perm = 0;
 	switch(omode) {
 	case OREAD:
 		perm = 4;
--- a/kern/devroot.c
+++ b/kern/devroot.c
@@ -181,6 +181,8 @@
 			t = c->qid.path - Qmnt - 1;
 			l = &mntlist;
 			break;
+		default:
+			return -1;
 		}
 		if(t >= l->ndir)
 			return -1;
--- a/kern/devssl.c
+++ b/kern/devssl.c
@@ -717,7 +717,7 @@
 randfill(uchar *buf, int len)
 {
 	while(len-- > 0)
-		*buf++ = nrand(256);
+		*buf++ = fastrand();
 }
 
 static long
--- a/kern/win32.c
+++ b/kern/win32.c
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "dat.h"
 #include "fns.h"
+#include <libsec.h>
 
 typedef struct Oproc Oproc;
 struct Oproc {
@@ -137,23 +138,48 @@
 }
 
 void
+random20(uchar *p)
+{
+	LARGE_INTEGER ti;
+	int i, j;
+	FILETIME ft;
+	DigestState ds;
+	vlong tsc;
+	
+	GetSystemTimeAsFileTime(&ft);
+	memset(&ds, 0, sizeof ds);
+	sha1((uchar*)&ft, sizeof(ft), 0, &ds);
+	for(i=0; i<50; i++) {
+		for(j=0; j<10; j++) {
+			QueryPerformanceCounter(&ti);
+			sha1((uchar*)&ti, sizeof(ti), 0, &ds);
+			tsc = GetTickCount();
+			sha1((uchar*)&tsc, sizeof(tsc), 0, &ds);
+		}
+		Sleep(10);
+	}
+	sha1(0, 0, p, &ds);
+}
+
+void
 randominit(void)
 {
-	srand(seconds());
 }
 
 ulong
 randomread(void *v, ulong n)
 {
-	int m, i, *r;
-
-	m = (n / sizeof(int)) * sizeof(int);
-	for (i = 0, r = (int*)v; i < m; i += sizeof(int)) {
-		*r = rand();
-		r += sizeof(int);
+	int i;
+	uchar p[20];
+	
+	for(i=0; i<n; i+=20){
+		random20(p);
+		if(i+20 <= n)
+			memmove((char*)v+i, p, 20);
+		else
+			memmove((char*)v+i, p, n-i);
 	}
-
-	return m;
+	return n;
 }
 
 long
@@ -183,14 +209,151 @@
 
 extern int	main(int, char*[]);
 
+
+int
+wstrutflen(Rune *s)
+{
+	int n;
+	
+	for(n=0; *s; n+=runelen(*s),s++)
+		;
+	return n;
+}
+
+int
+wstrtoutf(char *s, Rune *t, int n)
+{
+	int i;
+	char *s0;
+
+	s0 = s;
+	if(n <= 0)
+		return wstrutflen(t)+1;
+	while(*t) {
+		if(n < UTFmax+1 && n < runelen(*t)+1) {
+			*s = 0;
+			return s-s0+wstrutflen(t)+1;
+		}
+		i = runetochar(s, t);
+		s += i;
+		n -= i;
+		t++;
+	}
+	*s = 0;
+	return s-s0;
+}
+
+int
+win_hasunicode(void)
+{
+	OSVERSIONINFOA osinfo;
+	int r;
+
+	osinfo.dwOSVersionInfoSize = sizeof(osinfo);
+	if(!GetVersionExA(&osinfo))
+		panic("GetVersionEx failed");
+	switch(osinfo.dwPlatformId) {
+	default:
+		panic("unknown PlatformId");
+	case VER_PLATFORM_WIN32s:
+		panic("Win32s not supported");
+	case VER_PLATFORM_WIN32_WINDOWS:
+		r = 0;
+		break;
+	case VER_PLATFORM_WIN32_NT:
+		r = 1;
+		break;
+	}
+
+	return r;
+}
+
+int
+wstrlen(Rune *s)
+{
+	int n;
+
+	for(n=0; *s; s++,n++)
+		;
+	return n;
+}
+static int	args(char *argv[], int n, char *p);
+
 int APIENTRY
-WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR arg, int nshow)
+WinMain(HINSTANCE x, HINSTANCE y, LPSTR z, int w)
 {
-	main(__argc, __argv);
+	int argc, n;
+	char *arg, *p, **argv;
+	Rune *warg;
+
+	if(0 && win_hasunicode()){
+		warg = GetCommandLineW();
+		n = (wstrlen(warg)+1)*UTFmax;
+		arg = malloc(n);
+		wstrtoutf(arg, warg, n);
+	}else
+		arg = GetCommandLineA();
+
+	/* conservative guess at the number of args */
+	for(argc=4,p=arg; *p; p++)
+		if(*p == ' ' || *p == '\t')
+			argc++;
+	argv = malloc(argc*sizeof(char*));
+	argc = args(argv, argc, arg);
+
+	mymain(argc, argv);
 	ExitThread(0);
 	return 0;
 }
 
+/*
+ * Break the command line into arguments
+ * The rules for this are not documented but appear to be the following
+ * according to the source for the microsoft C library.
+ * Words are seperated by space or tab
+ * Words containing a space or tab can be quoted using "
+ * 2N backslashes + " ==> N backslashes and end quote
+ * 2N+1 backslashes + " ==> N backslashes + literal "
+ * N backslashes not followed by " ==> N backslashes
+ */
+static int
+args(char *argv[], int n, char *p)
+{
+	char *p2;
+	int i, j, quote, nbs;
+
+	for(i=0; *p && i<n-1; i++) {
+		while(*p == ' ' || *p == '\t')
+			p++;
+		quote = 0;
+		argv[i] = p2 = p;
+		for(;*p; p++) {
+			if(!quote && (*p == ' ' || *p == '\t'))
+				break;
+			for(nbs=0; *p == '\\'; p++,nbs++)
+				;
+			if(*p == '"') {
+				for(j=0; j<(nbs>>1); j++)
+					*p2++ = '\\';
+				if(nbs&1)
+					*p2++ = *p;
+				else
+					quote = !quote;
+			} else {
+				for(j=0; j<nbs; j++)
+					*p2++ = '\\';
+				*p2++ = *p;
+			}
+		}
+		/* move p up one to avoid pointing to null at end of p2 */
+		if(*p)
+			p++;
+		*p2 = 0;	
+	}
+	argv[i] = 0;
+
+	return i;
+}
 /*
  * Windows socket error messages
  * There must be a way to get these strings out of the library.
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -29,16 +29,12 @@
 	fmtstr.$O\
 	fmtvprint.$O\
 	fprint.$O\
-	frand.$O\
 	getfields.$O\
 	getpid.$O\
-	lnrand.$O\
 	lock.$O\
-	lrand.$O\
 	mallocz.$O\
 	nan64.$O\
 	netmkaddr.$O\
-	nrand.$O\
 	nsec.$O\
 	pow10.$O\
 	pushssl.$O\
--- a/libc/nan64.c
+++ b/libc/nan64.c
@@ -19,13 +19,13 @@
 double
 __NaN(void)
 {
-	return *(double*)&uvnan;
+	return *(double*)(void*)&uvnan;
 }
 
 int
 __isNaN(double d)
 {
-	uvlong x = *(uvlong*)&d;
+	uvlong x = *(uvlong*)(void*)&d;
 	return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
 }
 
@@ -33,9 +33,9 @@
 __Inf(int sign)
 {
 	if(sign < 0)
-		return *(double*)&uvinf;
+		return *(double*)(void*)&uvinf;
 	else
-		return *(double*)&uvneginf;
+		return *(double*)(void*)&uvneginf;
 }
 
 int
@@ -43,7 +43,7 @@
 {
 	uvlong x;
 
-	x = *(uvlong*)&d;
+	x = *(uvlong*)(void*)&d;
 	if(sign == 0)
 		return x==uvinf || x==uvneginf;
 	else if(sign > 0)
--- a/libmemdraw/draw.c
+++ b/libmemdraw/draw.c
@@ -2368,7 +2368,7 @@
 
 	bx = -bsh-1;
 	ex = -bsh-1-dx;
-	SET(bits);
+	bits = 0;
 	v = par->sdval;
 
 	/* make little endian */
--- a/main.c
+++ b/main.c
@@ -32,6 +32,8 @@
 main(int argc, char **argv)
 {
 	eve = getuser();
+	if(eve == nil)
+		eve = "drawterm";
 
 	sizebug();
 	fmtinstall('r', errfmt);
@@ -101,6 +103,7 @@
 			continue;
 		pass = nil;
 		haveproto = havedom = 0;
+		user = nil;
 		for(i=1; i<nf; i++){
 			if(strncmp(f[i], "user=", 5) == 0)
 				user = f[i]+5;