xref: /inferno-os/Nt/386/include/lib9.h (revision 2b69dba5038ffd0b59cf30a4c44bce549e5097f8)
1 #define _POSIX_SOURCE
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <errno.h>
5 #include <string.h>
6 #include "math.h"
7 #include <fcntl.h>
8 #include <setjmp.h>
9 #include <float.h>
10 #include <time.h>
11 #include <process.h>
12 #include <io.h>
13 #include <direct.h>
14 
15 #define	getwd	infgetwd
16 
17 #ifndef EMU
18 typedef struct Proc Proc;
19 #endif
20 
21 /*
22  * math module dtoa
23  */
24 #define __LITTLE_ENDIAN
25 
26    /* there must be a Win32 header macro for endian-ness!!! */
27 
28 /*
29  * disable various silly warnings
30  * 4018 signed/unsigned comparison
31  * 4245 signed/unsigned conversion
32  * 4244 long to char conversion
33  * 4068	unknown pragma
34  * 4090 different volatile quals
35  * 4554 operator precedence
36  * 4146 unary - on unsigned type
37  * 4996 `deprecated' functions: they often suggest non-portable replacements
38  */
39 #pragma warning( disable : 4305 4244 4102 4761 4018 4245 4244 4068 4090 4554 4146 4996)
40 
41 #define	nil		((void*)0)
42 
43 typedef unsigned char	uchar;
44 typedef unsigned int	uint;
45 typedef unsigned long	ulong;
46 typedef signed char	schar;
47 typedef unsigned short	ushort;
48 typedef unsigned short	Rune;
49 typedef __int64		vlong;
50 typedef unsigned __int64		uvlong;
51 typedef unsigned int u32int;
52 typedef uvlong u64int;
53 
54 typedef unsigned int	mpdigit;	/* for /sys/include/mp.h */
55 typedef unsigned short u16int;
56 typedef unsigned char u8int;
57 typedef unsigned long uintptr;
58 
59 #define	USED(x)		if(x){}else{}
60 #define	SET(x)
61 
62 #undef nelem
63 #define	nelem(x)	(sizeof(x)/sizeof((x)[0]))
64 #undef offsetof
65 #define	offsetof(s, m)	(ulong)(&(((s*)0)->m))
66 #undef assert
67 #define	assert(x)	if(x){}else _assert("x")
68 
69 /*
70  * most mem and string routines are declared by ANSI/POSIX files above
71  */
72 
73 extern	char*	strecpy(char*, char*, char*);
74 extern	char*	strdup(const char*);
75 extern	int	cistrncmp(char*, char*, int);
76 extern	int	cistrcmp(char*, char*);
77 extern	char*	cistrstr(char*, char*);
78 extern	int	tokenize(char*, char**, int);
79 extern	vlong	strtoll(const char*, char**, int);
80 extern	uvlong	strtoull(const char*, char**, int);
81 
82 enum
83 {
84 	UTFmax		= 3,		/* maximum bytes per rune */
85 	Runesync	= 0x80,		/* cannot represent part of a UTF sequence (<) */
86 	Runeself	= 0x80,		/* rune and UTF sequences are the same (<) */
87 	Runeerror	= 0x80		/* decoding error in UTF */
88 };
89 
90 /*
91  * rune routines
92  */
93 extern	int	runetochar(char*, Rune*);
94 extern	int	chartorune(Rune*, char*);
95 extern	int	runelen(long);
96 extern	int	runenlen(Rune*, int);
97 extern	int	fullrune(char*, int);
98 extern	int	utflen(char*);
99 extern	int	utfnlen(char*, long);
100 extern	char*	utfrune(char*, long);
101 extern	char*	utfrrune(char*, long);
102 extern	char*	utfutf(char*, char*);
103 extern	char*	utfecpy(char*, char*, char*);
104 
105 extern	Rune*	runestrcat(Rune*, Rune*);
106 extern	Rune*	runestrchr(Rune*, Rune);
107 extern	int	runestrcmp(Rune*, Rune*);
108 extern	Rune*	runestrcpy(Rune*, Rune*);
109 extern	Rune*	runestrncpy(Rune*, Rune*, long);
110 extern	Rune*	runestrecpy(Rune*, Rune*, Rune*);
111 extern	Rune*	runestrdup(Rune*);
112 extern	Rune*	runestrncat(Rune*, Rune*, long);
113 extern	int	runestrncmp(Rune*, Rune*, long);
114 extern	Rune*	runestrrchr(Rune*, Rune);
115 extern	long	runestrlen(Rune*);
116 extern	Rune*	runestrstr(Rune*, Rune*);
117 
118 extern	Rune	tolowerrune(Rune);
119 extern	Rune	totitlerune(Rune);
120 extern	Rune	toupperrune(Rune);
121 extern	int	isalpharune(Rune);
122 extern	int	islowerrune(Rune);
123 extern	int	isspacerune(Rune);
124 extern	int	istitlerune(Rune);
125 extern	int	isupperrune(Rune);
126 
127 /*
128  * malloc
129  */
130 extern	void*	malloc(size_t);
131 extern	void*	mallocz(ulong, int);
132 extern	void	free(void*);
133 extern	ulong	msize(void*);
134 extern	void*	calloc(size_t, size_t);
135 extern	void*	realloc(void*, size_t);
136 extern	void		setmalloctag(void*, ulong);
137 extern	void		setrealloctag(void*, ulong);
138 extern	ulong	getmalloctag(void*);
139 extern	ulong	getrealloctag(void*);
140 extern	void*	malloctopoolblock(void*);
141 
142 /*
143  * print routines
144  */
145 typedef struct Fmt	Fmt;
146 struct Fmt{
147 	uchar	runes;			/* output buffer is runes or chars? */
148 	void	*start;			/* of buffer */
149 	void	*to;			/* current place in the buffer */
150 	void	*stop;			/* end of the buffer; overwritten if flush fails */
151 	int	(*flush)(Fmt *);	/* called when to == stop */
152 	void	*farg;			/* to make flush a closure */
153 	int	nfmt;			/* num chars formatted so far */
154 	va_list	args;			/* args passed to dofmt */
155 	int	r;			/* % format Rune */
156 	int	width;
157 	int	prec;
158 	ulong	flags;
159 };
160 
161 enum{
162 	FmtWidth	= 1,
163 	FmtLeft		= FmtWidth << 1,
164 	FmtPrec		= FmtLeft << 1,
165 	FmtSharp	= FmtPrec << 1,
166 	FmtSpace	= FmtSharp << 1,
167 	FmtSign		= FmtSpace << 1,
168 	FmtZero		= FmtSign << 1,
169 	FmtUnsigned	= FmtZero << 1,
170 	FmtShort	= FmtUnsigned << 1,
171 	FmtLong		= FmtShort << 1,
172 	FmtVLong	= FmtLong << 1,
173 	FmtComma	= FmtVLong << 1,
174 	FmtByte	= FmtComma << 1,
175 
176 	FmtFlag		= FmtByte << 1
177 };
178 
179 extern	int	print(char*, ...);
180 extern	char*	seprint(char*, char*, char*, ...);
181 extern	char*	vseprint(char*, char*, char*, va_list);
182 extern	int	snprint(char*, int, char*, ...);
183 extern	int	vsnprint(char*, int, char*, va_list);
184 extern	char*	smprint(char*, ...);
185 extern	char*	vsmprint(char*, va_list);
186 extern	int	sprint(char*, char*, ...);
187 extern	int	fprint(int, char*, ...);
188 extern	int	vfprint(int, char*, va_list);
189 
190 extern	int	runesprint(Rune*, char*, ...);
191 extern	int	runesnprint(Rune*, int, char*, ...);
192 extern	int	runevsnprint(Rune*, int, char*, va_list);
193 extern	Rune*	runeseprint(Rune*, Rune*, char*, ...);
194 extern	Rune*	runevseprint(Rune*, Rune*, char*, va_list);
195 extern	Rune*	runesmprint(char*, ...);
196 extern	Rune*	runevsmprint(char*, va_list);
197 
198 extern	int	fmtfdinit(Fmt*, int, char*, int);
199 extern	int	fmtfdflush(Fmt*);
200 extern	int	fmtstrinit(Fmt*);
201 extern	char*	fmtstrflush(Fmt*);
202 extern	int	runefmtstrinit(Fmt*);
203 extern	Rune*	runefmtstrflush(Fmt*);
204 
205 extern	int	fmtinstall(int, int (*)(Fmt*));
206 extern	int	dofmt(Fmt*, char*);
207 extern	int	dorfmt(Fmt*, Rune*);
208 extern	int	fmtprint(Fmt*, char*, ...);
209 extern	int	fmtvprint(Fmt*, char*, va_list);
210 extern	int	fmtrune(Fmt*, int);
211 extern	int	fmtstrcpy(Fmt*, char*);
212 extern	int	fmtrunestrcpy(Fmt*, Rune*);
213 /*
214  * error string for %r
215  * supplied on per os basis, not part of fmt library
216  */
217 extern	int	errfmt(Fmt *f);
218 
219 /*
220  * quoted strings
221  */
222 extern	char	*unquotestrdup(char*);
223 extern	Rune	*unquoterunestrdup(Rune*);
224 extern	char	*quotestrdup(char*);
225 extern	Rune	*quoterunestrdup(Rune*);
226 extern	int	quotestrfmt(Fmt*);
227 extern	int	quoterunestrfmt(Fmt*);
228 extern	void	quotefmtinstall(void);
229 extern	int	(*doquote)(int);
230 
231 /*
232  * random number
233  */
234 extern	ulong	truerand(void);
235 extern	ulong	ntruerand(ulong);
236 
237 /*
238  * math
239  */
240 extern	int	isNaN(double);
241 extern	int	isInf(double, int);
242 
243 #define	PIO2	1.570796326794896619231e0
244 #define	PI	(PIO2+PIO2)
245 
246 /*
247  * Time-of-day
248  */
249 
250 typedef struct Tm Tm;
251 struct Tm {
252 	int	sec;
253 	int	min;
254 	int	hour;
255 	int	mday;
256 	int	mon;
257 	int	year;
258 	int	wday;
259 	int	yday;
260 	char	zone[4];
261 	int	tzoff;
262 };
263 extern	vlong	osnsec(void);
264 #define	nsec	osnsec
265 
266 /*
267  * one-of-a-kind
268  */
269 extern	void	_assert(char*);
270 extern	double	charstod(int(*)(void*), void*);
271 extern	char*	cleanname(char*);
272 extern	ulong	getcallerpc(void*);
273 extern	int	getfields(char*, char**, int, int, char*);
274 extern	char*	getuser(void);
275 extern	char*	getuser(void);
276 extern	char*	getwd(char*, int);
277 extern	char*	getwd(char*, int);
278 extern	double	ipow10(int);
279 extern	double	pow10(int);
280 extern	void	sysfatal(char*, ...);
281 extern	int	dec64(uchar*, int, char*, int);
282 extern	int	enc64(char*, int, uchar*, int);
283 extern	int	dec32(uchar*, int, char*, int);
284 extern	int	enc32(char*, int, uchar*, int);
285 extern	int	dec16(uchar*, int, char*, int);
286 extern	int	enc16(char*, int, uchar*, int);
287 extern	int	encodefmt(Fmt*);
288 
289 /*
290  *  synchronization
291  */
292 typedef
293 struct Lock {
294 	int	val;
295 	int	pid;
296 } Lock;
297 
298 extern int	_tas(int*);
299 
300 extern	void	lock(Lock*);
301 extern	void	unlock(Lock*);
302 extern	int	canlock(Lock*);
303 
304 typedef struct QLock QLock;
305 struct QLock
306 {
307 	Lock	use;			/* to access Qlock structure */
308 	Proc	*head;			/* next process waiting for object */
309 	Proc	*tail;			/* last process waiting for object */
310 	int	locked;			/* flag */
311 };
312 
313 extern	void	qlock(QLock*);
314 extern	void	qunlock(QLock*);
315 extern	int	canqlock(QLock*);
316 extern	void	_qlockinit(ulong (*)(ulong, ulong));	/* called only by the thread library */
317 
318 typedef
319 struct RWLock
320 {
321 	Lock	l;			/* Lock modify lock */
322 	QLock	x;			/* Mutual exclusion lock */
323 	QLock	k;			/* Lock for waiting writers */
324 	int	readers;		/* Count of readers in lock */
325 } RWLock;
326 
327 extern	int	canrlock(RWLock*);
328 extern	int	canwlock(RWLock*);
329 extern	void	rlock(RWLock*);
330 extern	void	runlock(RWLock*);
331 extern	void	wlock(RWLock*);
332 extern	void	wunlock(RWLock*);
333 
334 /*
335  * network dialing
336  */
337 #define NETPATHLEN 40
338 
339 /*
340  * system calls
341  *
342  */
343 #define	STATMAX	65535U	/* max length of machine-independent stat structure */
344 #define	DIRMAX	(sizeof(Dir)+STATMAX)	/* max length of Dir structure */
345 #define	ERRMAX	128	/* max length of error string */
346 
347 #define	MORDER	0x0003	/* mask for bits defining order of mounting */
348 #define	MREPL	0x0000	/* mount replaces object */
349 #define	MBEFORE	0x0001	/* mount goes before others in union directory */
350 #define	MAFTER	0x0002	/* mount goes after others in union directory */
351 #define	MCREATE	0x0004	/* permit creation in mounted directory */
352 #define	MCACHE	0x0010	/* cache some data */
353 #define	MMASK	0x0017	/* all bits on */
354 
355 #define	OREAD	0	/* open for read */
356 #define	OWRITE	1	/* write */
357 #define	ORDWR	2	/* read and write */
358 #define	OEXEC	3	/* execute, == read but check execute permission */
359 #define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */
360 #define	OCEXEC	32	/* or'ed in, close on exec */
361 #define	ORCLOSE	64	/* or'ed in, remove on close */
362 #define	OEXCL	0x1000	/* or'ed in, exclusive use (create only) */
363 
364 #define	AEXIST	0	/* accessible: exists */
365 #define	AEXEC	1	/* execute access */
366 #define	AWRITE	2	/* write access */
367 #define	AREAD	4	/* read access */
368 
369 /* bits in Qid.type */
370 #define QTDIR		0x80		/* type bit for directories */
371 #define QTAPPEND	0x40		/* type bit for append only files */
372 #define QTEXCL		0x20		/* type bit for exclusive use files */
373 #define QTMOUNT		0x10		/* type bit for mounted channel */
374 #define QTAUTH		0x08		/* type bit for authentication file */
375 #define QTFILE		0x00		/* plain file */
376 
377 /* bits in Dir.mode */
378 #define DMDIR		0x80000000	/* mode bit for directories */
379 #define DMAPPEND	0x40000000	/* mode bit for append only files */
380 #define DMEXCL		0x20000000	/* mode bit for exclusive use files */
381 #define DMMOUNT		0x10000000	/* mode bit for mounted channel */
382 #define DMAUTH		0x08000000	/* mode bit for authentication file */
383 #define DMREAD		0x4		/* mode bit for read permission */
384 #define DMWRITE		0x2		/* mode bit for write permission */
385 #define DMEXEC		0x1		/* mode bit for execute permission */
386 
387 typedef
388 struct Qid
389 {
390 	uvlong	path;
391 	ulong	vers;
392 	uchar	type;
393 } Qid;
394 
395 typedef
396 struct Dir {
397 	/* system-modified data */
398 	ushort	type;	/* server type */
399 	uint	dev;	/* server subtype */
400 	/* file data */
401 	Qid	qid;	/* unique id from server */
402 	ulong	mode;	/* permissions */
403 	ulong	atime;	/* last read time */
404 	ulong	mtime;	/* last write time */
405 	vlong	length;	/* file length */
406 	char	*name;	/* last element of path */
407 	char	*uid;	/* owner name */
408 	char	*gid;	/* group name */
409 	char	*muid;	/* last modifier name */
410 } Dir;
411 
412 extern	Dir*	dirstat(char*);
413 extern	Dir*	dirfstat(int);
414 extern	int	dirwstat(char*, Dir*);
415 extern	int	dirfwstat(int, Dir*);
416 extern	long	dirread(int, Dir**);
417 extern	void	nulldir(Dir*);
418 extern	long	dirreadall(int, Dir**);
419 
420 typedef
421 struct Waitmsg
422 {
423 	int pid;	/* of loved one */
424 	ulong time[3];	/* of loved one & descendants */
425 	char	*msg;
426 } Waitmsg;
427 
428 extern	void	_exits(char*);
429 
430 extern	void	exits(char*);
431 extern	int	create(char*, int, int);
432 extern	int	errstr(char*, uint);
433 
434 extern	long	readn(int, void*, long);
435 extern	void	rerrstr(char*, uint);
436 extern	vlong	seek(int, vlong, int);
437 extern	void	werrstr(char*, ...);
438 
439 extern char *argv0;
440 #define	ARGBEGIN	for((argv0||(argv0=*argv)),argv++,argc--;\
441 			    argv[0] && argv[0][0]=='-' && argv[0][1];\
442 			    argc--, argv++) {\
443 				char *_args, *_argt;\
444 				Rune _argc;\
445 				_args = &argv[0][1];\
446 				if(_args[0]=='-' && _args[1]==0){\
447 					argc--; argv++; break;\
448 				}\
449 				_argc = 0;\
450 				while(*_args && (_args += chartorune(&_argc, _args)))\
451 				switch(_argc)
452 #define	ARGEND		(_argt=0);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc);
453 #define	ARGF()		(_argt=_args, _args="",\
454 				(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
455 #define	EARGF(x)	(_argt=_args, _args="",\
456 				(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
457 
458 #define	ARGC()		_argc
459 
460 /*
461  *	Extensions for Inferno to basic libc.h
462  */
463 
464 extern	void	setbinmode(void);
465 extern	void*	sbrk(int);
466 
467