xref: /plan9/sys/src/cmd/unix/drawterm/kern/win32.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
18ccd4a63SDavid du Colombier #include <windows.h>
28ccd4a63SDavid du Colombier #include "u.h"
38ccd4a63SDavid du Colombier #include "lib.h"
48ccd4a63SDavid du Colombier #include "dat.h"
58ccd4a63SDavid du Colombier #include "fns.h"
68ccd4a63SDavid du Colombier #include <libsec.h>
78ccd4a63SDavid du Colombier 
88ccd4a63SDavid du Colombier typedef struct Oproc Oproc;
98ccd4a63SDavid du Colombier struct Oproc {
108ccd4a63SDavid du Colombier 	int tid;
118ccd4a63SDavid du Colombier 	HANDLE	*sema;
128ccd4a63SDavid du Colombier };
138ccd4a63SDavid du Colombier 
148ccd4a63SDavid du Colombier static int tlsx = TLS_OUT_OF_INDEXES;
158ccd4a63SDavid du Colombier 
168ccd4a63SDavid du Colombier char	*argv0;
178ccd4a63SDavid du Colombier 
188ccd4a63SDavid du Colombier Proc*
_getproc(void)198ccd4a63SDavid du Colombier _getproc(void)
208ccd4a63SDavid du Colombier {
218ccd4a63SDavid du Colombier 	if(tlsx == TLS_OUT_OF_INDEXES)
228ccd4a63SDavid du Colombier 		return nil;
238ccd4a63SDavid du Colombier 	return TlsGetValue(tlsx);
248ccd4a63SDavid du Colombier }
258ccd4a63SDavid du Colombier 
268ccd4a63SDavid du Colombier void
_setproc(Proc * p)278ccd4a63SDavid du Colombier _setproc(Proc *p)
288ccd4a63SDavid du Colombier {
298ccd4a63SDavid du Colombier 	if(tlsx == TLS_OUT_OF_INDEXES){
308ccd4a63SDavid du Colombier 		tlsx = TlsAlloc();
318ccd4a63SDavid du Colombier 		if(tlsx == TLS_OUT_OF_INDEXES)
328ccd4a63SDavid du Colombier 			panic("out of indexes");
338ccd4a63SDavid du Colombier 	}
348ccd4a63SDavid du Colombier 	TlsSetValue(tlsx, p);
358ccd4a63SDavid du Colombier }
368ccd4a63SDavid du Colombier 
378ccd4a63SDavid du Colombier void
oserror(void)388ccd4a63SDavid du Colombier oserror(void)
398ccd4a63SDavid du Colombier {
408ccd4a63SDavid du Colombier 	oserrstr();
418ccd4a63SDavid du Colombier 	nexterror();
428ccd4a63SDavid du Colombier }
438ccd4a63SDavid du Colombier 
448ccd4a63SDavid du Colombier void
osinit(void)458ccd4a63SDavid du Colombier osinit(void)
468ccd4a63SDavid du Colombier {
478ccd4a63SDavid du Colombier 	Oproc *t;
488ccd4a63SDavid du Colombier 	static Proc firstprocCTstore;
498ccd4a63SDavid du Colombier 
508ccd4a63SDavid du Colombier 	_setproc(&firstprocCTstore);
518ccd4a63SDavid du Colombier 	t = (Oproc*)firstprocCTstore.oproc;
528ccd4a63SDavid du Colombier 	assert(t != 0);
538ccd4a63SDavid du Colombier 
548ccd4a63SDavid du Colombier 	t->tid = GetCurrentThreadId();
558ccd4a63SDavid du Colombier 	t->sema = CreateSemaphore(0, 0, 1000, 0);
568ccd4a63SDavid du Colombier 	if(t->sema == 0) {
578ccd4a63SDavid du Colombier 		oserror();
588ccd4a63SDavid du Colombier 		panic("could not create semaphore: %r");
598ccd4a63SDavid du Colombier 	}
608ccd4a63SDavid du Colombier }
618ccd4a63SDavid du Colombier 
628ccd4a63SDavid du Colombier void
osnewproc(Proc * p)638ccd4a63SDavid du Colombier osnewproc(Proc *p)
648ccd4a63SDavid du Colombier {
658ccd4a63SDavid du Colombier 	Oproc *op;
668ccd4a63SDavid du Colombier 
678ccd4a63SDavid du Colombier 	op = (Oproc*)p->oproc;
688ccd4a63SDavid du Colombier 	op->sema = CreateSemaphore(0, 0, 1000, 0);
698ccd4a63SDavid du Colombier 	if (op->sema == 0) {
708ccd4a63SDavid du Colombier 		oserror();
718ccd4a63SDavid du Colombier 		panic("could not create semaphore: %r");
728ccd4a63SDavid du Colombier 	}
738ccd4a63SDavid du Colombier }
748ccd4a63SDavid du Colombier 
758ccd4a63SDavid du Colombier void
osmsleep(int ms)768ccd4a63SDavid du Colombier osmsleep(int ms)
778ccd4a63SDavid du Colombier {
788ccd4a63SDavid du Colombier 	Sleep((DWORD) ms);
798ccd4a63SDavid du Colombier }
808ccd4a63SDavid du Colombier 
818ccd4a63SDavid du Colombier void
osyield(void)828ccd4a63SDavid du Colombier osyield(void)
838ccd4a63SDavid du Colombier {
848ccd4a63SDavid du Colombier 	Sleep(0);
858ccd4a63SDavid du Colombier }
868ccd4a63SDavid du Colombier 
878ccd4a63SDavid du Colombier static DWORD WINAPI tramp(LPVOID vp);
888ccd4a63SDavid du Colombier 
898ccd4a63SDavid du Colombier void
osproc(Proc * p)908ccd4a63SDavid du Colombier osproc(Proc *p)
918ccd4a63SDavid du Colombier {
928ccd4a63SDavid du Colombier 	DWORD tid;
938ccd4a63SDavid du Colombier 
948ccd4a63SDavid du Colombier 	if(CreateThread(0, 0, tramp, p, 0, &tid) == 0) {
958ccd4a63SDavid du Colombier 		oserror();
968ccd4a63SDavid du Colombier 		panic("osproc: %r");
978ccd4a63SDavid du Colombier 	}
988ccd4a63SDavid du Colombier 
998ccd4a63SDavid du Colombier 	Sleep(0);
1008ccd4a63SDavid du Colombier }
1018ccd4a63SDavid du Colombier 
1028ccd4a63SDavid du Colombier static DWORD WINAPI
tramp(LPVOID vp)1038ccd4a63SDavid du Colombier tramp(LPVOID vp)
1048ccd4a63SDavid du Colombier {
1058ccd4a63SDavid du Colombier 	Proc *p = (Proc *) vp;
1068ccd4a63SDavid du Colombier 	Oproc *op = (Oproc*) p->oproc;
1078ccd4a63SDavid du Colombier 
1088ccd4a63SDavid du Colombier 	_setproc(p);
1098ccd4a63SDavid du Colombier 	op->tid = GetCurrentThreadId();
1108ccd4a63SDavid du Colombier 	op->sema = CreateSemaphore(0, 0, 1000, 0);
1118ccd4a63SDavid du Colombier 	if(op->sema == 0) {
1128ccd4a63SDavid du Colombier 		oserror();
1138ccd4a63SDavid du Colombier 		panic("could not create semaphore: %r");
1148ccd4a63SDavid du Colombier 	}
1158ccd4a63SDavid du Colombier 
1168ccd4a63SDavid du Colombier  	(*p->fn)(p->arg);
1178ccd4a63SDavid du Colombier 	ExitThread(0);
1188ccd4a63SDavid du Colombier 	return 0;
1198ccd4a63SDavid du Colombier }
1208ccd4a63SDavid du Colombier 
1218ccd4a63SDavid du Colombier void
procsleep(void)1228ccd4a63SDavid du Colombier procsleep(void)
1238ccd4a63SDavid du Colombier {
1248ccd4a63SDavid du Colombier 	Proc *p;
1258ccd4a63SDavid du Colombier 	Oproc *op;
1268ccd4a63SDavid du Colombier 
1278ccd4a63SDavid du Colombier 	p = up;
1288ccd4a63SDavid du Colombier 	op = (Oproc*)p->oproc;
1298ccd4a63SDavid du Colombier 	WaitForSingleObject(op->sema, INFINITE);}
1308ccd4a63SDavid du Colombier 
1318ccd4a63SDavid du Colombier void
procwakeup(Proc * p)1328ccd4a63SDavid du Colombier procwakeup(Proc *p)
1338ccd4a63SDavid du Colombier {
1348ccd4a63SDavid du Colombier 	Oproc *op;
1358ccd4a63SDavid du Colombier 
1368ccd4a63SDavid du Colombier 	op = (Oproc*)p->oproc;
1378ccd4a63SDavid du Colombier 	ReleaseSemaphore(op->sema, 1, 0);
1388ccd4a63SDavid du Colombier }
1398ccd4a63SDavid du Colombier 
1408ccd4a63SDavid du Colombier void
random20(uchar * p)1418ccd4a63SDavid du Colombier random20(uchar *p)
1428ccd4a63SDavid du Colombier {
1438ccd4a63SDavid du Colombier 	LARGE_INTEGER ti;
1448ccd4a63SDavid du Colombier 	int i, j;
1458ccd4a63SDavid du Colombier 	FILETIME ft;
1468ccd4a63SDavid du Colombier 	DigestState ds;
1478ccd4a63SDavid du Colombier 	vlong tsc;
1488ccd4a63SDavid du Colombier 
1498ccd4a63SDavid du Colombier 	GetSystemTimeAsFileTime(&ft);
1508ccd4a63SDavid du Colombier 	memset(&ds, 0, sizeof ds);
1518ccd4a63SDavid du Colombier 	sha1((uchar*)&ft, sizeof(ft), 0, &ds);
1528ccd4a63SDavid du Colombier 	for(i=0; i<50; i++) {
1538ccd4a63SDavid du Colombier 		for(j=0; j<10; j++) {
1548ccd4a63SDavid du Colombier 			QueryPerformanceCounter(&ti);
1558ccd4a63SDavid du Colombier 			sha1((uchar*)&ti, sizeof(ti), 0, &ds);
1568ccd4a63SDavid du Colombier 			tsc = GetTickCount();
1578ccd4a63SDavid du Colombier 			sha1((uchar*)&tsc, sizeof(tsc), 0, &ds);
1588ccd4a63SDavid du Colombier 		}
1598ccd4a63SDavid du Colombier 		Sleep(10);
1608ccd4a63SDavid du Colombier 	}
1618ccd4a63SDavid du Colombier 	sha1(0, 0, p, &ds);
1628ccd4a63SDavid du Colombier }
1638ccd4a63SDavid du Colombier 
1648ccd4a63SDavid du Colombier void
randominit(void)1658ccd4a63SDavid du Colombier randominit(void)
1668ccd4a63SDavid du Colombier {
1678ccd4a63SDavid du Colombier }
1688ccd4a63SDavid du Colombier 
1698ccd4a63SDavid du Colombier ulong
randomread(void * v,ulong n)1708ccd4a63SDavid du Colombier randomread(void *v, ulong n)
1718ccd4a63SDavid du Colombier {
1728ccd4a63SDavid du Colombier 	int i;
1738ccd4a63SDavid du Colombier 	uchar p[20];
1748ccd4a63SDavid du Colombier 
1758ccd4a63SDavid du Colombier 	for(i=0; i<n; i+=20){
1768ccd4a63SDavid du Colombier 		random20(p);
1778ccd4a63SDavid du Colombier 		if(i+20 <= n)
1788ccd4a63SDavid du Colombier 			memmove((char*)v+i, p, 20);
1798ccd4a63SDavid du Colombier 		else
1808ccd4a63SDavid du Colombier 			memmove((char*)v+i, p, n-i);
1818ccd4a63SDavid du Colombier 	}
1828ccd4a63SDavid du Colombier 	return n;
1838ccd4a63SDavid du Colombier }
1848ccd4a63SDavid du Colombier 
1858ccd4a63SDavid du Colombier long
seconds(void)1868ccd4a63SDavid du Colombier seconds(void)
1878ccd4a63SDavid du Colombier {
1888ccd4a63SDavid du Colombier 	return time(0);
1898ccd4a63SDavid du Colombier }
1908ccd4a63SDavid du Colombier 
1918ccd4a63SDavid du Colombier ulong
ticks(void)1928ccd4a63SDavid du Colombier ticks(void)
1938ccd4a63SDavid du Colombier {
1948ccd4a63SDavid du Colombier 	return GetTickCount();
1958ccd4a63SDavid du Colombier }
1968ccd4a63SDavid du Colombier 
1978ccd4a63SDavid du Colombier #if 0
1988ccd4a63SDavid du Colombier uvlong
1998ccd4a63SDavid du Colombier fastticks(uvlong *v)
2008ccd4a63SDavid du Colombier {
2018ccd4a63SDavid du Colombier 	uvlong n;
2028ccd4a63SDavid du Colombier 
2038ccd4a63SDavid du Colombier 	n = GetTickCount() * 1000 * 1000;
2048ccd4a63SDavid du Colombier 	if(v)
2058ccd4a63SDavid du Colombier 		*v = n;
2068ccd4a63SDavid du Colombier 	return n;
2078ccd4a63SDavid du Colombier }
2088ccd4a63SDavid du Colombier #endif
2098ccd4a63SDavid du Colombier 
2108ccd4a63SDavid du Colombier extern int	main(int, char*[]);
2118ccd4a63SDavid du Colombier 
2128ccd4a63SDavid du Colombier 
2138ccd4a63SDavid du Colombier int
wstrutflen(Rune * s)2148ccd4a63SDavid du Colombier wstrutflen(Rune *s)
2158ccd4a63SDavid du Colombier {
2168ccd4a63SDavid du Colombier 	int n;
2178ccd4a63SDavid du Colombier 
2188ccd4a63SDavid du Colombier 	for(n=0; *s; n+=runelen(*s),s++)
2198ccd4a63SDavid du Colombier 		;
2208ccd4a63SDavid du Colombier 	return n;
2218ccd4a63SDavid du Colombier }
2228ccd4a63SDavid du Colombier 
2238ccd4a63SDavid du Colombier int
wstrtoutf(char * s,Rune * t,int n)2248ccd4a63SDavid du Colombier wstrtoutf(char *s, Rune *t, int n)
2258ccd4a63SDavid du Colombier {
2268ccd4a63SDavid du Colombier 	int i;
2278ccd4a63SDavid du Colombier 	char *s0;
2288ccd4a63SDavid du Colombier 
2298ccd4a63SDavid du Colombier 	s0 = s;
2308ccd4a63SDavid du Colombier 	if(n <= 0)
2318ccd4a63SDavid du Colombier 		return wstrutflen(t)+1;
2328ccd4a63SDavid du Colombier 	while(*t) {
2338ccd4a63SDavid du Colombier 		if(n < UTFmax+1 && n < runelen(*t)+1) {
2348ccd4a63SDavid du Colombier 			*s = 0;
2358ccd4a63SDavid du Colombier 			return s-s0+wstrutflen(t)+1;
2368ccd4a63SDavid du Colombier 		}
2378ccd4a63SDavid du Colombier 		i = runetochar(s, t);
2388ccd4a63SDavid du Colombier 		s += i;
2398ccd4a63SDavid du Colombier 		n -= i;
2408ccd4a63SDavid du Colombier 		t++;
2418ccd4a63SDavid du Colombier 	}
2428ccd4a63SDavid du Colombier 	*s = 0;
2438ccd4a63SDavid du Colombier 	return s-s0;
2448ccd4a63SDavid du Colombier }
2458ccd4a63SDavid du Colombier 
2468ccd4a63SDavid du Colombier int
win_hasunicode(void)2478ccd4a63SDavid du Colombier win_hasunicode(void)
2488ccd4a63SDavid du Colombier {
2498ccd4a63SDavid du Colombier 	OSVERSIONINFOA osinfo;
2508ccd4a63SDavid du Colombier 	int r;
2518ccd4a63SDavid du Colombier 
2528ccd4a63SDavid du Colombier 	osinfo.dwOSVersionInfoSize = sizeof(osinfo);
2538ccd4a63SDavid du Colombier 	if(!GetVersionExA(&osinfo))
2548ccd4a63SDavid du Colombier 		panic("GetVersionEx failed");
2558ccd4a63SDavid du Colombier 	switch(osinfo.dwPlatformId) {
2568ccd4a63SDavid du Colombier 	default:
2578ccd4a63SDavid du Colombier 		panic("unknown PlatformId");
2588ccd4a63SDavid du Colombier 	case VER_PLATFORM_WIN32s:
2598ccd4a63SDavid du Colombier 		panic("Win32s not supported");
2608ccd4a63SDavid du Colombier 	case VER_PLATFORM_WIN32_WINDOWS:
2618ccd4a63SDavid du Colombier 		r = 0;
2628ccd4a63SDavid du Colombier 		break;
2638ccd4a63SDavid du Colombier 	case VER_PLATFORM_WIN32_NT:
2648ccd4a63SDavid du Colombier 		r = 1;
2658ccd4a63SDavid du Colombier 		break;
2668ccd4a63SDavid du Colombier 	}
2678ccd4a63SDavid du Colombier 
2688ccd4a63SDavid du Colombier 	return r;
2698ccd4a63SDavid du Colombier }
2708ccd4a63SDavid du Colombier 
2718ccd4a63SDavid du Colombier int
wstrlen(Rune * s)2728ccd4a63SDavid du Colombier wstrlen(Rune *s)
2738ccd4a63SDavid du Colombier {
2748ccd4a63SDavid du Colombier 	int n;
2758ccd4a63SDavid du Colombier 
2768ccd4a63SDavid du Colombier 	for(n=0; *s; s++,n++)
2778ccd4a63SDavid du Colombier 		;
2788ccd4a63SDavid du Colombier 	return n;
2798ccd4a63SDavid du Colombier }
2808ccd4a63SDavid du Colombier static int	args(char *argv[], int n, char *p);
2818ccd4a63SDavid du Colombier 
2828ccd4a63SDavid du Colombier int APIENTRY
WinMain(HINSTANCE x,HINSTANCE y,LPSTR z,int w)2838ccd4a63SDavid du Colombier WinMain(HINSTANCE x, HINSTANCE y, LPSTR z, int w)
2848ccd4a63SDavid du Colombier {
2858ccd4a63SDavid du Colombier 	int argc, n;
2868ccd4a63SDavid du Colombier 	char *arg, *p, **argv;
2878ccd4a63SDavid du Colombier 	Rune *warg;
2888ccd4a63SDavid du Colombier 
2898ccd4a63SDavid du Colombier 	if(0 && win_hasunicode()){
2908ccd4a63SDavid du Colombier 		warg = GetCommandLineW();
2918ccd4a63SDavid du Colombier 		n = (wstrlen(warg)+1)*UTFmax;
2928ccd4a63SDavid du Colombier 		arg = malloc(n);
2938ccd4a63SDavid du Colombier 		wstrtoutf(arg, warg, n);
2948ccd4a63SDavid du Colombier 	}else
2958ccd4a63SDavid du Colombier 		arg = GetCommandLineA();
2968ccd4a63SDavid du Colombier 
2978ccd4a63SDavid du Colombier 	/* conservative guess at the number of args */
2988ccd4a63SDavid du Colombier 	for(argc=4,p=arg; *p; p++)
2998ccd4a63SDavid du Colombier 		if(*p == ' ' || *p == '\t')
3008ccd4a63SDavid du Colombier 			argc++;
3018ccd4a63SDavid du Colombier 	argv = malloc(argc*sizeof(char*));
3028ccd4a63SDavid du Colombier 	argc = args(argv, argc, arg);
3038ccd4a63SDavid du Colombier 
3048ccd4a63SDavid du Colombier 	mymain(argc, argv);
3058ccd4a63SDavid du Colombier 	ExitThread(0);
3068ccd4a63SDavid du Colombier 	return 0;
3078ccd4a63SDavid du Colombier }
3088ccd4a63SDavid du Colombier 
3098ccd4a63SDavid du Colombier /*
3108ccd4a63SDavid du Colombier  * Break the command line into arguments
3118ccd4a63SDavid du Colombier  * The rules for this are not documented but appear to be the following
3128ccd4a63SDavid du Colombier  * according to the source for the microsoft C library.
3138ccd4a63SDavid du Colombier  * Words are seperated by space or tab
3148ccd4a63SDavid du Colombier  * Words containing a space or tab can be quoted using "
3158ccd4a63SDavid du Colombier  * 2N backslashes + " ==> N backslashes and end quote
3168ccd4a63SDavid du Colombier  * 2N+1 backslashes + " ==> N backslashes + literal "
3178ccd4a63SDavid du Colombier  * N backslashes not followed by " ==> N backslashes
3188ccd4a63SDavid du Colombier  */
3198ccd4a63SDavid du Colombier static int
args(char * argv[],int n,char * p)3208ccd4a63SDavid du Colombier args(char *argv[], int n, char *p)
3218ccd4a63SDavid du Colombier {
3228ccd4a63SDavid du Colombier 	char *p2;
3238ccd4a63SDavid du Colombier 	int i, j, quote, nbs;
3248ccd4a63SDavid du Colombier 
3258ccd4a63SDavid du Colombier 	for(i=0; *p && i<n-1; i++) {
3268ccd4a63SDavid du Colombier 		while(*p == ' ' || *p == '\t')
3278ccd4a63SDavid du Colombier 			p++;
3288ccd4a63SDavid du Colombier 		quote = 0;
3298ccd4a63SDavid du Colombier 		argv[i] = p2 = p;
3308ccd4a63SDavid du Colombier 		for(;*p; p++) {
3318ccd4a63SDavid du Colombier 			if(!quote && (*p == ' ' || *p == '\t'))
3328ccd4a63SDavid du Colombier 				break;
3338ccd4a63SDavid du Colombier 			for(nbs=0; *p == '\\'; p++,nbs++)
3348ccd4a63SDavid du Colombier 				;
3358ccd4a63SDavid du Colombier 			if(*p == '"') {
3368ccd4a63SDavid du Colombier 				for(j=0; j<(nbs>>1); j++)
3378ccd4a63SDavid du Colombier 					*p2++ = '\\';
3388ccd4a63SDavid du Colombier 				if(nbs&1)
3398ccd4a63SDavid du Colombier 					*p2++ = *p;
3408ccd4a63SDavid du Colombier 				else
3418ccd4a63SDavid du Colombier 					quote = !quote;
3428ccd4a63SDavid du Colombier 			} else {
3438ccd4a63SDavid du Colombier 				for(j=0; j<nbs; j++)
3448ccd4a63SDavid du Colombier 					*p2++ = '\\';
3458ccd4a63SDavid du Colombier 				*p2++ = *p;
3468ccd4a63SDavid du Colombier 			}
3478ccd4a63SDavid du Colombier 		}
3488ccd4a63SDavid du Colombier 		/* move p up one to avoid pointing to null at end of p2 */
3498ccd4a63SDavid du Colombier 		if(*p)
3508ccd4a63SDavid du Colombier 			p++;
3518ccd4a63SDavid du Colombier 		*p2 = 0;
3528ccd4a63SDavid du Colombier 	}
3538ccd4a63SDavid du Colombier 	argv[i] = 0;
3548ccd4a63SDavid du Colombier 
3558ccd4a63SDavid du Colombier 	return i;
3568ccd4a63SDavid du Colombier }
3578ccd4a63SDavid du Colombier /*
3588ccd4a63SDavid du Colombier  * Windows socket error messages
3598ccd4a63SDavid du Colombier  * There must be a way to get these strings out of the library.
3608ccd4a63SDavid du Colombier  * This table is derived from the MSDN online help.
3618ccd4a63SDavid du Colombier  */
3628ccd4a63SDavid du Colombier static struct {
3638ccd4a63SDavid du Colombier 	int e;
3648ccd4a63SDavid du Colombier 	char *s;
3658ccd4a63SDavid du Colombier } tab[] = {
3668ccd4a63SDavid du Colombier 	{ 10004, "interrupted function call" },
3678ccd4a63SDavid du Colombier 	{ 10013, "permission denied" },
3688ccd4a63SDavid du Colombier 	{ 10014, "bad address" },
3698ccd4a63SDavid du Colombier 	{ 10022, "invalid argument" },
3708ccd4a63SDavid du Colombier 	{ 10024, "too many open files" },
3718ccd4a63SDavid du Colombier 	{ 10035, "resource temporarily unavailable" },
3728ccd4a63SDavid du Colombier 	{ 10036, "operation now in progress" },
3738ccd4a63SDavid du Colombier 	{ 10037, "operation already in progress" },
3748ccd4a63SDavid du Colombier 	{ 10038, "socket operation on nonsocket" },
3758ccd4a63SDavid du Colombier 	{ 10039, "destination address required" },
3768ccd4a63SDavid du Colombier 	{ 10040, "message too long" },
3778ccd4a63SDavid du Colombier 	{ 10041, "protocol wrong type for socket" },
3788ccd4a63SDavid du Colombier 	{ 10042, "bad protocol option" },
3798ccd4a63SDavid du Colombier 	{ 10043, "protocol not supported" },
3808ccd4a63SDavid du Colombier 	{ 10044, "socket type not supported" },
3818ccd4a63SDavid du Colombier 	{ 10045, "operation not supported" },
3828ccd4a63SDavid du Colombier 	{ 10046, "protocol family not supported" },
3838ccd4a63SDavid du Colombier 	{ 10047, "address family not supported by protocol family" },
3848ccd4a63SDavid du Colombier 	{ 10048, "address already in use" },
3858ccd4a63SDavid du Colombier 	{ 10049, "cannot assign requested address" },
3868ccd4a63SDavid du Colombier 	{ 10050, "network is down" },
3878ccd4a63SDavid du Colombier 	{ 10051, "network is unreachable" },
3888ccd4a63SDavid du Colombier 	{ 10052, "network dropped connection on reset" },
3898ccd4a63SDavid du Colombier 	{ 10053, "software caused connection abort" },
3908ccd4a63SDavid du Colombier 	{ 10054, "connection reset by peer" },
3918ccd4a63SDavid du Colombier 	{ 10055, "no buffer space available" },
3928ccd4a63SDavid du Colombier 	{ 10056, "socket is already connected" },
3938ccd4a63SDavid du Colombier 	{ 10057, "socket is not connected" },
3948ccd4a63SDavid du Colombier 	{ 10058, "cannot send after socket shutdown" },
3958ccd4a63SDavid du Colombier 	{ 10060, "connection timed out" },
3968ccd4a63SDavid du Colombier 	{ 10061, "connection refused" },
3978ccd4a63SDavid du Colombier 	{ 10064, "host is down" },
3988ccd4a63SDavid du Colombier 	{ 10065, "no route to host" },
3998ccd4a63SDavid du Colombier 	{ 10067, "too many processes" },
4008ccd4a63SDavid du Colombier 	{ 10091, "network subsystem is unavailable" },
4018ccd4a63SDavid du Colombier 	{ 10092, "winsock.dll version out of range" },
4028ccd4a63SDavid du Colombier 	{ 10093, "wsastartup not called" },
4038ccd4a63SDavid du Colombier 	{ 10101, "graceful shutdown in progress" },
4048ccd4a63SDavid du Colombier 	{ 10109, "class type not found" },
4058ccd4a63SDavid du Colombier 	{ 11001, "host name not found" },
4068ccd4a63SDavid du Colombier 	{ 11002, "host not found (non-authoritative)" },
4078ccd4a63SDavid du Colombier 	{ 11003, "nonrecoverable error" },
4088ccd4a63SDavid du Colombier 	{ 11004, "valid name, but no data record of requested type" },
4098ccd4a63SDavid du Colombier };
4108ccd4a63SDavid du Colombier 
4118ccd4a63SDavid du Colombier void
osrerrstr(char * buf,uint nbuf)4128ccd4a63SDavid du Colombier osrerrstr(char *buf, uint nbuf)
4138ccd4a63SDavid du Colombier {
4148ccd4a63SDavid du Colombier 	char *p, *q;
4158ccd4a63SDavid du Colombier 	int e, i, r;
4168ccd4a63SDavid du Colombier 
4178ccd4a63SDavid du Colombier 	e = GetLastError();
4188ccd4a63SDavid du Colombier 	r = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
4198ccd4a63SDavid du Colombier 		0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
4208ccd4a63SDavid du Colombier 		buf, nbuf, 0);
4218ccd4a63SDavid du Colombier 	if(r == 0){
4228ccd4a63SDavid du Colombier 		for(i=0; i<nelem(tab); i++)
4238ccd4a63SDavid du Colombier 			if(tab[i].e == e){
4248ccd4a63SDavid du Colombier 				strecpy(buf, buf+nbuf, tab[i].s);
4258ccd4a63SDavid du Colombier 				break;
4268ccd4a63SDavid du Colombier 			}
4278ccd4a63SDavid du Colombier 		if(i==nelem(tab))
4288ccd4a63SDavid du Colombier 			snprint(buf, nbuf, "windows error %d", e);
4298ccd4a63SDavid du Colombier 	}
4308ccd4a63SDavid du Colombier 
4318ccd4a63SDavid du Colombier 	for(p=q=buf; *p; p++) {
4328ccd4a63SDavid du Colombier 		if(*p == '\r')
4338ccd4a63SDavid du Colombier 			continue;
4348ccd4a63SDavid du Colombier 		if(*p == '\n')
4358ccd4a63SDavid du Colombier 			*q++ = ' ';
4368ccd4a63SDavid du Colombier 		else
4378ccd4a63SDavid du Colombier 			*q++ = *p;
4388ccd4a63SDavid du Colombier 	}
4398ccd4a63SDavid du Colombier 	*q = '\0';
4408ccd4a63SDavid du Colombier }
4418ccd4a63SDavid du Colombier 
4428ccd4a63SDavid du Colombier void
oserrstr(void)4438ccd4a63SDavid du Colombier oserrstr(void)
4448ccd4a63SDavid du Colombier {
4458ccd4a63SDavid du Colombier 	osrerrstr(up->errstr, ERRMAX);
4468ccd4a63SDavid du Colombier }
447ec59a3ddSDavid du Colombier 
448ec59a3ddSDavid du Colombier long
showfilewrite(char * a,int n)449ec59a3ddSDavid du Colombier showfilewrite(char *a, int n)
450ec59a3ddSDavid du Colombier {
451*781103c4SDavid du Colombier 	Rune *action, *arg, *cmd, *p;
452ec59a3ddSDavid du Colombier 	static Rune Lopen[] = { 'o', 'p', 'e', 'n', 0 };
453ec59a3ddSDavid du Colombier 
454ec59a3ddSDavid du Colombier 	cmd = runesmprint("%.*s", n, a);
455ec59a3ddSDavid du Colombier 	if(cmd == nil)
456ec59a3ddSDavid du Colombier 		error("out of memory");
457ec59a3ddSDavid du Colombier 	if(cmd[runestrlen(cmd)-1] == '\n')
458ec59a3ddSDavid du Colombier 		cmd[runestrlen(cmd)] = 0;
459ec59a3ddSDavid du Colombier 	p = runestrchr(cmd, ' ');
460ec59a3ddSDavid du Colombier 	if(p){
461ec59a3ddSDavid du Colombier 		action = cmd;
462ec59a3ddSDavid du Colombier 		*p++ = 0;
463ec59a3ddSDavid du Colombier 		arg = p;
464ec59a3ddSDavid du Colombier 	}else{
465ec59a3ddSDavid du Colombier 		action = Lopen;
466ec59a3ddSDavid du Colombier 		arg = cmd;
467ec59a3ddSDavid du Colombier 	}
468ec59a3ddSDavid du Colombier 	ShellExecute(0, 0, action, arg, 0, SW_SHOWNORMAL);
469ec59a3ddSDavid du Colombier 	return n;
470ec59a3ddSDavid du Colombier }
471