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