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