1 /*
2  * pxheader - program to sit in front of interpreter code to make shell mods
3  *	      unnecessary to make Pascal obj's look like real programs.
4  *
5  * This program lives in /usr/lib/px_header
6  * Bill Joy UCB February 6, 1978
7  */
8 
9 static char sccsid[] = "@(#)px_header.c 1.2 03/06/81";
10 
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <a.out.h>
14 #include "whoami.h"
15 #include "objfmt.h"
16 
17 #define	ETXTBSY	26
18 #define	ADDR_LC	HEADER_BYTES - sizeof (struct exec) - sizeof (struct pxhdr)
19 
20 extern	errno;
21 
22 main(argc, argv)
23 	register int argc;
24 	register char *argv[];
25 {
26 	register int i, j;
27 	register unsigned short *ip;
28 	char *largv[512];
29 	int pv[2];
30 
31 	if (argc > 510) {
32 		error("Too many arguments.\n");
33 		exit(1);
34 	}
35 	largv[0] = argv[0];
36 	largv[1] = "-";
37 	for (i = 1; i < argc; i++)
38 		largv[i + 1] = argv[i];
39 	largv[argc + 1] = 0;
40 	pipe(pv);
41 	i = fork();
42 	if (i == -1)
43 		error("Try again.\n");
44 	if (i == 0) {
45 		close(pv[0]);
46 		ip = (unsigned short *)(ADDR_LC);
47 		i = ((struct pxhdr *)(ip))->objsize + sizeof(struct pxhdr);
48 		while (i != 0) {
49 			j = (i > 0 && i < BUFSIZ) ? i : BUFSIZ;
50 			write(pv[1], ip, j);
51 			ip += BUFSIZ / sizeof ( unsigned short );
52 			i -= j;
53 		}
54 		exit(1);
55 	}
56 	close(pv[1]);
57 	if (pv[0] != 3) {
58 		close(3);
59 		dup(pv[0]);
60 		close(pv[0]);
61 	}
62 	for (;;) {
63 		execv(PX_INTRP, largv);
64 		if (errno != ETXTBSY)
65 			break;
66 		sleep(2);
67 	}
68 	error("Px not found.\n");
69 }
70 
71 error(cp)
72 	register char *cp;
73 {
74 	register int i;
75 	register char *dp;
76 
77 	dp = cp;
78 	i = 0;
79 	while (*dp++)
80 		i++;
81 	write(2, cp, i);
82 	exit(1);
83 }
84 
85 exit(i)
86 {
87 	_exit(i);
88 }
89