1ref	-D_def_map_ast=1
2
3cmd	universe
4
5hdr	dirent,direntry,filio,fmtmsg,fnmatch,jioctl,libgen,limits
6hdr	locale,ndir,nl_types,process,spawn,syslog,utime,vfork,wctype
7hdr	wchar note{ <wchar.h> and isw*() really work }end execute{
8	#include <wchar.h>
9	int
10	main()
11	{
12		wchar_t	w = 'a';
13		return iswalnum(w) == 0;
14	}
15}end
16
17dat	_tzname,tzname
18
19lib	BSDsetpgrp
20lib	_cleanup
21lib	atexit,bcopy,bzero,catclose,catgets,catopen,confstr,dirread,dup2
22lib	execlp,execve,execvp,execvpe
23lib	fchmod,fcntl,fmtmsg,fnmatch,fork,fsync
24lib	getconf,getdents,getdirentries,getdtablesize,getdate
25lib	getgroups,gethostname,getlogin,getpagesize,getrlimit,getuniverse
26lib	getopt,getsubopt,getopt_long,getopt_long_only
27lib	glob,index,iswblank,iswctype,killpg,link,localeconv,madvise
28lib	mbtowc,mbrtowc,memalign,memchr,memcpy,memdup,memmove,memset
29lib	mkdir,mkfifo,mktemp,mktime
30lib	mount,on_exit,onexit,opendir,pathconf
31lib	readlink,remove,rename,rewinddir,rindex,rmdir,setlocale
32lib	setpgid,setpgrp,setpgrp2,setreuid,setsid,setuid,sigaction
33lib	sigprocmask,sigsetmask,sigunblock,sigvec,socketpair
34lib	spawn,spawnve,spawnveg
35lib	strchr,strcoll,strdup,strerror,strcasecmp,strncasecmp,strrchr,strstr
36lib	strmode,strxfrm,strftime,swab,symlink,sysconf,sysinfo,syslog
37lib	telldir,tmpnam,tzset,universe,unlink,utime,wctype
38lib	ftruncate,truncate
39lib	creat64,fstat64,fstatvfs64,ftruncate64 -D_LARGEFILE64_SOURCE
40lib	lseek64,lstat64 -D_LARGEFILE64_SOURCE
41lib	open64,readdir64,stat64,statvfs64,truncate64 -D_LARGEFILE64_SOURCE
42
43lib,npt	strtod,strtold,strtol,strtoll,strtoul,strtoull stdlib.h
44lib,npt	sigflag signal.h
45
46mem	direct.d_reclen sys/types.h sys/dir.h
47mem	dirent.d_fileno,dirent.d_ino,dirent.d_namlen,dirent.d_off,dirent.d_reclen,dirent.d_type sys/types.h dirent.h
48mem	DIR sys/types.h - dirent.h - sys/dir.h
49mem	DIR.dd_fd sys/types.h - dirent.h - sys/dir.h
50mem	inheritance.pgroup spawn.h
51
52sys	dir,filio,jioctl,localedef,ptem,resource
53sys	socket,stream,systeminfo,universe,vfork
54
55typ	off64_t -D_LARGEFILE64_SOURCE
56typ	struct.dirent64 -D_LARGEFILE64_SOURCE dirent.h
57
58tst	tst_errno note{ errno can be assigned }end link{
59	_BEGIN_EXTERNS_
60	#define error		______error
61	#define strerror	______strerror
62	#include <errno.h>
63	#undef	error
64	#undef	strerror
65	#ifndef errno
66	extern int errno;
67	#endif
68	error() { }
69	strerror() { }
70	_END_EXTERNS_
71	int main() { errno = 0; error(); strerror(); return 0; }
72}end
73
74tst	lib_poll_fd_1 note{ fd is first arg to poll() }end execute{
75	#include <poll.h>
76	_BEGIN_EXTERNS_
77	extern int	pipe _ARG_((int*));
78	_END_EXTERNS_
79	int
80	main()
81	{	int		rw[2];
82		struct pollfd	fd;
83		if (pipe(rw) < 0) return 1;
84		fd.fd = rw[0];
85		fd.events = POLLIN;
86		fd.revents = 0;
87		if (poll(&fd, 1, 0) < 0 || fd.revents != 0) return 1;
88		if (write(rw[1], "x", 1) != 1) return 1;
89		if (poll(&fd, 1, 0) < 0 || fd.revents == 0) return 1;
90		return 0;
91	}
92}end
93
94tst	lib_poll_fd_2 note{ fd is second arg to poll() }end execute{
95	#include <poll.h>
96	_BEGIN_EXTERNS_
97	extern int	pipe _ARG_((int*));
98	_END_EXTERNS_
99	int
100	main()
101	{	int		rw[2];
102		struct pollfd	fd;
103		if (pipe(rw) < 0) return 1;
104		fd.fd = rw[0];
105		fd.events = POLLIN;
106		fd.revents = 0;
107		return poll(1, &fd, 0) < 0;
108		if (poll(1, &fd, 0) < 0 || fd.revents != 0) return 1;
109		if (write(rw[1], "x", 1) != 1) return 1;
110		if (poll(1, &fd, 0) < 0 || fd.revents == 0) return 1;
111		return 0;
112	}
113}end
114
115exp	_lib_poll	_lib_poll_fd_1||_lib_poll_fd_2
116
117tst	lib_poll_notimer note{ poll with no fds ignores timeout }end execute{
118	#include <sys/types.h>
119	#include <poll.h>
120	_BEGIN_EXTERNS_
121	extern time_t	time _ARG_((time_t*));
122	_END_EXTERNS_
123	#define TIMEOUT		4
124	int
125	main()
126	{
127		unsigned long	start;
128		unsigned long	finish;
129		struct pollfd	fd;
130		start = time((time_t*)0);
131		if (poll(&fd, 0, TIMEOUT * 1000) < 0)
132			return 0;
133		finish = time((time_t*)0);
134		return (finish - start) > (TIMEOUT / 2);
135	}
136}end
137
138tst	lib_select note{ select() has standard 5 arg interface }end link{
139	#include <sys/types.h>
140	#include <sys/time.h>
141	#include <sys/socket.h>
142	int
143	main()
144	{	struct timeval	tmb;
145		fd_set		rd;
146		FD_ZERO(&rd);
147		FD_SET(0,&rd);
148		tmb.tv_sec = 0;
149		tmb.tv_usec = 0;
150		select(1,&rd,(fd_set*)0,(fd_set*)0,&tmb);
151		return 0;
152	}
153}end
154
155tst	pipe_rw note{ full duplex pipes }end execute{
156	_BEGIN_EXTERNS_
157	extern int	pipe _ARG_((int*));
158	extern int	read _ARG_((int, void*, int));
159	extern int	strcmp _ARG_((const char*, const char*));
160	extern int	write _ARG_((int, void*, int));
161	_END_EXTERNS_
162	int
163	main()
164	{
165	#if defined(__sgi) || defined(_sgi) || defined(sgi)
166		/* boot tuneable pipes force one way for bin compatibility */
167		return 1;
168	#else
169		static char	test[] = "test\n";
170		int		io[2];
171		char		buf[sizeof(test)];
172		if (pipe(io)) return 1;
173		if (write(io[1], test, sizeof(test)) != sizeof(test)) return 1;
174		if (read(io[0], buf, sizeof(test)) != sizeof(test)) return 1;
175		if (strcmp(test, buf)) return 1;
176		if (write(io[0], test, sizeof(test)) != sizeof(test)) return 1;
177		if (read(io[1], buf, sizeof(test)) != sizeof(test)) return 1;
178		if (strcmp(test, buf)) return 1;
179		return 0;
180	#endif
181	}
182}end
183
184tst	lib_vfork unistd.h stdlib.h vfork.h note{ vfork exists and it works }end execute{
185	#include <signal.h>
186	int
187	main(argc, argv)
188	int	argc;
189	char**	argv;
190	{
191		int	status;
192		char*	cmd[3];
193		if (argv[1])
194			_exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
195		signal(SIGHUP, SIG_IGN);
196		switch (vfork())
197		{
198		case -1:
199			_exit(1);
200		case 0:
201			cmd[0] = argv[0];
202			cmd[1] = "test";
203			cmd[2] = 0;
204			execv(cmd[0], cmd);
205			_exit(2);
206		}
207		status = 1;
208		_exit(wait(&status) < 0 || status != 0);
209 	}
210}end
211 
212tst	real_vfork note{ vfork child shares data with parent }end execute{
213	_BEGIN_EXTERNS_
214	extern int	_exit _ARG_((int));
215	extern int	vfork _ARG_((void));
216	_END_EXTERNS_
217	int		code;
218	int
219	main()
220	{
221		code = 1;
222		if (!vfork())
223			code = 0;
224		_exit(code);
225	}
226}end
227
228tst	lib_posix_spawn unistd.h stdlib.h spawn.h -Dfork=______fork note{ posix_spawn exists and it works and its worth using }end status{
229	#include <sys/types.h>
230	#include <sys/stat.h>
231	#include <sys/wait.h>
232	#include <spawn.h>
233	#include <signal.h>
234	#include <fcntl.h>
235	#include <string.h>
236	#undef fork
237	/* if it uses fork() why bother? */
238	pid_t fork _ARG_((void)) { return -1; }
239	pid_t _fork _ARG_((void)) { return -1; }
240	pid_t __fork _ARG_((void)) { return -1; }
241	int
242	main(argc, argv)
243	int	argc;
244	char**	argv;
245	{
246		char*			s;
247		pid_t			pid;
248		posix_spawnattr_t	attr;
249		int			n;
250		int			status;
251		char*			cmd[3];
252		char			tmp[1024];
253		if (argv[1])
254			_exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
255		signal(SIGHUP, SIG_IGN);
256		if (posix_spawnattr_init(&attr))
257			_exit(0);
258		if (posix_spawnattr_setpgroup(&attr, 0))
259			_exit(0);
260		if (posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP))
261			_exit(0);
262		/* first try an a.out and verify that SIGHUP is ignored */
263		cmd[0] = argv[0];
264		cmd[1] = "test";
265		cmd[2] = 0;
266		if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0))
267			_exit(0);
268		status = 1;
269		if (wait(&status) < 0 || status != 0)
270			_exit(0);
271		/* passing ENOEXEC to the shell is bogus */
272		n = strlen(cmd[0]);
273		if (n >= (sizeof(tmp) - 3))
274			_exit(0);
275		strcpy(tmp, cmd[0]);
276		tmp[n] = '.';
277		tmp[n+1] = 's';
278		tmp[n+2] = 'h';
279		tmp[n+3] = 0;
280		if (close(open(tmp, O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO)) < 0 || chmod(tmp, S_IRWXU|S_IRWXG|S_IRWXO) < 0)
281			_exit(0);
282		cmd[0] = tmp;
283		n = 0;
284		pid = -1;
285		if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0))
286			n = 2;
287		else
288		{
289			n = pid != -1 && waitpid(pid, &status, WNOHANG|WNOWAIT) == pid && ((status>>8)&0x7f) == 127;
290			wait(&status);
291		}
292		_exit(n);
293 	}
294}end
295
296tst	lib_spawn_mode unistd.h stdlib.h note{ first spawn arg is mode and it works }end execute{
297	#include <signal.h>
298	#include <process.h>
299	#ifndef P_NOWAIT
300	#define P_NOWAIT _P_NOWAIT
301	#endif
302	int
303	main(argc, argv)
304	int	argc;
305	char**	argv;
306	{
307		int	status;
308		char*	cmd[3];
309		if (argv[1])
310			_exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
311		signal(SIGHUP, SIG_IGN);
312		cmd[0] = argv[0];
313		cmd[1] = "test";
314		cmd[2] = 0;
315		if (spawnv(P_NOWAIT, cmd[0], cmd) < 0)
316			_exit(1);
317		status = 1;
318		_exit(wait(&status) < 0 || status != 0);
319	}
320}end
321
322tst	stream_peek note{ ioctl(I_PEEK) works on pipe() }end execute{
323	#include <sys/types.h>
324	#include <unistd.h>
325	#include <stropts.h>
326	int
327	main()
328	{	struct strpeek	peek;
329		int		fds[2];
330		char		ctlbuf[32];
331		char		databuf[32];
332		peek.flags = 0;
333		peek.ctlbuf.maxlen = peek.ctlbuf.len = sizeof(ctlbuf);
334		peek.ctlbuf.buf = ctlbuf;
335		peek.databuf.maxlen = peek.databuf.len = sizeof(databuf);
336		peek.databuf.buf = databuf;
337		pipe(fds);
338		return ioctl(fds[0],I_PEEK,&peek) < 0;
339	}
340}end
341
342tst	socket_peek note{ recv(MSG_PEEK) works on socketpair() }end execute{
343	#include <unistd.h>
344	#include <sys/types.h>
345	#include <sys/socket.h>
346	int
347	main()
348	{	
349		int		i;
350		int		fds[2];
351		char		buf[128];
352
353		static char	msg[] = "abcd";
354
355		if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
356			return 1;
357		if (write(fds[1], msg, sizeof(msg)) != sizeof(msg))
358				return 1;
359		if (recv(fds[0], buf, sizeof(buf), MSG_PEEK) != sizeof(msg))
360			return 1;
361		for (i = 0; i < sizeof(msg); i++)
362			if (buf[i] != msg[i])
363				return 1;
364		if (read(fds[0], buf, sizeof(msg)) != sizeof(msg))
365			return 1;
366		for (i = 0; i < sizeof(msg); i++)
367			if (buf[i] != msg[i])
368				return 1;
369		return 0;
370	}
371}end
372
373tst	lib_memcmp string.h note{ standard memcmp interface that works }end execute{
374	/* sgi again -- we're sick of being their regression test */
375	#define L	8
376	char		a[L] = { '0' };
377	char		b[L] = { '1' };
378	int
379	main()
380	{
381		return memcmp(a, b, L) >= 0;
382	}
383}end
384
385tst	lib_memccpy string.h unistd.h stdlib.h fcntl.h signal.h sys/types.h sys/stat.h sys/mman.h fcntl.h note{ standard memccpy interface that works }end execute{
386	#if _STD_
387	static void gotcha(int sig)
388	#else
389	static int gotcha(sig) int sig;
390	#endif
391	{
392		exit(1);
393	}
394	#ifdef MAP_PRIVATE
395	static const char x[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxN";
396	#if _STD_
397	static int indict_sgi_ia64_4Q_2004(int n)
398	#else
399	static int indict_sgi_ia64_4Q_2004(n) int n;
400	#endif
401	{
402		char*		b;
403		char*		s;
404		char*		e;
405		char*		t;
406		long		m;
407		int		d;
408		char		u[1024];
409
410		static char	p[32] = {'/','t','m','p','/','m','m'};
411
412		for (d = 7; d < 13; d++)
413			p[d] = 'X';
414		p[d] = 0;
415		if ((d = mkstemp(p)) < 0)
416			return 1;
417		remove(p);
418		for (m = 0; m < n; m++)
419			if (write(d, x, sizeof(x)-1) != sizeof(x)-1)
420			{
421				close(d);
422				return 1;
423			}
424		if (lseek(d, (off_t)0, SEEK_SET))
425		{
426			close(d);
427			return 1;
428		}
429		m = n * (sizeof(x)-1);
430		if (!(b = mmap((void*)0, m, PROT_READ|PROT_WRITE, MAP_PRIVATE, d, (off_t)0)))
431		{
432			close(d);
433			return 1;
434		}
435		for (e = (s = b) + m; s < e && (t = memccpy(u, s, 'N', (e-s) > sizeof(u) ? sizeof(u) : (e-s))); s += (t-u))
436			if ((t-u) != (sizeof(x)-1) || memcmp(u, s, t-u))
437			{
438				close(d);
439				return 1;
440			}
441		if (s < e)
442		{
443			close(d);
444			return 1;
445		}
446		close(d);
447		return 0;
448	}
449	#endif
450
451	int
452	main ()
453	{
454		char	buf[1024];
455	#ifdef MAP_PRIVATE
456		char*	srcbuf;
457		char*	dstbuf;
458		int	fd;
459		size_t	siz;
460		int	i;
461	#endif
462
463	#if defined(__ia64) || defined(__ia64__) || defined(__itanium__)
464		/*
465		 * 0 faith that the itanium coders will ever get this right
466		 * prove me wrong
467		 */
468
469		return 1;
470	#endif
471	
472		/*
473		 * early mac osx failed here -- fixed 3Q 2001
474		 */
475
476		if (memccpy(buf, "abc", 0, sizeof(buf)) != (buf + 4))
477			return 1;
478	#ifdef MAP_PRIVATE
479		siz = 64 * 1024;
480		if (!(dstbuf = malloc(2 * siz)))
481			return 0;
482		if ((fd = open("/dev/zero", O_RDWR)) < 0)
483			return 0;
484		if (!(srcbuf = (char*)mmap(NULL, siz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)))
485			return 0;
486		if (!mmap(srcbuf + siz, siz, PROT_NONE, MAP_PRIVATE, fd, 0))
487			return 0;
488		for (i = 0; i < siz; i++)
489			srcbuf[i] = 'x';
490		srcbuf[siz - 1] = 0;
491		alarm(10);
492		signal(SIGSEGV, gotcha);
493		signal(SIGBUS, gotcha);
494		signal(SIGALRM, gotcha);
495		/*
496		 * sgi ia64 dumps here as of 3Q 2001
497		 * bug acknowleged 1Q 2003
498		 */
499		memccpy(dstbuf, srcbuf, 0, siz + 10);
500		alarm(0);
501		if (strcmp(srcbuf, dstbuf))
502			return 1;
503		if (indict_sgi_ia64_4Q_2004(1))
504			return 1;
505		if (indict_sgi_ia64_4Q_2004(257))
506			return 1;
507	#endif
508		return 0;
509	}
510}end
511
512tst	lib_utime_now note{ utime works with 0 time vector }end execute{
513	#include <sys/types.h>
514	_BEGIN_EXTERNS_
515	extern int	utime _ARG_((const char*, void*));
516	_END_EXTERNS_
517	int
518	main()
519	{
520		return utime(".", (void*)0) == -1;
521	}
522}end
523
524tst	cross{
525	u=att
526	case `/bin/cat -s /dev/null/foo 2>&1` in
527	'')	;;
528	*)	case `/bin/echo '\\t'` in
529		'\t')	u=ucb ;;
530		esac
531		;;
532	esac
533	echo "#define _UNIV_DEFAULT	\"$u\"	/* default universe name */"
534}end
535
536std	cleanup note{ stuck with standard _cleanup }end noexecute{
537	_BEGIN_EXTERNS_
538	extern void exit _ARG_((int));
539	extern void _exit _ARG_((int));
540	extern void _cleanup();
541	void _cleanup() { _exit(0); }
542	_END_EXTERNS_
543	int main() { printf("cleanup\n"); exit(1); }
544}end
545
546std	remove note{ stuck with standard remove() }end nostatic{
547	_BEGIN_EXTERNS_
548	extern int unlink _ARG_((const char*));
549	_END_EXTERNS_
550	#if _STD_
551	int remove(const char* path) { return 0; }
552	#else
553	int remove(path) char* path; { return 0; }
554	#endif
555	int main() { return unlink("foo"); }
556}end
557
558std	signal note{ stuck with standard signal }end nolink{
559	_BEGIN_EXTERNS_
560	extern int abort();
561	int signal() { return 0; }
562	_END_EXTERNS_
563	int main() { signal(); abort(); return 0; }
564}end
565
566std	strcoll note{ standard strcoll works }end execute{
567	#include <string.h>
568	#define S	"hello world"
569	int
570	main()
571	{
572		char	s[] = S;
573		char	t[] = S;
574		return strcoll(s, t) || strcmp(s, t);
575	}
576}end
577
578std	strtod stdlib.h note{ stuck with standard strtod }end nostatic{
579	_BEGIN_EXTERNS_
580	#if _STD_
581	double strtod(const char* s, char** e) { return 0.0; }
582	#else
583	double strtod(s, e) char* s; char** e; { return 0.0; }
584	#endif
585	_END_EXTERNS_
586	int main() { printf(""); return strtod("1",0) != 0; }
587}end
588
589std	strtold stdlib.h note{ stuck with standard strtold }end nostatic{
590	_BEGIN_EXTERNS_
591	#if _STD_
592	long double strtold(const char* s, char** e) { return 0.0; }
593	#else
594	long double strtold(s, e) char* s; char** e; { return 0.0; }
595	#endif
596	_END_EXTERNS_
597	int main() { printf(""); return strtold("1",0) != 0; }
598}end
599
600std	strtol note{ stuck with standard strtol }end nostatic{
601	_BEGIN_EXTERNS_
602	#if _STD_
603	extern long atol(const char*);
604	long strtol(const char* s, char** e, int b) { return 0; }
605	#else
606	extern long atol();
607	long strtol(s, e, b) char* s; char** e; int b; { return 0; }
608	#endif
609	_END_EXTERNS_
610	int main() { printf(""); return (atol("1") + strtol("1",(char**)0,0)) != 0; }
611}end
612
613tst	- output{
614	int
615	main()
616	{
617	#if _UWIN
618		printf("\n");
619		printf("/* override some uwin feature tests */\n");
620		printf("#undef	_lib_execlp\n");
621		printf("#undef	_lib_execvp\n");
622		printf("#undef	_lib_execvpe\n");
623		printf("#undef	_lib_fork\n");
624		printf("#undef	_std_string\n");
625		printf("#define _std_string	1\n");
626		printf("#undef	_stream_peek\n");
627		printf("\n");
628	#endif
629
630	#if _lib_spawnveg || _lib_posix_spawn || _lib_spawn_mode || _lib_spawn && _hdr_spawn && _mem_pgroup_inheritance || _lib_vfork && _real_vfork
631		printf("#if !_AST_no_spawnveg\n");
632		printf("#define _use_spawnveg	1\n");
633		printf("#endif\n");
634		printf("\n");
635	#endif
636
637		return 0;
638	}
639
640}end
641
642tst	no64 -D_LARGEFILE64_SOURCE note{ largefile 64 broken }end execute{
643	#include <sys/types.h>
644	#include <sys/stat.h>
645	int
646	main()
647	{
648		struct stat64	st;
649		return !stat64(".", &st) && st.st_mode && st.st_mtime;
650	}
651}end pass{
652	echo "/* can we at least agree that a successful return means success? */"
653	echo "#undef	_lib_creat64"
654	echo "#undef	_lib_fstat64"
655	echo "#undef	_lib_fstatvfs64"
656	echo "#undef	_lib_ftruncate64"
657	echo "#undef	_lib_lseek64"
658	echo "#undef	_lib_lstat64"
659	echo "#undef	_lib_mmap64"
660	echo "#undef	_lib_stat64"
661	echo "#undef	_lib_statvfs64"
662	echo "#undef	_lib_truncate64"
663}end
664