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