diff options
author | Ron Yorston <rmy@pobox.com> | 2018-03-04 08:56:04 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-03-04 08:56:04 +0000 |
commit | 31997b1796bdaf5734f5fff1a20a637d8872419d (patch) | |
tree | 9c27f6741a1149059cb4f2cb324f6b2ee913e428 | |
parent | 13cb88b0f6f2a69076e91858fbbdd0c65697e621 (diff) | |
download | busybox-w32-31997b1796bdaf5734f5fff1a20a637d8872419d.tar.gz busybox-w32-31997b1796bdaf5734f5fff1a20a637d8872419d.tar.bz2 busybox-w32-31997b1796bdaf5734f5fff1a20a637d8872419d.zip |
win32: reduce amount of static data
It appears that uninitialised static variables are placed in the
data section rather than bss, increasing the size of the binary.
Rewrite some code to reduce the amount of static data.
-rw-r--r-- | win32/isaac.c | 96 | ||||
-rw-r--r-- | win32/mingw.c | 24 | ||||
-rw-r--r-- | win32/mntent.c | 46 | ||||
-rw-r--r-- | win32/process.c | 62 |
4 files changed, 127 insertions, 101 deletions
diff --git a/win32/isaac.c b/win32/isaac.c index 8e9da9baf..ba51d199a 100644 --- a/win32/isaac.c +++ b/win32/isaac.c | |||
@@ -19,34 +19,36 @@ You may use this code in any way you wish, and it is free. No warrantee. | |||
19 | */ | 19 | */ |
20 | #include "libbb.h" | 20 | #include "libbb.h" |
21 | 21 | ||
22 | /* external results */ | 22 | typedef struct { |
23 | static uint32_t randrsl[256]; | 23 | /* external results */ |
24 | uint32_t randrsl[256]; | ||
24 | 25 | ||
25 | /* internal state */ | 26 | /* internal state */ |
26 | static uint32_t mm[256]; | 27 | uint32_t mm[256]; |
27 | static uint32_t aa=0, bb=0, cc=0; | 28 | uint32_t aa, bb, cc; |
29 | } isaac_t; | ||
28 | 30 | ||
29 | 31 | ||
30 | static void isaac(void) | 32 | static void isaac(isaac_t *t) |
31 | { | 33 | { |
32 | register uint32_t i,x,y; | 34 | register uint32_t i,x,y; |
33 | 35 | ||
34 | cc = cc + 1; /* cc just gets incremented once per 256 results */ | 36 | t->cc = t->cc + 1; /* cc just gets incremented once per 256 results */ |
35 | bb = bb + cc; /* then combined with bb */ | 37 | t->bb = t->bb + t->cc; /* then combined with bb */ |
36 | 38 | ||
37 | for (i=0; i<256; ++i) | 39 | for (i=0; i<256; ++i) |
38 | { | 40 | { |
39 | x = mm[i]; | 41 | x = t->mm[i]; |
40 | switch (i%4) | 42 | switch (i%4) |
41 | { | 43 | { |
42 | case 0: aa = aa^(aa<<13); break; | 44 | case 0: t->aa = t->aa^(t->aa<<13); break; |
43 | case 1: aa = aa^(aa>>6); break; | 45 | case 1: t->aa = t->aa^(t->aa>>6); break; |
44 | case 2: aa = aa^(aa<<2); break; | 46 | case 2: t->aa = t->aa^(t->aa<<2); break; |
45 | case 3: aa = aa^(aa>>16); break; | 47 | case 3: t->aa = t->aa^(t->aa>>16); break; |
46 | } | 48 | } |
47 | aa = mm[(i+128)%256] + aa; | 49 | t->aa = t->mm[(i+128)%256] + t->aa; |
48 | mm[i] = y = mm[(x>>2)%256] + aa + bb; | 50 | t->mm[i] = y = t->mm[(x>>2)%256] + t->aa + t->bb; |
49 | randrsl[i] = bb = mm[(y>>10)%256] + x; | 51 | t->randrsl[i] = t->bb = t->mm[(y>>10)%256] + x; |
50 | 52 | ||
51 | /* Note that bits 2..9 are chosen from x but 10..17 are chosen | 53 | /* Note that bits 2..9 are chosen from x but 10..17 are chosen |
52 | from y. The only important thing here is that 2..9 and 10..17 | 54 | from y. The only important thing here is that 2..9 and 10..17 |
@@ -71,11 +73,11 @@ static void isaac(void) | |||
71 | h^=a>>9; c+=h; a+=b; \ | 73 | h^=a>>9; c+=h; a+=b; \ |
72 | } | 74 | } |
73 | 75 | ||
74 | static void randinit(int flag) | 76 | static void randinit(isaac_t *t, int flag) |
75 | { | 77 | { |
76 | int i; | 78 | int i; |
77 | uint32_t a,b,c,d,e,f,g,h; | 79 | uint32_t a,b,c,d,e,f,g,h; |
78 | aa=bb=cc=0; | 80 | t->aa = t->bb = t->cc = 0; |
79 | a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */ | 81 | a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */ |
80 | 82 | ||
81 | for (i=0; i<4; ++i) /* scramble it */ | 83 | for (i=0; i<4; ++i) /* scramble it */ |
@@ -87,27 +89,28 @@ static void randinit(int flag) | |||
87 | { | 89 | { |
88 | if (flag) /* use all the information in the seed */ | 90 | if (flag) /* use all the information in the seed */ |
89 | { | 91 | { |
90 | a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3]; | 92 | a+=t->randrsl[i ]; b+=t->randrsl[i+1]; c+=t->randrsl[i+2]; |
91 | e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7]; | 93 | d+=t->randrsl[i+3]; e+=t->randrsl[i+4]; f+=t->randrsl[i+5]; |
94 | g+=t->randrsl[i+6]; h+=t->randrsl[i+7]; | ||
92 | } | 95 | } |
93 | mix(a,b,c,d,e,f,g,h); | 96 | mix(a,b,c,d,e,f,g,h); |
94 | mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; | 97 | t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d; |
95 | mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; | 98 | t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h; |
96 | } | 99 | } |
97 | 100 | ||
98 | if (flag) | 101 | if (flag) |
99 | { /* do a second pass to make all of the seed affect all of mm */ | 102 | { /* do a second pass to make all of the seed affect all of mm */ |
100 | for (i=0; i<256; i+=8) | 103 | for (i=0; i<256; i+=8) |
101 | { | 104 | { |
102 | a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; | 105 | a+=t->mm[i ]; b+=t->mm[i+1]; c+=t->mm[i+2]; d+=t->mm[i+3]; |
103 | e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7]; | 106 | e+=t->mm[i+4]; f+=t->mm[i+5]; g+=t->mm[i+6]; h+=t->mm[i+7]; |
104 | mix(a,b,c,d,e,f,g,h); | 107 | mix(a,b,c,d,e,f,g,h); |
105 | mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; | 108 | t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d; |
106 | mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; | 109 | t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h; |
107 | } | 110 | } |
108 | } | 111 | } |
109 | 112 | ||
110 | isaac(); /* fill in the first set of results */ | 113 | isaac(t); /* fill in the first set of results */ |
111 | } | 114 | } |
112 | 115 | ||
113 | /* call 'fn' to put data in 'dt' then copy it to generator state */ | 116 | /* call 'fn' to put data in 'dt' then copy it to generator state */ |
@@ -115,7 +118,7 @@ static void randinit(int flag) | |||
115 | fn(&dt); \ | 118 | fn(&dt); \ |
116 | u = (uint32_t *)&dt; \ | 119 | u = (uint32_t *)&dt; \ |
117 | for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \ | 120 | for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \ |
118 | randrsl[i++] = *u++; \ | 121 | t->randrsl[i++] = *u++; \ |
119 | } | 122 | } |
120 | 123 | ||
121 | /* | 124 | /* |
@@ -123,7 +126,7 @@ static void randinit(int flag) | |||
123 | * This is unlikely to be very robust: don't rely on it for | 126 | * This is unlikely to be very robust: don't rely on it for |
124 | * anything that needs to be secure. | 127 | * anything that needs to be secure. |
125 | */ | 128 | */ |
126 | static void get_entropy(void) | 129 | static void get_entropy(isaac_t *t) |
127 | { | 130 | { |
128 | int i, j, len; | 131 | int i, j, len; |
129 | SYSTEMTIME tm; | 132 | SYSTEMTIME tm; |
@@ -136,9 +139,9 @@ static void get_entropy(void) | |||
136 | unsigned char buf[16]; | 139 | unsigned char buf[16]; |
137 | 140 | ||
138 | i = 0; | 141 | i = 0; |
139 | randrsl[i++] = (uint32_t)GetCurrentProcessId(); | 142 | t->randrsl[i++] = (uint32_t)GetCurrentProcessId(); |
140 | randrsl[i++] = (uint32_t)GetCurrentThreadId(); | 143 | t->randrsl[i++] = (uint32_t)GetCurrentThreadId(); |
141 | randrsl[i++] = (uint32_t)GetTickCount(); | 144 | t->randrsl[i++] = (uint32_t)GetTickCount(); |
142 | 145 | ||
143 | GET_DATA(GetLocalTime, tm) | 146 | GET_DATA(GetLocalTime, tm) |
144 | GET_DATA(GlobalMemoryStatus, ms) | 147 | GET_DATA(GlobalMemoryStatus, ms) |
@@ -159,12 +162,12 @@ static void get_entropy(void) | |||
159 | 162 | ||
160 | u = (uint32_t *)buf; | 163 | u = (uint32_t *)buf; |
161 | for (j=0; j<sizeof(buf)/sizeof(uint32_t); ++j) { | 164 | for (j=0; j<sizeof(buf)/sizeof(uint32_t); ++j) { |
162 | randrsl[i++] = *u++; | 165 | t->randrsl[i++] = *u++; |
163 | } | 166 | } |
164 | 167 | ||
165 | #if 0 | 168 | #if 0 |
166 | { | 169 | { |
167 | unsigned char *p = (unsigned char *)randrsl; | 170 | unsigned char *p = (unsigned char *)t->randrsl; |
168 | 171 | ||
169 | for (j=0; j<i*sizeof(uint32_t); ++j) { | 172 | for (j=0; j<i*sizeof(uint32_t); ++j) { |
170 | fprintf(stderr, "%02x", *p++); | 173 | fprintf(stderr, "%02x", *p++); |
@@ -180,8 +183,8 @@ static void get_entropy(void) | |||
180 | #endif | 183 | #endif |
181 | } | 184 | } |
182 | 185 | ||
183 | #define RAND_BYTES sizeof(randrsl) | 186 | #define RAND_BYTES sizeof(t->randrsl) |
184 | #define RAND_WORDS (sizeof(randrsl)/sizeof(randrsl[0])) | 187 | #define RAND_WORDS (sizeof(t->randrsl)/sizeof(t->randrsl[0])) |
185 | 188 | ||
186 | /* | 189 | /* |
187 | * Place 'count' random bytes in the buffer 'buf'. You're responsible | 190 | * Place 'count' random bytes in the buffer 'buf'. You're responsible |
@@ -189,29 +192,26 @@ static void get_entropy(void) | |||
189 | */ | 192 | */ |
190 | ssize_t get_random_bytes(void *buf, ssize_t count) | 193 | ssize_t get_random_bytes(void *buf, ssize_t count) |
191 | { | 194 | { |
192 | static int initialised = 0; | 195 | static isaac_t *t = NULL; |
193 | static int rand_index = 0; | 196 | static int rand_index = 0; |
194 | int i; | ||
195 | ssize_t save_count = count; | 197 | ssize_t save_count = count; |
196 | unsigned char *ptr = (unsigned char *)randrsl; | 198 | unsigned char *ptr; |
197 | 199 | ||
198 | if (buf == NULL || count < 0) { | 200 | if (buf == NULL || count < 0) { |
199 | errno = EINVAL; | 201 | errno = EINVAL; |
200 | return -1; | 202 | return -1; |
201 | } | 203 | } |
202 | 204 | ||
203 | if (!initialised) { | 205 | if (!t) { |
204 | aa = bb = cc = (uint32_t)0; | 206 | t = xzalloc(sizeof(isaac_t)); |
205 | for (i=0; i<RAND_WORDS; ++i) | ||
206 | mm[i] = randrsl[i] = (uint32_t)0; | ||
207 | 207 | ||
208 | get_entropy(); | 208 | get_entropy(t); |
209 | randinit(1); | 209 | randinit(t, 1); |
210 | isaac(); | 210 | isaac(t); |
211 | rand_index = 0; | 211 | rand_index = 0; |
212 | initialised = 1; | ||
213 | } | 212 | } |
214 | 213 | ||
214 | ptr = (unsigned char *)t->randrsl; | ||
215 | while (count > 0) { | 215 | while (count > 0) { |
216 | int bytes_left = RAND_BYTES - rand_index; | 216 | int bytes_left = RAND_BYTES - rand_index; |
217 | 217 | ||
@@ -231,7 +231,7 @@ ssize_t get_random_bytes(void *buf, ssize_t count) | |||
231 | 231 | ||
232 | if (rand_index >= RAND_BYTES) { | 232 | if (rand_index >= RAND_BYTES) { |
233 | /* generate more */ | 233 | /* generate more */ |
234 | isaac(); | 234 | isaac(t); |
235 | rand_index = 0; | 235 | rand_index = 0; |
236 | } | 236 | } |
237 | } | 237 | } |
diff --git a/win32/mingw.c b/win32/mingw.c index bedf14784..4c449514a 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -676,11 +676,14 @@ int mingw_rename(const char *pold, const char *pnew) | |||
676 | 676 | ||
677 | static char *gethomedir(void) | 677 | static char *gethomedir(void) |
678 | { | 678 | { |
679 | static char buf[PATH_MAX]; | 679 | static char *buf = NULL; |
680 | DWORD len = sizeof(buf); | 680 | DWORD len = PATH_MAX; |
681 | HANDLE h; | 681 | HANDLE h; |
682 | char *s; | 682 | char *s; |
683 | 683 | ||
684 | if (!buf) | ||
685 | buf = xmalloc(PATH_MAX); | ||
686 | |||
684 | buf[0] = '\0'; | 687 | buf[0] = '\0'; |
685 | if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) ) | 688 | if ( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &h) ) |
686 | return buf; | 689 | return buf; |
@@ -701,11 +704,17 @@ static char *gethomedir(void) | |||
701 | return buf; | 704 | return buf; |
702 | } | 705 | } |
703 | 706 | ||
707 | #define NAME_LEN 100 | ||
704 | static char *get_user_name(void) | 708 | static char *get_user_name(void) |
705 | { | 709 | { |
706 | static char user_name[100] = ""; | 710 | static char *user_name = NULL; |
707 | char *s; | 711 | char *s; |
708 | DWORD len = sizeof(user_name); | 712 | DWORD len = NAME_LEN; |
713 | |||
714 | if ( user_name == NULL ) { | ||
715 | user_name = xmalloc(NAME_LEN); | ||
716 | user_name[0] = '\0'; | ||
717 | } | ||
709 | 718 | ||
710 | if ( user_name[0] != '\0' ) { | 719 | if ( user_name[0] != '\0' ) { |
711 | return user_name; | 720 | return user_name; |
@@ -857,7 +866,12 @@ char *realpath(const char *path, char *resolved_path) | |||
857 | 866 | ||
858 | const char *get_busybox_exec_path(void) | 867 | const char *get_busybox_exec_path(void) |
859 | { | 868 | { |
860 | static char path[PATH_MAX] = ""; | 869 | static char *path = NULL; |
870 | |||
871 | if (!path) { | ||
872 | path = xmalloc(PATH_MAX); | ||
873 | path[0] = '\0'; | ||
874 | } | ||
861 | 875 | ||
862 | if (!*path) | 876 | if (!*path) |
863 | GetModuleFileName(NULL, path, PATH_MAX); | 877 | GetModuleFileName(NULL, path, PATH_MAX); |
diff --git a/win32/mntent.c b/win32/mntent.c index 9b04a9c5e..f9a2d26d4 100644 --- a/win32/mntent.c +++ b/win32/mntent.c | |||
@@ -7,6 +7,11 @@ | |||
7 | struct mntdata { | 7 | struct mntdata { |
8 | DWORD flags; | 8 | DWORD flags; |
9 | int index; | 9 | int index; |
10 | struct mntent me; | ||
11 | char mnt_fsname[4]; | ||
12 | char mnt_dir[4]; | ||
13 | char mnt_type[100]; | ||
14 | char mnt_opts[4]; | ||
10 | }; | 15 | }; |
11 | 16 | ||
12 | FILE *setmntent(const char *file UNUSED_PARAM, const char *mode UNUSED_PARAM) | 17 | FILE *setmntent(const char *file UNUSED_PARAM, const char *mode UNUSED_PARAM) |
@@ -26,34 +31,35 @@ FILE *setmntent(const char *file UNUSED_PARAM, const char *mode UNUSED_PARAM) | |||
26 | struct mntent *getmntent(FILE *stream) | 31 | struct mntent *getmntent(FILE *stream) |
27 | { | 32 | { |
28 | struct mntdata *data = (struct mntdata *)stream; | 33 | struct mntdata *data = (struct mntdata *)stream; |
29 | static char mnt_fsname[4]; | ||
30 | static char mnt_dir[4]; | ||
31 | static char mnt_type[100]; | ||
32 | static char mnt_opts[4]; | ||
33 | static struct mntent my_mount_entry = | ||
34 | { mnt_fsname, mnt_dir, mnt_type, mnt_opts, 0, 0 }; | ||
35 | struct mntent *entry; | 34 | struct mntent *entry; |
36 | 35 | ||
36 | data->me.mnt_fsname = data->mnt_fsname; | ||
37 | data->me.mnt_dir = data->mnt_dir; | ||
38 | data->me.mnt_type = data->mnt_type; | ||
39 | data->me.mnt_opts = data->mnt_opts; | ||
40 | data->me.mnt_freq = 0; | ||
41 | data->me.mnt_passno = 0; | ||
42 | |||
37 | entry = NULL; | 43 | entry = NULL; |
38 | while ( ++data->index < 26 ) { | 44 | while ( ++data->index < 26 ) { |
39 | if ( (data->flags & 1<<data->index) != 0 ) { | 45 | if ( (data->flags & 1<<data->index) != 0 ) { |
40 | mnt_fsname[0] = 'A' + data->index; | 46 | data->mnt_fsname[0] = 'A' + data->index; |
41 | mnt_fsname[1] = ':'; | 47 | data->mnt_fsname[1] = ':'; |
42 | mnt_fsname[2] = '\0'; | 48 | data->mnt_fsname[2] = '\0'; |
43 | mnt_dir[0] = 'A' + data->index; | 49 | data->mnt_dir[0] = 'A' + data->index; |
44 | mnt_dir[1] = ':'; | 50 | data->mnt_dir[1] = ':'; |
45 | mnt_dir[2] = '\\'; | 51 | data->mnt_dir[2] = '\\'; |
46 | mnt_dir[3] = '\0'; | 52 | data->mnt_dir[3] = '\0'; |
47 | mnt_type[0] = '\0'; | 53 | data->mnt_type[0] = '\0'; |
48 | mnt_opts[0] = '\0'; | 54 | data->mnt_opts[0] = '\0'; |
49 | 55 | ||
50 | if ( GetDriveType(mnt_dir) == DRIVE_FIXED ) { | 56 | if ( GetDriveType(data->mnt_dir) == DRIVE_FIXED ) { |
51 | if ( !GetVolumeInformation(mnt_dir, NULL, 0, NULL, NULL, | 57 | if ( !GetVolumeInformation(data->mnt_dir, NULL, 0, NULL, NULL, |
52 | NULL, mnt_type, 100) ) { | 58 | NULL, data->mnt_type, 100) ) { |
53 | mnt_type[0] = '\0'; | 59 | data->mnt_type[0] = '\0'; |
54 | } | 60 | } |
55 | 61 | ||
56 | entry = &my_mount_entry; | 62 | entry = &data->me; |
57 | break; | 63 | break; |
58 | } | 64 | } |
59 | } | 65 | } |
diff --git a/win32/process.c b/win32/process.c index 96561c482..0d6d70970 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -39,43 +39,50 @@ next_path_sep(const char *path) | |||
39 | return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); | 39 | return strchr(has_dos_drive_prefix(path) ? path+2 : path, ':'); |
40 | } | 40 | } |
41 | 41 | ||
42 | static char * | 42 | typedef struct { |
43 | parse_interpreter(const char *cmd, char **name, char **opts) | 43 | char *path; |
44 | char *name; | ||
45 | char *opts; | ||
46 | char buf[100]; | ||
47 | } interp_t; | ||
48 | |||
49 | static int | ||
50 | parse_interpreter(const char *cmd, interp_t *interp) | ||
44 | { | 51 | { |
45 | static char buf[100]; | ||
46 | char *path, *t; | 52 | char *path, *t; |
47 | int n, fd; | 53 | int n, fd; |
48 | 54 | ||
49 | fd = open(cmd, O_RDONLY); | 55 | fd = open(cmd, O_RDONLY); |
50 | if (fd < 0) | 56 | if (fd < 0) |
51 | return NULL; | 57 | return 0; |
52 | n = read(fd, buf, sizeof(buf)-1); | 58 | n = read(fd, interp->buf, sizeof(interp->buf)-1); |
53 | close(fd); | 59 | close(fd); |
54 | if (n < 4) /* at least '#!/x' and not error */ | 60 | if (n < 4) /* at least '#!/x' and not error */ |
55 | return NULL; | 61 | return 0; |
56 | 62 | ||
57 | /* | 63 | /* |
58 | * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia | 64 | * See http://www.in-ulm.de/~mascheck/various/shebang/ for trivia |
59 | * relating to '#!'. | 65 | * relating to '#!'. |
60 | */ | 66 | */ |
61 | if (buf[0] != '#' || buf[1] != '!') | 67 | if (interp->buf[0] != '#' || interp->buf[1] != '!') |
62 | return NULL; | 68 | return 0; |
63 | buf[n] = '\0'; | 69 | interp->buf[n] = '\0'; |
64 | if ((t=strchr(buf, '\n')) == NULL) | 70 | if ((t=strchr(interp->buf, '\n')) == NULL) |
65 | return NULL; | 71 | return 0; |
66 | t[1] = '\0'; | 72 | t[1] = '\0'; |
67 | 73 | ||
68 | if ((path=strtok(buf+2, " \t\r\n")) == NULL) | 74 | if ((path=strtok(interp->buf+2, " \t\r\n")) == NULL) |
69 | return NULL; | 75 | return 0; |
70 | 76 | ||
71 | t = (char *)bb_basename(path); | 77 | t = (char *)bb_basename(path); |
72 | if (*t == '\0') | 78 | if (*t == '\0') |
73 | return NULL; | 79 | return 0; |
74 | 80 | ||
75 | *name = t; | 81 | interp->path = path; |
76 | *opts = strtok(NULL, "\r\n"); | 82 | interp->name = t; |
83 | interp->opts = strtok(NULL, "\r\n"); | ||
77 | 84 | ||
78 | return path; | 85 | return 1; |
79 | } | 86 | } |
80 | 87 | ||
81 | /* | 88 | /* |
@@ -284,36 +291,35 @@ mingw_spawn_interpreter(int mode, const char *prog, char *const *argv, char *con | |||
284 | { | 291 | { |
285 | intptr_t ret; | 292 | intptr_t ret; |
286 | int nopts; | 293 | int nopts; |
287 | char *int_name, *opts; | 294 | interp_t interp; |
288 | char *int_path = parse_interpreter(prog, &int_name, &opts); | ||
289 | char **new_argv; | 295 | char **new_argv; |
290 | int argc = -1; | 296 | int argc = -1; |
291 | char *fullpath = NULL; | 297 | char *fullpath = NULL; |
292 | 298 | ||
293 | if (!int_path) | 299 | if (!parse_interpreter(prog, &interp)) |
294 | return spawnveq(mode, prog, argv, envp); | 300 | return spawnveq(mode, prog, argv, envp); |
295 | 301 | ||
296 | nopts = opts != NULL; | 302 | nopts = interp.opts != NULL; |
297 | while (argv[++argc]) | 303 | while (argv[++argc]) |
298 | ; | 304 | ; |
299 | 305 | ||
300 | new_argv = xmalloc(sizeof(*argv)*(argc+nopts+2)); | 306 | new_argv = xmalloc(sizeof(*argv)*(argc+nopts+2)); |
301 | new_argv[1] = opts; | 307 | new_argv[1] = interp.opts; |
302 | new_argv[nopts+1] = (char *)prog; /* pass absolute path */ | 308 | new_argv[nopts+1] = (char *)prog; /* pass absolute path */ |
303 | memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); | 309 | memcpy(new_argv+nopts+2, argv+1, sizeof(*argv)*argc); |
304 | 310 | ||
305 | if ((fullpath=add_win32_extension(int_path)) != NULL || | 311 | if ((fullpath=add_win32_extension(interp.path)) != NULL || |
306 | file_is_executable(int_path)) { | 312 | file_is_executable(interp.path)) { |
307 | new_argv[0] = fullpath ? fullpath : int_path; | 313 | new_argv[0] = fullpath ? fullpath : interp.path; |
308 | ret = spawnveq(mode, new_argv[0], new_argv, envp); | 314 | ret = spawnveq(mode, new_argv[0], new_argv, envp); |
309 | } else | 315 | } else |
310 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE | 316 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE |
311 | if (find_applet_by_name(int_name) >= 0) { | 317 | if (find_applet_by_name(interp.name) >= 0) { |
312 | new_argv[0] = int_name; | 318 | new_argv[0] = interp.name; |
313 | ret = mingw_spawn_applet(mode, new_argv, envp); | 319 | ret = mingw_spawn_applet(mode, new_argv, envp); |
314 | } else | 320 | } else |
315 | #endif | 321 | #endif |
316 | if ((fullpath=find_first_executable(int_name)) != NULL) { | 322 | if ((fullpath=find_first_executable(interp.name)) != NULL) { |
317 | new_argv[0] = fullpath; | 323 | new_argv[0] = fullpath; |
318 | ret = spawnveq(mode, fullpath, new_argv, envp); | 324 | ret = spawnveq(mode, fullpath, new_argv, envp); |
319 | } | 325 | } |