1 /* inststr.c ... stolen from bdupdate.c, which stole it from perl 4.
2 * Theft by C. Scott Ananian <cananian@alumni.princeton.edu>
3 * Modified similarly to perl 5.8.3's alignment-checking code
4 8 by Paul Howarth <paul@city-fan.org>
6 * $Id: inststr.c,v 1.3 2004/06/08 23:40:14 quozl Exp $
11 #define PTRSIZE sizeof(void *)
12 typedef unsigned long UL
;
15 inststr(int argc
, char **argv
, char **environ
, char *src
)
17 if (strlen(src
) <= strlen(argv
[0]))
21 for (ptr
= argv
[0]; *ptr
; *(ptr
++) = '\0');
26 /* Stolen from the source to perl 4.036 (assigning to $0) */
27 /* Modified to allow for aligned array members, assuming */
28 /* no system has something bizarre like the argv[] */
29 /* interleaved with some other data. Also allow for argv */
30 /* array having higher numbered elements lower in memory */
31 /* than lower numbered elements. */
34 UL mask
= ~(UL
)(PTRSIZE
== 4 ? 3 : PTRSIZE
== 8 ? 7 : PTRSIZE
== 16 ? 15 : 0);
35 int aligned
= (mask
< ~(UL
)0) && (((UL
)(argv
[0]) & mask
) == (UL
)(argv
[0]));
36 ptr
= argv
[0] + strlen(argv
[0]);
37 if (argv
[argc
- 1] >= argv
[1]) {
38 /* argv pointers in ascending memory order */
39 for (count
= 1; count
< argc
; count
++) {
40 if (argv
[count
] == ptr
+ 1
42 (aligned
&& argv
[count
] > ptr
&& argv
[count
] <= (char *)((UL
)(ptr
+ PTRSIZE
) & mask
))
44 ptr
= argv
[count
] + strlen(argv
[count
]);
49 /* sometimes the argv pointers go down in memory rather than up */
50 for (count
= argc
- 1; count
> 0; count
--) {
51 if (argv
[count
] == ptr
+ 1
53 (aligned
&& argv
[count
] > ptr
&& argv
[count
] <= (char *)((UL
)(ptr
+ PTRSIZE
) & mask
))
55 ptr
= argv
[count
] + strlen(argv
[count
]);
59 for (count
= 0; environ
[count
]; count
++) {
60 if (environ
[count
] == ptr
+ 1
62 (aligned
&& environ
[count
] > ptr
&& environ
[count
] <= (char *)((UL
)(ptr
+ PTRSIZE
) & mask
))
64 ptr
= environ
[count
] + strlen(environ
[count
]);
68 for (ptr2
= argv
[0]; ptr2
<= ptr
; ptr2
++) {
72 strncpy(argv
[0], src
, count
);