@@ -89,6 +89,27 @@ static inline const TCHAR *escape(const TCHAR *str) {
8989 return out ;
9090}
9191
92+ static inline TCHAR * concat (const TCHAR * prefix , const TCHAR * suffix );
93+
94+ static TCHAR * make_response_file (const TCHAR * * argv ) {
95+ if (!argv [1 ])
96+ return NULL ;
97+ TCHAR * temp_path = malloc (MAX_PATH * sizeof (* temp_path ));
98+ if (GetTempPath (MAX_PATH , temp_path ) == 0 )
99+ return NULL ;
100+ TCHAR * rsp_file = malloc (MAX_PATH * sizeof (* rsp_file ));
101+ if (GetTempFileName (temp_path , _T ("ctw" ), 0 , rsp_file ) == 0 )
102+ return NULL ;
103+
104+ FILE * f = _tfopen (rsp_file , _T ("w, ccs=UNICODE" ));
105+ for (int i = 1 ; argv [i ]; i ++ )
106+ _ftprintf (f , _T (TS "\n" ), argv [i ]);
107+ fclose (f );
108+ argv [1 ] = escape (concat (_T ("@" ), rsp_file ));
109+ argv [2 ] = NULL ;
110+ return rsp_file ;
111+ }
112+
92113static inline int _tspawnvp_escape (int mode , const TCHAR * filename , const TCHAR * const * argv ) {
93114 int num_args = 0 ;
94115 while (argv [num_args ])
@@ -100,12 +121,17 @@ static inline int _tspawnvp_escape(int mode, const TCHAR *filename, const TCHAR
100121 total += 1 + _tcslen (escaped_argv [i ]);
101122 }
102123 escaped_argv [num_args ] = NULL ;
103- int ret = _tspawnvp (mode , filename , escaped_argv );
104- if (ret == -1 && total >= 32767 ) {
105- int err = errno ;
106- fprintf (stderr , "command line too long; %d characters\n" , total );
107- errno = err ;
124+ const TCHAR * temp_file = NULL ;
125+ if (total > 32000 ) {
126+ // If we are getting close to the limit, write the arguments to
127+ // a temporary response file.
128+ temp_file = make_response_file (escaped_argv );
129+ if (temp_file )
130+ total = _tcslen (escaped_argv [0 ]) + _tcslen (escaped_argv [1 ]) + 2 ;
108131 }
132+ int ret = _tspawnvp (mode , filename , escaped_argv );
133+ if (temp_file )
134+ DeleteFile (temp_file );
109135 return ret ;
110136}
111137#else
0 commit comments