Improve error reporting in the Windows port when env size is too large.

w32/subproc/misc.c (arr2envblk): Compute and return the size of
the environment passed to child process.

w32/subproc/sub_proc.c (process_begin): If the call to
CreateProcess failed with EINVAL, and the required environment
size was larger than 32KB, assume it's a Windows XP limitation,
and display an error message to that effect.

w32/subproc/proc.h (arr2envblk): Update prototype.

Copyright-paperwork-exempt: yes
This commit is contained in:
Gisle Vanem 2014-02-07 11:15:56 +02:00 committed by Eli Zaretskii
parent 88713683fe
commit b981bfd197
3 changed files with 11 additions and 4 deletions

View File

@ -36,7 +36,7 @@ int _cdecl compare(const void *a1, const void *a2)
return _stricoll(*((char**)a1),*((char**)a2)); return _stricoll(*((char**)a1),*((char**)a2));
} }
bool_t bool_t
arr2envblk(char **arr, char **envblk_out) arr2envblk(char **arr, char **envblk_out, int *envsize_needed)
{ {
char **tmp; char **tmp;
int size_needed; int size_needed;
@ -54,13 +54,14 @@ arr2envblk(char **arr, char **envblk_out)
} }
arrcnt = 0; arrcnt = 0;
size_needed = 0; size_needed = *envsize_needed = 0;
while (arr[arrcnt]) { while (arr[arrcnt]) {
tmp[arrcnt] = arr[arrcnt]; tmp[arrcnt] = arr[arrcnt];
size_needed += strlen(arr[arrcnt]) + 1; size_needed += strlen(arr[arrcnt]) + 1;
arrcnt++; arrcnt++;
} }
size_needed++; size_needed++;
*envsize_needed = size_needed;
qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare); qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare);

View File

@ -24,6 +24,6 @@ typedef int bool_t;
#define E_NO_MEM 103 #define E_NO_MEM 103
#define E_FORK 104 #define E_FORK 104
extern bool_t arr2envblk(char **arr, char **envblk_out); extern bool_t arr2envblk(char **arr, char **envblk_out, int *envsize_needed);
#endif #endif

View File

@ -593,6 +593,7 @@ process_begin(
STARTUPINFO startInfo; STARTUPINFO startInfo;
PROCESS_INFORMATION procInfo; PROCESS_INFORMATION procInfo;
char *envblk=NULL; char *envblk=NULL;
int envsize_needed = 0;
int pass_null_exec_path = 0; int pass_null_exec_path = 0;
/* /*
@ -734,10 +735,15 @@ process_begin(
} }
if (envp) { if (envp) {
if (arr2envblk(envp, &envblk) ==FALSE) { if (arr2envblk(envp, &envblk, &envsize_needed) == FALSE) {
pproc->last_err = 0; pproc->last_err = 0;
pproc->lerrno = E_NO_MEM; pproc->lerrno = E_NO_MEM;
free( command_line ); free( command_line );
if (pproc->last_err == ERROR_INVALID_PARAMETER
&& envsize_needed > 32*1024) {
fprintf (stderr, "CreateProcess failed, probably because environment is too large (%d bytes).\n",
envsize_needed);
}
return(-1); return(-1);
} }
} }