source: trunk/src/kmk/output.c

Last change on this file was 3671, checked in by bird, 5 months ago

kmk: Workaround for the cygwin pipe problem.

  • Property svn:eol-style set to native
File size: 58.8 KB
Line 
1/* Output to stdout / stderr for GNU make
2Copyright (C) 2013-2016 Free Software Foundation, Inc.
3This file is part of GNU Make.
4
5GNU Make is free software; you can redistribute it and/or modify it under the
6terms of the GNU General Public License as published by the Free Software
7Foundation; either version 3 of the License, or (at your option) any later
8version.
9
10GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#if defined (KBUILD_OS_WINDOWS) && (defined(KMK) || defined(DEBUG_STDOUT_CLOSE_ISSUE))
18# include "nt/ntstuff.h"
19# include "nt/nthlp.h"
20# include <process.h>
21#endif
22#include "makeint.h"
23#include "job.h"
24
25/* GNU make no longer supports pre-ANSI89 environments. */
26
27#include <assert.h>
28#include <stdio.h>
29#include <stdarg.h>
30
31#ifdef HAVE_UNISTD_H
32# include <unistd.h>
33#endif
34
35#ifdef HAVE_FCNTL_H
36# include <fcntl.h>
37#else
38# include <sys/file.h>
39#endif
40
41#ifdef WINDOWS32
42# include <windows.h>
43# include <io.h>
44# ifndef CONFIG_NEW_WIN_CHILDREN
45# include "sub_proc.h"
46# else
47# include "w32/winchildren.h"
48# endif
49#endif /* WINDOWS32 */
50#ifdef KBUILD_OS_WINDOWS
51# include "console.h"
52#endif
53
54struct output *output_context = NULL;
55unsigned int stdio_traced = 0;
56
57#define OUTPUT_NONE (-1)
58
59#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
60
61#ifdef HAVE_FCNTL_H
62# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
63#else
64# define STREAM_OK(_s) 1
65#endif
66
67#ifdef DEBUG_STDOUT_CLOSE_ISSUE
68
69/* fflush wrapper w/ error checking + reporting for stdout.
70 This is to debug the mysterious 'kmk: write error: stdout' errors. */
71int g_fStdOutError = 0;
72
73# ifdef KBUILD_OS_WINDOWS
74static void my_output_pipe_info (HANDLE hStdOut, const char *pszWhere)
75{
76 MY_IO_STATUS_BLOCK Ios = {0} ;
77 struct MY_FILE_PIPE_INFORMATION
78 {
79 ULONG ReadMode;
80 ULONG CompletionMode;
81 } Info1 = {0};
82 MY_NTSTATUS rcNt1 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &Info1, sizeof(Info1), MyFilePipeInformation);
83 struct MY_FILE_PIPE_LOCAL_INFORMATION
84 {
85 ULONG NamedPipeType;
86 ULONG NamedPipeConfiguration;
87 ULONG MaximumInstances;
88 ULONG CurrentInstances;
89 ULONG InboundQuota;
90 ULONG ReadDataAvailable;
91 ULONG OutboundQuota;
92 ULONG WriteQuotaAvailable;
93 ULONG NamedPipeState;
94 ULONG NamedPipeEnd;
95 } Info2 = {0};
96 MY_NTSTATUS rcNt2 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &Info2, sizeof(Info2), MyFilePipeLocalInformation);
97 union { BYTE ab[1024]; MY_FILE_NAME_INFORMATION NameInfo; } uBuf = {{0}};
98 MY_NTSTATUS rcNt3 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &uBuf, sizeof(uBuf) - sizeof(WCHAR), MyFileNameInformation);
99 DWORD dwMode = 0;
100 MY_NTSTATUS rcNt4 = g_pfnNtQueryInformationFile(hStdOut, &Ios, &dwMode, sizeof(dwMode), MyFileModeInformation);
101 fprintf(stderr, "kmk[%u/%u]: stdout pipeinfo at %s: fmode=%#x pipemode=%#x complmode=%#x type=%#x cfg=%#x instances=%u/%u inquota=%#x readable=%#x outquota=%#x writable=%#x state=%#x end=%#x hStdOut=%p %S rcNt=%#x/%#x/%#x/%#x\n",
102 makelevel, _getpid(), pszWhere, dwMode, Info1.ReadMode, Info1.CompletionMode, Info2.NamedPipeType,
103 Info2.NamedPipeConfiguration, Info2.CurrentInstances, Info2.MaximumInstances, Info2.InboundQuota,
104 Info2.ReadDataAvailable, Info2.OutboundQuota, Info2.WriteQuotaAvailable, Info2.NamedPipeState, Info2.NamedPipeEnd,
105 hStdOut, uBuf.NameInfo.FileName, rcNt1, rcNt2, rcNt3, rcNt4);
106}
107# endif /* KBUILD_OS_WINDOWS */
108
109static void my_stdout_error (const char *pszOperation, const char *pszMessage)
110{
111# ifdef KBUILD_OS_WINDOWS
112 DWORD const dwErr = GetLastError ();
113# endif
114 int const iErrNo = errno;
115 int const fdFile = fileno (stdout);
116# ifdef KBUILD_OS_WINDOWS
117 HANDLE const hNative = (HANDLE)_get_osfhandle (_fileno (stdout));
118 DWORD const dwType = GetFileType (hNative);
119 unsigned int uDosErr = _doserrno;
120 if ((dwType & ~FILE_TYPE_REMOTE) == FILE_TYPE_PIPE)
121 my_output_pipe_info (hNative, "error");
122 fprintf (stderr, "kmk[%u/%u]: stdout error: %s: %s! (lasterr=%u errno=%d fileno=%d uDosErr=%u native=%p type=%#x)\n",
123 makelevel, _getpid(), pszOperation, pszMessage, dwErr, iErrNo, fdFile, uDosErr, hNative, dwType);
124# else
125 fprintf (stderr, "kmk[%u]: stdout error: %s: %s! (lasterr=%u errno=%d fileno=%d)\n",
126 makelevel, pszOperation, pszMessage, dwErr, iErrNo, fdFile);
127# endif
128}
129
130/* Preserves errno and win32 last error. */
131void my_check_stdout (const char *pszWhere)
132{
133 if (!g_fStdOutError)
134 {
135# ifdef KBUILD_OS_WINDOWS
136 DWORD const dwErrSaved = GetLastError();
137# endif
138 int const iErrNoSaved = errno;
139
140 if (ferror (stdout))
141 {
142 my_stdout_error (pszWhere, "error pending!");
143 g_fStdOutError = 1;
144 }
145
146 errno = iErrNoSaved;
147# ifdef KBUILD_OS_WINDOWS
148 SetLastError(dwErrSaved);
149# endif
150 }
151}
152
153# ifdef KBUILD_OS_WINDOWS
154/* generic fwrite wrapper */
155__declspec(dllexport) size_t __cdecl fwrite(void const *pvBuf, size_t cbItem, size_t cItems, FILE *pFile)
156{
157 size_t cbWritten;
158 if (pFile == stdout)
159 my_check_stdout("fwrite/entry");
160 _lock_file(pFile);
161 cbWritten = _fwrite_nolock(pvBuf, cbItem, cItems, pFile);
162 _unlock_file(pFile);
163 if (pFile == stdout)
164 my_check_stdout("fwrite/exit");
165 return cbWritten;
166}
167void * const __imp_fwrite = (void *)(uintptr_t)fwrite;
168
169/* generic fflush wrapper */
170__declspec(dllexport) int __cdecl fflush(FILE *pFile)
171{
172 int rc;
173 if (pFile == stdout || !pFile)
174 my_check_stdout("fflush/entry");
175 if (pFile)
176 {
177 _lock_file(pFile);
178 rc = _fflush_nolock(pFile);
179 _unlock_file(pFile);
180 }
181 if (pFile == stdout || !pFile)
182 my_check_stdout("fflush/exit");
183 return rc;
184}
185void * const __imp_fflush = (void *)(uintptr_t)fflush;
186
187# else
188static int my_fflush (FILE *pFile)
189{
190 if (pFile == stdout && !g_fStdOutError)
191 {
192 if (!ferror (pFile))
193 {
194 int rcRet = fflush (pFile);
195 g_fStdOutError = ferror (pFile);
196 if (rcRet != EOF && !g_fStdOutError)
197 { /* likely */ }
198 else if (rcRet == EOF)
199 my_stdout_error ("fflush(stdout)", "flush failed!");
200 else
201 my_stdout_error ("fflush(stdout)", "error pending after successful flush!");
202
203 return rcRet;
204 }
205 else
206 {
207 my_stdout_error ("fflush(stdout)", "error pending on entry!");
208 g_fStdOutError = 1;
209 }
210
211 }
212 return fflush (pFile);
213}
214
215# undef fflush
216# define fflush(a_pFile) my_fflush(a_pFile)
217# endif
218
219#endif /* DEBUG_STDOUT_CLOSE_ISSUE */
220
221#if defined(KBUILD_OS_WINDOWS) && defined(KMK)
222/*
223 Windows Asynchronous (Overlapping) Pipe Hack
224 --------------------------------------------
225
226 If a write pipe is opened with FILE_FLAG_OVERLAPPED or equivalent flags,
227 concurrent WriteFile calls on that pipe may run into a race causing the
228 wrong thread to be worken up on completion. Since the write is still
229 pending, the number of bytes written hasn't been set and is still zero.
230 This leads to UCRT setting errno = ENOSPC and may cause stack corruption
231 when the write is finally completed and the IO_STATUS_BLOCK is written
232 by the kernel.
233
234 To work around this problem, we detect asynchronous pipes attached to
235 stdout and stderr and replaces them with standard pipes and threads
236 pumping output. The thread deals properly with the async writes. */
237
238/* Data for the pipe workaround hacks. */
239struct win_pipe_hacks
240{
241 /* 1 (stdout) or 2 (stderr). */
242 int fd;
243 int volatile fShutdown;
244 /** Event handle for overlapped I/O. */
245 HANDLE hEvt;
246 /* The original pipe that's in overlapping state (write end). */
247 HANDLE hDstPipe;
248 /* The replacement pipe (read end). */
249 HANDLE hSrcPipe;
250 /** The thread pumping bytes between the two pipes. */
251 HANDLE hThread;
252 /** Putting the overlapped I/O structure here is safer. */
253 OVERLAPPED Overlapped;
254} g_pipe_workarounds[2] =
255{
256 { 1, 0, NULL, NULL, NULL, NULL, { 0, 0, {{ 0, 0}}} },
257 { 2, 0, NULL, NULL, NULL, NULL, { 0, 0, {{ 0, 0}}} },
258};
259
260/* Thread function that pumps bytes between our pipe and the parents pipe. */
261static unsigned __stdcall win_pipe_pump_thread (void *user)
262{
263 unsigned const idx = (unsigned)(intptr_t)user;
264 int fQuit = 0;
265 do
266 {
267 /* Read from the source pipe (our). */
268 char achBuf[4096];
269 DWORD cbRead = 0;
270 if (ReadFile (g_pipe_workarounds[idx].hSrcPipe, achBuf, sizeof(achBuf), &cbRead, NULL))
271 {
272 for (unsigned iWrite = 0, off = 0; off < cbRead && !fQuit; iWrite++)
273 {
274 /* Write the data we've read to the origianl pipe, using overlapped
275 I/O. This should work fine even if hDstPipe wasn't opened in
276 overlapped I/O mode. */
277 g_pipe_workarounds[idx].Overlapped.Internal = 0;
278 g_pipe_workarounds[idx].Overlapped.InternalHigh = 0;
279 g_pipe_workarounds[idx].Overlapped.Offset = 0xffffffff /*FILE_WRITE_TO_END_OF_FILE*/;
280 g_pipe_workarounds[idx].Overlapped.OffsetHigh = (DWORD)-1;
281 g_pipe_workarounds[idx].Overlapped.hEvent = g_pipe_workarounds[idx].hEvt;
282 DWORD cbWritten = 0;
283 if (!WriteFile (g_pipe_workarounds[idx].hDstPipe, &achBuf[off], cbRead - off,
284 &cbWritten, &g_pipe_workarounds[idx].Overlapped))
285 {
286 if ((fQuit = GetLastError () != ERROR_IO_PENDING))
287 break;
288 if ((fQuit = !GetOverlappedResult (g_pipe_workarounds[idx].hDstPipe, &g_pipe_workarounds[idx].Overlapped,
289 &cbWritten, TRUE)))
290 break;
291 }
292 off += cbWritten;
293 if (cbWritten == 0 && iWrite > 15)
294 {
295 DWORD fState = 0;
296 if ( GetNamedPipeHandleState(g_pipe_workarounds[idx].hDstPipe, &fState, NULL, NULL, NULL, NULL, 0)
297 && (fState & (PIPE_WAIT | PIPE_NOWAIT)) == PIPE_NOWAIT)
298 {
299 fState &= ~PIPE_NOWAIT;
300 fState |= PIPE_WAIT;
301 if ( SetNamedPipeHandleState(g_pipe_workarounds[idx].hDstPipe, &fState, NULL, NULL)
302 && iWrite == 16)
303 continue;
304 }
305 Sleep(iWrite & 15);
306 }
307 }
308 }
309 else
310 break;
311 }
312 while (!g_pipe_workarounds[idx].fShutdown && !fQuit);
313
314 /* Cleanup. */
315 CloseHandle (g_pipe_workarounds[idx].hSrcPipe);
316 g_pipe_workarounds[idx].hSrcPipe = NULL;
317
318 CloseHandle (g_pipe_workarounds[idx].hDstPipe);
319 g_pipe_workarounds[idx].hDstPipe = NULL;
320
321 CloseHandle (g_pipe_workarounds[idx].hEvt);
322 g_pipe_workarounds[idx].hEvt = NULL;
323 return 0;
324}
325
326/* Shuts down the thread pumping bytes between our pipe and the parents pipe. */
327static void win_pipe_hack_terminate (void)
328{
329 for (unsigned idx = 0; idx < 2; idx++)
330 if (g_pipe_workarounds[idx].hThread != NULL)
331 {
332 g_pipe_workarounds[idx].fShutdown++;
333 if (g_pipe_workarounds[idx].hSrcPipe != NULL)
334 CancelIoEx (g_pipe_workarounds[idx].hSrcPipe, NULL);
335 }
336
337 for (unsigned idx = 0; idx < 2; idx++)
338 if (g_pipe_workarounds[idx].hThread != NULL)
339 for (unsigned msWait = 64; msWait <= 1000; msWait *= 2) /* wait almost 2 seconds. */
340 {
341 if (g_pipe_workarounds[idx].hSrcPipe != NULL)
342 CancelIoEx (g_pipe_workarounds[idx].hSrcPipe, NULL);
343 DWORD dwWait = WaitForSingleObject (g_pipe_workarounds[idx].hThread, msWait);
344 if (dwWait == WAIT_OBJECT_0)
345 {
346 CloseHandle (g_pipe_workarounds[idx].hThread);
347 g_pipe_workarounds[idx].hThread = NULL;
348 break;
349 }
350 }
351}
352
353/* Applies the asynchronous pipe hack to a standard handle.
354 The hPipe argument is the handle, and idx is 0 for stdout and 1 for stderr. */
355static void win_pipe_hack_apply (HANDLE hPipe, int idx, int fSameObj)
356{
357 /* Create a normal pipe and assign it to an CRT file descriptor. The handles
358 will be created as not inheritable, but the _dup2 call below will duplicate
359 the write handle with inhertiance enabled. */
360 HANDLE hPipeR = NULL;
361 HANDLE hPipeW = NULL;
362 if (CreatePipe (&hPipeR, &hPipeW, NULL, 0x1000))
363 {
364 int fdTmp = _open_osfhandle ((intptr_t)hPipeW, _O_TEXT);
365 if (fdTmp >= 0)
366 {
367 int const fOldMode = _setmode (idx + 1, _O_TEXT);
368 if (fOldMode != _O_TEXT && fOldMode != -1)
369 {
370 _setmode (idx + 1, fOldMode);
371 _setmode (fdTmp, fOldMode);
372 }
373
374 /* Create the event sempahore. */
375 HANDLE hEvt = CreateEventW (NULL, FALSE, FALSE, NULL);
376 if (hEvt != NULL && hEvt != INVALID_HANDLE_VALUE)
377 {
378 /* Duplicate the pipe, as the _dup2 call below will (probably) close it. */
379 HANDLE hDstPipe = NULL;
380 if (DuplicateHandle (GetCurrentProcess (), hPipe,
381 GetCurrentProcess (), &hDstPipe,
382 0, FALSE, DUPLICATE_SAME_ACCESS))
383 {
384 /* Create a thread for safely pumping bytes between the pipes. */
385 g_pipe_workarounds[idx].hEvt = hEvt;
386 g_pipe_workarounds[idx].fShutdown = 0;
387 g_pipe_workarounds[idx].hDstPipe = hDstPipe;
388 g_pipe_workarounds[idx].hSrcPipe = hPipeR;
389 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, win_pipe_pump_thread, (void *)(intptr_t)idx, 0, NULL);
390 if (hThread != NULL && hThread != INVALID_HANDLE_VALUE)
391 {
392 g_pipe_workarounds[idx].hThread = hThread;
393
394 /* Now that the thread is operating, replace the file descriptors(s).
395 This involves DuplicateHandle and will call SetStdHandle. */
396 if (_dup2 (fdTmp, idx + 1) == 0)
397 {
398 if ( fSameObj
399 && _dup2 (fdTmp, idx + 2) != 0)
400 {
401 fprintf (stderr, "%s: warning: _dup2(%d,%d) failed - fSameObj=1: %s (%d, %u)",
402 program, fdTmp, idx + 2, strerror (errno), errno, GetLastError ());
403 fSameObj = 0;
404 }
405
406 /* Boost the thread priority. */
407 int const iPrioOld = GetThreadPriority (hThread);
408 int const iPrioNew = iPrioOld < THREAD_PRIORITY_NORMAL ? THREAD_PRIORITY_NORMAL
409 : iPrioOld < THREAD_PRIORITY_HIGHEST ? THREAD_PRIORITY_HIGHEST
410 : iPrioOld;
411 if (iPrioOld != iPrioNew)
412 SetThreadPriority (hThread, iPrioNew);
413
414 /* Update the standard handle and close the temporary file descriptor. */
415 close (fdTmp);
416 return;
417 }
418 g_pipe_workarounds[idx].fShutdown = 1;
419 fprintf (stderr, "%s: warning: _dup2(%d,%d) failed: %s (%d, %u)",
420 program, fdTmp, idx + 1, strerror (errno), errno, GetLastError ());
421 for (unsigned msWait = 64; msWait <= 1000; msWait *= 2) /* wait almost 2 seconds. */
422 {
423 if (g_pipe_workarounds[idx].hSrcPipe != NULL)
424 CancelIoEx (g_pipe_workarounds[idx].hSrcPipe, NULL);
425 DWORD dwWait = WaitForSingleObject (hThread, msWait);
426 if (dwWait == WAIT_OBJECT_0)
427 break;
428 }
429 CloseHandle (g_pipe_workarounds[idx].hThread);
430 }
431 else
432 fprintf (stderr, "%s: warning: _beginthreadex failed: %s (%d, %u)",
433 program, strerror (errno), errno, GetLastError ());
434 CloseHandle (hDstPipe);
435 }
436 else
437 fprintf (stderr, "%s: warning: DuplicateHandle failed: %u", program, GetLastError ());
438 }
439 else
440 fprintf (stderr, "%s: warning: CreateEventW failed: %u", program, GetLastError ());
441 close (fdTmp);
442 }
443 else
444 {
445 fprintf (stderr, "%s: warning: _open_osfhandle failed: %s (%d, %u)",
446 program, strerror (errno), errno, GetLastError ());
447 CloseHandle (hPipeW);
448 }
449 CloseHandle (hPipeR);
450 }
451 else
452 fprintf (stderr, "%s: warning: CreatePipe failed: %u", program, GetLastError());
453}
454
455/* Check if the two handles refers to the same pipe. */
456int win_pipe_is_same_object (HANDLE hPipe1, HANDLE hPipe2)
457{
458 if (hPipe1 == NULL || hPipe1 == INVALID_HANDLE_VALUE)
459 return 0;
460 if (hPipe1 == hPipe2)
461 return 1;
462
463 /* Since windows 10 there is an API for this. */
464 typedef BOOL (WINAPI *PFNCOMPAREOBJECTHANDLES)(HANDLE, HANDLE);
465 static int s_fInitialized = 0;
466 static PFNCOMPAREOBJECTHANDLES s_pfnCompareObjectHandles = NULL;
467 PFNCOMPAREOBJECTHANDLES pfnCompareObjectHandles = s_pfnCompareObjectHandles;
468 if (!pfnCompareObjectHandles && !s_fInitialized)
469 {
470 pfnCompareObjectHandles = (PFNCOMPAREOBJECTHANDLES)GetProcAddress (GetModuleHandleW (L"kernelbase.dll"),
471 "CompareObjectHandles");
472 s_pfnCompareObjectHandles = pfnCompareObjectHandles;
473 s_fInitialized = 1;
474 }
475 if (pfnCompareObjectHandles)
476 return pfnCompareObjectHandles (hPipe1, hPipe2);
477
478 /* Otherwise we use FileInternalInformation, assuming ofc that the two are
479 local pipes. */
480 birdResolveImportsWorker();
481 MY_IO_STATUS_BLOCK Ios = {0};
482 MY_FILE_INTERNAL_INFORMATION Info1;
483 MY_NTSTATUS rcNt = g_pfnNtQueryInformationFile (hPipe1, &Ios, &Info1, sizeof(Info1), MyFileInternalInformation);
484 if (!NT_SUCCESS (rcNt))
485 return 0;
486
487 MY_FILE_INTERNAL_INFORMATION Info2;
488 rcNt = g_pfnNtQueryInformationFile (hPipe2, &Ios, &Info2, sizeof(Info2), MyFileInternalInformation);
489 if (!NT_SUCCESS (rcNt))
490 return 0;
491
492 return Info1.IndexNumber.QuadPart == Info2.IndexNumber.QuadPart;
493}
494
495/* Predicate function that checks if the hack is required. */
496static int win_pipe_hack_needed (HANDLE hPipe, const char *pszEnvVarOverride)
497{
498 birdResolveImportsWorker ();
499
500 /* Check the environment variable override first.
501 Setting it to '0' disables the hack, setting to anything else (other than
502 an empty string) forces the hack to be enabled. */
503 const char * const pszValue = getenv (pszEnvVarOverride);
504 if (pszValue && *pszValue != '\0')
505 return *pszValue != '0';
506
507 /* Check whether it is a pipe next. */
508 DWORD const fType = GetFileType (hPipe) & ~FILE_TYPE_REMOTE;
509 if (fType != FILE_TYPE_PIPE)
510 return 0;
511
512 /* Check if the pipe is synchronous or overlapping. If it's overlapping
513 we must apply the workaround. */
514 MY_IO_STATUS_BLOCK Ios = {0};
515 DWORD fFlags = 0;
516 MY_NTSTATUS rcNt = g_pfnNtQueryInformationFile (hPipe, &Ios, &fFlags, sizeof(fFlags), MyFileModeInformation);
517 if ( NT_SUCCESS(rcNt)
518 && !(fFlags & (FILE_SYNCHRONOUS_IO_NONALERT | FILE_SYNCHRONOUS_IO_ALERT)))
519 return 1;
520
521#if 1
522 /* We could also check if the pipe is in NOWAIT mode, but since we've got
523 code elsewhere for switching them to WAIT mode, we probably don't need
524 to do that... */
525 if ( GetNamedPipeHandleStateW (hPipe, &fFlags, NULL, NULL, NULL, NULL, 0)
526 && (fFlags & PIPE_NOWAIT))
527 return 1;
528#endif
529 return 0;
530}
531
532/** Initializes the pipe hack. */
533static void win_pipe_hack_init (void)
534{
535 HANDLE const hStdOut = (HANDLE)_get_osfhandle (_fileno (stdout));
536 int const fStdOutNeeded = win_pipe_hack_needed (hStdOut, "KMK_PIPE_HACK_STDOUT");
537 HANDLE const hStdErr = (HANDLE)_get_osfhandle (_fileno (stderr));
538 int const fStdErrNeeded = win_pipe_hack_needed (hStdErr, "KMK_PIPE_HACK_STDERR");
539
540 /* To avoid getting too mixed up output in a 'kmk |& tee log' situation, we
541 must try figure out if the two handles refer to the same pipe object. */
542 int const fSameObj = fStdOutNeeded
543 && fStdErrNeeded
544 && win_pipe_is_same_object (hStdOut, hStdOut);
545
546 /* Apply the hack as needed. */
547 if (fStdOutNeeded)
548 win_pipe_hack_apply (hStdOut, 0, fSameObj);
549 if (fStdErrNeeded && !fSameObj)
550 win_pipe_hack_apply (hStdErr, 1, 0);
551 if (getenv ("KMK_PIPE_HACK_DEBUG"))
552 fprintf (stderr, "fStdOutNeeded=%d fStdErrNeeded=%d fSameObj=%d\n",
553 fStdOutNeeded, fStdErrNeeded, fSameObj);
554}
555
556#endif /* KBUILD_OS_WINDOWS && KMK */
557
558#if defined(KMK) && !defined(NO_OUTPUT_SYNC)
559/* Non-negative if we're counting output lines.
560
561 This is used by die_with_job_output to decide whether the initial build
562 error needs to be repeated because there was too much output from parallel
563 jobs between it and the actual make termination. */
564int output_metered = -1;
565
566static void meter_output_block (char const *buffer, size_t len)
567{
568 while (len > 0)
569 {
570 char *nl = (char *)memchr (buffer, '\n', len);
571 size_t linelen;
572 if (nl)
573 {
574 linelen = nl - buffer + 1;
575 output_metered++;
576 }
577 else
578 linelen = len;
579 output_metered += linelen / 132;
580
581 /* advance */
582 buffer += linelen;
583 len -= linelen;
584 }
585}
586#endif
587
588
589#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
590# define MEMBUF_MIN_SEG_SIZE 4096
591# define MEMBUF_MAX_SEG_SIZE (512*1024)
592# define MEMBUF_MAX_MOVE_LEN ( MEMBUF_MIN_SEG_SIZE \
593 - offsetof (struct output_segment, runs) \
594 - sizeof (struct output_run))
595# define MEMBUF_MAX_TOTAL ( sizeof (void *) <= 4 \
596 ? (size_t)512*1024 : (size_t)16*1024*1024 )
597
598static void *acquire_semaphore (void);
599static void release_semaphore (void *);
600static int log_working_directory (int);
601
602/* Is make's stdout going to the same place as stderr?
603 Also, did we already sync_init (== -1)? */
604static int combined_output = -1;
605
606/* Helper for membuf_reset and output_reset */
607static membuf_reset (struct output *out)
608{
609 struct output_segment *seg;
610 while ((seg = out->out.head_seg))
611 {
612 out->out.head_seg = seg->next;
613 free (seg);
614 }
615 out->out.tail_seg = NULL;
616 out->out.tail_run = NULL;
617 out->out.head_run = NULL;
618 out->out.left = 0;
619 out->out.total = 0;
620
621 while ((seg = out->err.head_seg))
622 {
623 out->err.head_seg = seg->next;
624 free (seg);
625 }
626 out->err.tail_seg = NULL;
627 out->err.tail_run = NULL;
628 out->err.head_run = NULL;
629 out->err.left = 0;
630 out->err.total = 0;
631
632 out->seqno = 0;
633}
634
635/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
636void output_reset (struct output *out)
637{
638 if (out && (out->out.total || out->err.total))
639 membuf_reset (out);
640}
641
642/* Internal worker for output_dump and membuf_dump_most. */
643static void membuf_dump (struct output *out)
644{
645 if (out->out.total || out->err.total)
646 {
647 int traced = 0;
648 struct output_run *err_run;
649 struct output_run *out_run;
650 FILE *prevdst;
651
652 /* Try to acquire the semaphore. If it fails, dump the output
653 unsynchronized; still better than silently discarding it.
654 We want to keep this lock for as little time as possible. */
655 void *sem = acquire_semaphore ();
656# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
657 int prev_mode_out = _setmode (fileno (stdout), _O_BINARY);
658 int prev_mode_err = _setmode (fileno (stderr), _O_BINARY);
659# endif
660
661# ifndef KMK /* this drives me bananas. */
662 /* Log the working directory for this dump. */
663 if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
664 traced = log_working_directory (1);
665# endif
666
667 /* Work the out and err sequences in parallel. */
668 out_run = out->out.head_run;
669 err_run = out->err.head_run;
670 prevdst = NULL;
671 while (err_run || out_run)
672 {
673 FILE *dst;
674 const void *src;
675 size_t len;
676 if (out_run && (!err_run || out_run->seqno <= err_run->seqno))
677 {
678 src = out_run + 1;
679 len = out_run->len;
680 dst = stdout;
681 out_run = out_run->next;
682 }
683 else
684 {
685 src = err_run + 1;
686 len = err_run->len;
687 dst = stderr;
688 err_run = err_run->next;
689 }
690 if (dst != prevdst)
691 fflush (prevdst);
692 prevdst = dst;
693#ifdef KMK
694 if (output_metered < 0)
695 { /* likely */ }
696 else
697 meter_output_block (src, len);
698#endif
699# if 0 /* for debugging */
700 while (len > 0)
701 {
702 const char *nl = (const char *)memchr (src, '\n', len);
703 size_t line_len = nl ? nl - (const char *)src + 1 : len;
704 char *tmp = (char *)xmalloc (1 + line_len + 1 + 1);
705 tmp[0] = '{';
706 memcpy (&tmp[1], src, line_len);
707 tmp[1 + line_len] = '}';
708# ifdef KBUILD_OS_WINDOWS
709 maybe_con_fwrite (tmp, 1 + line_len + 1, 1, dst);
710# else
711 fwrite (tmp, 1 + line_len + 1, 1, dst);
712# endif
713 free (tmp);
714 src = (const char *)src + line_len;
715 len -= line_len;
716 }
717#else
718# ifdef KBUILD_OS_WINDOWS
719 maybe_con_fwrite (src, len, 1, dst);
720# else
721 fwrite (src, len, 1, dst);
722# endif
723# endif
724 }
725 if (prevdst)
726 fflush (prevdst);
727
728# ifndef KMK /* this drives me bananas. */
729 if (traced)
730 log_working_directory (0);
731# endif
732
733 /* Exit the critical section. */
734# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
735 if (prev_mode_out != -1)
736 _setmode (fileno (stdout), prev_mode_out);
737 if (prev_mode_err != -1)
738 _setmode (fileno (stderr), prev_mode_err);
739# endif
740 if (sem)
741 release_semaphore (sem);
742
743# ifdef KMK
744 if (!out->dont_truncate)
745 { /* likely */ }
746 else return;
747# endif
748
749 /* Free the segments and reset the state. */
750 membuf_reset (out);
751 }
752 else
753 assert (out->out.head_seg == NULL && out->err.head_seg == NULL);
754}
755
756/* Writes up to LEN bytes to the given segment.
757 Returns how much was actually written. */
758static size_t
759membuf_write_segment (struct output_membuf *membuf, struct output_segment *seg,
760 const char *src, size_t len, unsigned int *pseqno)
761{
762 size_t written = 0;
763 if (seg && membuf->left > 0)
764 {
765 struct output_run *run = membuf->tail_run;
766 char *dst = (char *)(run + 1) + run->len;
767 assert ((uintptr_t)run - (uintptr_t)seg < seg->size);
768
769 /* If the sequence number didn't change, then we can append
770 to the current run without further considerations. */
771 if (run->seqno == *pseqno)
772 written = len;
773 /* If the current run does not end with a newline, don't start a new
774 run till we encounter one. */
775 else if (dst[-1] != '\n')
776 {
777 char const *srcnl = (const char *)memchr (src, '\n', len);
778 written = srcnl ? srcnl - src + 1 : len;
779 }
780 /* Try create a new empty run and append to it. */
781 else
782 {
783 size_t const offnextrun = ( (uintptr_t)dst - (uintptr_t)(seg)
784 + sizeof(void *) - 1)
785 & ~(sizeof(void *) - 1);
786 if (offnextrun > seg->size - sizeof (struct output_run) * 2)
787 return 0; /* need new segment */
788
789 run = run->next = (struct output_run *)((char *)seg + offnextrun);
790 run->next = NULL;
791 run->seqno = ++(*pseqno);
792 run->len = 0;
793 membuf->tail_run = run;
794 membuf->left = seg->size - (offnextrun + sizeof (*run));
795 dst = (char *)(run + 1);
796 written = len;
797 }
798
799 /* Append to the current run. */
800 if (written > membuf->left)
801 written = membuf->left;
802 memcpy (dst, src, written);
803 run->len += written;
804 membuf->left -= written;
805 }
806 return written;
807}
808
809/* Helper for membuf_write_new_segment and membuf_dump_most that figures out
810 now much data needs to be moved from the previous run in order to make it
811 end with a newline. */
812static size_t membuf_calc_move_len (struct output_run *tail_run)
813{
814 size_t to_move = 0;
815 if (tail_run)
816 {
817 const char *data = (const char *)(tail_run + 1);
818 size_t off = tail_run->len;
819 while (off > 0 && data[off - 1] != '\n')
820 off--;
821 to_move = tail_run->len - off;
822 if (to_move >= MEMBUF_MAX_MOVE_LEN)
823 to_move = 0;
824 }
825 return to_move;
826}
827
828/* Allocates a new segment and writes to it.
829 This will take care to make sure the previous run terminates with
830 a newline so that we pass whole lines to fwrite when dumping. */
831static size_t
832membuf_write_new_segment (struct output_membuf *membuf, const char *src,
833 size_t len, unsigned int *pseqno)
834{
835 struct output_run *prev_run = membuf->tail_run;
836 struct output_segment *prev_seg = membuf->tail_seg;
837 size_t const to_move = membuf_calc_move_len (prev_run);
838 struct output_segment *new_seg;
839 size_t written;
840 char *dst;
841
842 /* Figure the the segment size. We start with MEMBUF_MIN_SEG_SIZE and double
843 it each time till we reach MEMBUF_MAX_SEG_SIZE. */
844 size_t const offset_runs = offsetof (struct output_segment, runs);
845 size_t segsize = !prev_seg ? MEMBUF_MIN_SEG_SIZE
846 : prev_seg->size >= MEMBUF_MAX_SEG_SIZE ? MEMBUF_MAX_SEG_SIZE
847 : prev_seg->size * 2;
848 while ( segsize < to_move + len + offset_runs + sizeof (struct output_run) * 2
849 && segsize < MEMBUF_MAX_SEG_SIZE)
850 segsize *= 2;
851
852 /* Allocate the segment and link it and the first run. */
853 new_seg = (struct output_segment *)xmalloc (segsize);
854 new_seg->size = segsize;
855 new_seg->next = NULL;
856 new_seg->runs[0].next = NULL;
857 if (!prev_seg)
858 {
859 membuf->head_seg = new_seg;
860 membuf->head_run = &new_seg->runs[0];
861 }
862 else
863 {
864 prev_seg->next = new_seg;
865 prev_run->next = &new_seg->runs[0];
866 }
867 membuf->tail_seg = new_seg;
868 membuf->tail_run = &new_seg->runs[0];
869 membuf->total += segsize;
870 membuf->left = segsize - sizeof (struct output_run) - offset_runs;
871
872 /* Initialize and write data to the first run. */
873 dst = (char *)&new_seg->runs[0]; /* Try bypass gcc array size cleverness. */
874 dst += sizeof (struct output_run);
875 assert (MEMBUF_MAX_MOVE_LEN < MEMBUF_MIN_SEG_SIZE);
876 if (to_move > 0)
877 {
878 /* Move to_move bytes from the previous run in hope that we'll get a
879 newline to soon. Afterwards call membuf_segment_write to work SRC. */
880 assert (prev_run != NULL);
881 assert (membuf->left >= to_move);
882 prev_run->len -= to_move;
883 new_seg->runs[0].len = to_move;
884 new_seg->runs[0].seqno = prev_run->seqno;
885 memcpy (dst, (const char *)(prev_run + 1) + prev_run->len, to_move);
886 membuf->left -= to_move;
887
888 written = membuf_write_segment (membuf, new_seg, src, len, pseqno);
889 }
890 else
891 {
892 /* Create a run with up to LEN from SRC. */
893 written = len;
894 if (written > membuf->left)
895 written = membuf->left;
896 new_seg->runs[0].len = written;
897 new_seg->runs[0].seqno = ++(*pseqno);
898 memcpy (dst, src, written);
899 membuf->left -= written;
900 }
901 return written;
902}
903
904/* Worker for output_write that will dump most of the output when we hit
905 MEMBUF_MAX_TOTAL on either of the two membuf structures, then free all the
906 output segments. Incomplete lines will be held over to the next buffers
907 and copied into new segments. */
908static void
909membuf_dump_most (struct output *out)
910{
911 size_t out_to_move = membuf_calc_move_len (out->out.tail_run);
912 size_t err_to_move = membuf_calc_move_len (out->err.tail_run);
913 if (!out_to_move && !err_to_move)
914 membuf_dump (out);
915 else
916 {
917 /* Allocate a stack buffer for holding incomplete lines. This should be
918 fine since we're only talking about max 2 * MEMBUF_MAX_MOVE_LEN.
919 The -1 on the sequence numbers, ise because membuf_write_new_segment
920 will increment them before use. */
921 unsigned int out_seqno = out_to_move ? out->out.tail_run->seqno - 1 : 0;
922 unsigned int err_seqno = err_to_move ? out->err.tail_run->seqno - 1 : 0;
923 char *tmp = alloca (out_to_move + err_to_move);
924 if (out_to_move)
925 {
926 out->out.tail_run->len -= out_to_move;
927 memcpy (tmp,
928 (char *)(out->out.tail_run + 1) + out->out.tail_run->len,
929 out_to_move);
930 }
931 if (err_to_move)
932 {
933 out->err.tail_run->len -= err_to_move;
934 memcpy (tmp + out_to_move,
935 (char *)(out->err.tail_run + 1) + out->err.tail_run->len,
936 err_to_move);
937 }
938
939 membuf_dump (out);
940
941 if (out_to_move)
942 {
943 size_t written = membuf_write_new_segment (&out->out, tmp,
944 out_to_move, &out_seqno);
945 assert (written == out_to_move); (void)written;
946 }
947 if (err_to_move)
948 {
949 size_t written = membuf_write_new_segment (&out->err,
950 tmp + out_to_move,
951 err_to_move, &err_seqno);
952 assert (written == err_to_move); (void)written;
953 }
954 }
955}
956
957
958
959/* write/fwrite like function, binary mode. */
960ssize_t
961output_write_bin (struct output *out, int is_err, const char *src, size_t len)
962{
963 size_t ret = len;
964 if (!out || !out->syncout)
965 {
966 FILE *f = is_err ? stderr : stdout;
967# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
968 /* On DOS platforms we need to disable \n -> \r\n converts that is common on
969 standard output/error. Also optimize for console output. */
970 int saved_errno;
971 int fd = fileno (f);
972 int prev_mode = _setmode (fd, _O_BINARY);
973 maybe_con_fwrite (src, len, 1, f);
974 if (fflush (f) == EOF)
975 ret = -1;
976 saved_errno = errno;
977 _setmode (fd, prev_mode);
978 errno = saved_errno;
979# else
980 fwrite (src, len, 1, f);
981 if (fflush (f) == EOF)
982 ret = -1;
983# endif
984 }
985 else
986 {
987 struct output_membuf *membuf = is_err ? &out->err : &out->out;
988 while (len > 0)
989 {
990 size_t runlen = membuf_write_segment (membuf, membuf->tail_seg, src, len, &out->seqno);
991 if (!runlen)
992 {
993 if (membuf->total < MEMBUF_MAX_TOTAL)
994 runlen = membuf_write_new_segment (membuf, src, len, &out->seqno);
995 else
996 membuf_dump_most (out);
997 }
998 /* advance */
999 len -= runlen;
1000 src += runlen;
1001 }
1002 }
1003 return ret;
1004}
1005
1006#endif /* CONFIG_WITH_OUTPUT_IN_MEMORY */
1007
1008/* write/fwrite like function, text mode. */
1009ssize_t
1010output_write_text (struct output *out, int is_err, const char *src, size_t len)
1011{
1012#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1013# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
1014 ssize_t ret = len;
1015 if (!out || !out->syncout)
1016 {
1017 /* ASSUME fwrite does the desired conversion. */
1018 FILE *f = is_err ? stderr : stdout;
1019# ifdef KBUILD_OS_WINDOWS
1020 if (maybe_con_fwrite (src, len, 1, f) < 0)
1021 ret = -1;
1022# else
1023 fwrite (src, len, 1, f);
1024# endif
1025 if (fflush (f) == EOF)
1026 ret = -1;
1027 }
1028 else
1029 {
1030 /* Work the buffer line by line, replacing each \n with \r\n. */
1031 while (len > 0)
1032 {
1033 const char *nl = memchr (src, '\n', len);
1034 size_t line_len = nl ? nl - src : len;
1035 output_write_bin (out, is_err, src, line_len);
1036 if (!nl)
1037 break;
1038 output_write_bin (out, is_err, "\r\n", 2);
1039 len -= line_len + 1;
1040 src += line_len + 1;
1041 }
1042 }
1043 return ret;
1044# else
1045 return output_write_bin (out, is_err, src, len);
1046# endif
1047#else
1048 ssize_t ret = len;
1049 if (! out || ! out->syncout)
1050 {
1051 FILE *f = is_err ? stderr : stdout;
1052# ifdef KBUILD_OS_WINDOWS
1053 maybe_con_fwrite(src, len, 1, f);
1054# else
1055 fwrite (src, len, 1, f);
1056# endif
1057 fflush (f);
1058 }
1059 else
1060 {
1061 int fd = is_err ? out->err : out->out;
1062 int r;
1063
1064 EINTRLOOP (r, lseek (fd, 0, SEEK_END));
1065 while (1)
1066 {
1067 EINTRLOOP (r, write (fd, src, len));
1068 if ((size_t)r == len || r <= 0)
1069 break;
1070 len -= r;
1071 src += r;
1072 }
1073 }
1074 return ret;
1075#endif
1076}
1077
1078
1079
1080/* Write a string to the current STDOUT or STDERR. */
1081static void
1082_outputs (struct output *out, int is_err, const char *msg)
1083{
1084#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1085 output_write_text (out, is_err, msg, strlen (msg));
1086#else /* !CONFIG_WITH_OUTPUT_IN_MEMORY */
1087 if (! out || ! out->syncout)
1088 {
1089 FILE *f = is_err ? stderr : stdout;
1090# ifdef KBUILD_OS_WINDOWS
1091 maybe_con_fwrite(msg, strlen(msg), 1, f);
1092# else
1093 fputs (msg, f);
1094# endif
1095 fflush (f);
1096 }
1097 else
1098 {
1099 int fd = is_err ? out->err : out->out;
1100 int len = strlen (msg);
1101 int r;
1102
1103 EINTRLOOP (r, lseek (fd, 0, SEEK_END));
1104 while (1)
1105 {
1106 EINTRLOOP (r, write (fd, msg, len));
1107 if (r == len || r <= 0)
1108 break;
1109 len -= r;
1110 msg += r;
1111 }
1112 }
1113#endif /* !CONFIG_WITH_OUTPUT_IN_MEMORY */
1114}
1115
1116
1117/* Write a message indicating that we've just entered or
1118 left (according to ENTERING) the current directory. */
1119
1120static int
1121log_working_directory (int entering)
1122{
1123 static char *buf = NULL;
1124 static unsigned int len = 0;
1125 unsigned int need;
1126 const char *fmt;
1127 char *p;
1128
1129 /* Get enough space for the longest possible output. */
1130 need = strlen (program) + INTSTR_LENGTH + 2 + 1;
1131 if (starting_directory)
1132 need += strlen (starting_directory);
1133
1134 /* Use entire sentences to give the translators a fighting chance. */
1135 if (makelevel == 0)
1136 if (starting_directory == 0)
1137 if (entering)
1138 fmt = _("%s: Entering an unknown directory\n");
1139 else
1140 fmt = _("%s: Leaving an unknown directory\n");
1141 else
1142 if (entering)
1143 fmt = _("%s: Entering directory '%s'\n");
1144 else
1145 fmt = _("%s: Leaving directory '%s'\n");
1146 else
1147 if (starting_directory == 0)
1148 if (entering)
1149 fmt = _("%s[%u]: Entering an unknown directory\n");
1150 else
1151 fmt = _("%s[%u]: Leaving an unknown directory\n");
1152 else
1153 if (entering)
1154 fmt = _("%s[%u]: Entering directory '%s'\n");
1155 else
1156 fmt = _("%s[%u]: Leaving directory '%s'\n");
1157
1158 need += strlen (fmt);
1159
1160 if (need > len)
1161 {
1162 buf = xrealloc (buf, need);
1163 len = need;
1164 }
1165
1166 p = buf;
1167 if (print_data_base_flag)
1168 {
1169 *(p++) = '#';
1170 *(p++) = ' ';
1171 }
1172
1173 if (makelevel == 0)
1174 if (starting_directory == 0)
1175 sprintf (p, fmt , program);
1176 else
1177 sprintf (p, fmt, program, starting_directory);
1178 else if (starting_directory == 0)
1179 sprintf (p, fmt, program, makelevel);
1180 else
1181 sprintf (p, fmt, program, makelevel, starting_directory);
1182
1183 _outputs (NULL, 0, buf);
1184
1185 return 1;
1186}
1187
1188/* Set a file descriptor to be in O_APPEND mode.
1189 If it fails, just ignore it. */
1190
1191static void
1192set_append_mode (int fd)
1193{
1194#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
1195 int flags = fcntl (fd, F_GETFL, 0);
1196 if (flags >= 0)
1197 fcntl (fd, F_SETFL, flags | O_APPEND);
1198#endif
1199}
1200
1201
1202
1203#ifndef NO_OUTPUT_SYNC
1204
1205/* Semaphore for use in -j mode with output_sync. */
1206static sync_handle_t sync_handle = -1;
1207
1208#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
1209
1210/* Set up the sync handle. Disables output_sync on error. */
1211static int
1212sync_init (void)
1213{
1214 int combined_output = 0;
1215
1216#ifdef WINDOWS32
1217# ifdef CONFIG_NEW_WIN_CHILDREN
1218 if (STREAM_OK (stdout))
1219 {
1220 if (STREAM_OK (stderr))
1221 {
1222 char mtxname[256];
1223 sync_handle = create_mutex (mtxname, sizeof (mtxname));
1224 if (sync_handle != -1)
1225 {
1226 prepare_mutex_handle_string (mtxname);
1227 return same_stream (stdout, stderr);
1228 }
1229 perror_with_name ("output-sync suppressed: ", "create_mutex");
1230 }
1231 else
1232 perror_with_name ("output-sync suppressed: ", "stderr");
1233 }
1234 else
1235 perror_with_name ("output-sync suppressed: ", "stdout");
1236 output_sync = OUTPUT_SYNC_NONE;
1237
1238# else /* !CONFIG_NEW_WIN_CHILDREN */
1239 if ((!STREAM_OK (stdout) && !STREAM_OK (stderr))
1240 || (sync_handle = create_mutex ()) == -1)
1241 {
1242 perror_with_name ("output-sync suppressed: ", "stderr");
1243 output_sync = 0;
1244 }
1245 else
1246 {
1247 combined_output = same_stream (stdout, stderr);
1248 prepare_mutex_handle_string (sync_handle);
1249 }
1250# endif /* !CONFIG_NEW_WIN_CHILDREN */
1251
1252#else
1253 if (STREAM_OK (stdout))
1254 {
1255 struct stat stbuf_o, stbuf_e;
1256
1257 sync_handle = fileno (stdout);
1258 combined_output = (fstat (fileno (stdout), &stbuf_o) == 0
1259 && fstat (fileno (stderr), &stbuf_e) == 0
1260 && stbuf_o.st_dev == stbuf_e.st_dev
1261 && stbuf_o.st_ino == stbuf_e.st_ino);
1262 }
1263 else if (STREAM_OK (stderr))
1264 sync_handle = fileno (stderr);
1265 else
1266 {
1267 perror_with_name ("output-sync suppressed: ", "stderr");
1268 output_sync = 0;
1269 }
1270#endif
1271
1272 return combined_output;
1273}
1274
1275#ifndef CONFIG_WITH_OUTPUT_IN_MEMORY
1276/* Support routine for output_sync() */
1277static void
1278pump_from_tmp (int from, FILE *to)
1279{
1280# ifdef KMK
1281 char buffer[8192];
1282# else
1283 static char buffer[8192];
1284#endif
1285
1286# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
1287 int prev_mode;
1288
1289 /* "from" is opened by open_tmpfd, which does it in binary mode, so
1290 we need the mode of "to" to match that. */
1291 prev_mode = _setmode (fileno (to), O_BINARY);
1292#endif
1293
1294 if (lseek (from, 0, SEEK_SET) == -1)
1295 perror ("lseek()");
1296
1297 while (1)
1298 {
1299 int len;
1300 EINTRLOOP (len, read (from, buffer, sizeof (buffer)));
1301 if (len < 0)
1302 perror ("read()");
1303 if (len <= 0)
1304 break;
1305#ifdef KMK
1306 if (output_metered < 0)
1307 { /* likely */ }
1308 else
1309 meter_output_block (buffer, len);
1310#endif
1311 if (fwrite (buffer, len, 1, to) < 1)
1312 {
1313 perror ("fwrite()");
1314 break;
1315 }
1316 fflush (to);
1317 }
1318
1319# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
1320 /* Switch "to" back to its original mode, so that log messages by
1321 Make have the same EOL format as without --output-sync. */
1322 _setmode (fileno (to), prev_mode);
1323#endif
1324}
1325#endif /* CONFIG_WITH_OUTPUT_IN_MEMORY */
1326
1327/* Obtain the lock for writing output. */
1328static void *
1329acquire_semaphore (void)
1330{
1331 static struct flock fl;
1332
1333 fl.l_type = F_WRLCK;
1334 fl.l_whence = SEEK_SET;
1335 fl.l_start = 0;
1336 fl.l_len = 1;
1337 if (fcntl (sync_handle, F_SETLKW, &fl) != -1)
1338 return &fl;
1339#ifdef KBUILD_OS_DARWIN /* F_SETLKW isn't supported on pipes */
1340 if (errno != EBADF)
1341#endif
1342 perror ("fcntl()");
1343 return NULL;
1344}
1345
1346/* Release the lock for writing output. */
1347static void
1348release_semaphore (void *sem)
1349{
1350 struct flock *flp = (struct flock *)sem;
1351 flp->l_type = F_UNLCK;
1352 if (fcntl (sync_handle, F_SETLKW, flp) == -1)
1353 perror ("fcntl()");
1354}
1355
1356#ifndef CONFIG_WITH_OUTPUT_IN_MEMORY
1357
1358/* Returns a file descriptor to a temporary file. The file is automatically
1359 closed/deleted on exit. Don't use a FILE* stream. */
1360int
1361output_tmpfd (void)
1362{
1363 int fd = -1;
1364 FILE *tfile = tmpfile ();
1365
1366 if (! tfile)
1367 {
1368#ifdef KMK
1369 if (output_context && output_context->syncout)
1370 output_context->syncout = 0; /* Avoid inifinit recursion. */
1371#endif
1372 pfatal_with_name ("tmpfile");
1373 }
1374
1375 /* Create a duplicate so we can close the stream. */
1376 fd = dup (fileno (tfile));
1377 if (fd < 0)
1378 {
1379#ifdef KMK
1380 if (output_context && output_context->syncout)
1381 output_context->syncout = 0; /* Avoid inifinit recursion. */
1382#endif
1383 pfatal_with_name ("dup");
1384 }
1385
1386 fclose (tfile);
1387
1388 set_append_mode (fd);
1389
1390 return fd;
1391}
1392
1393/* Adds file descriptors to the child structure to support output_sync; one
1394 for stdout and one for stderr as long as they are open. If stdout and
1395 stderr share a device they can share a temp file too.
1396 Will reset output_sync on error. */
1397static void
1398setup_tmpfile (struct output *out)
1399{
1400 /* Is make's stdout going to the same place as stderr? */
1401 static int combined_output = -1;
1402
1403 if (combined_output < 0)
1404 {
1405#ifdef KMK /* prevent infinite recursion if sync_init() calls perror_with_name. */
1406 combined_output = 0;
1407#endif
1408 combined_output = sync_init ();
1409 }
1410
1411 if (STREAM_OK (stdout))
1412 {
1413 int fd = output_tmpfd ();
1414 if (fd < 0)
1415 goto error;
1416 CLOSE_ON_EXEC (fd);
1417 out->out = fd;
1418 }
1419
1420 if (STREAM_OK (stderr))
1421 {
1422 if (out->out != OUTPUT_NONE && combined_output)
1423 out->err = out->out;
1424 else
1425 {
1426 int fd = output_tmpfd ();
1427 if (fd < 0)
1428 goto error;
1429 CLOSE_ON_EXEC (fd);
1430 out->err = fd;
1431 }
1432 }
1433
1434 return;
1435
1436 /* If we failed to create a temp file, disable output sync going forward. */
1437 error:
1438 output_close (out);
1439 output_sync = OUTPUT_SYNC_NONE;
1440}
1441
1442#endif /* !CONFIG_WITH_OUTPUT_IN_MEMORY */
1443
1444/* Synchronize the output of jobs in -j mode to keep the results of
1445 each job together. This is done by holding the results in temp files,
1446 one for stdout and potentially another for stderr, and only releasing
1447 them to "real" stdout/stderr when a semaphore can be obtained. */
1448
1449void
1450output_dump (struct output *out)
1451{
1452#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1453 membuf_dump (out);
1454#else
1455 int outfd_not_empty = FD_NOT_EMPTY (out->out);
1456 int errfd_not_empty = FD_NOT_EMPTY (out->err);
1457
1458 if (outfd_not_empty || errfd_not_empty)
1459 {
1460# ifndef KMK /* this drives me bananas. */
1461 int traced = 0;
1462# endif
1463
1464 /* Try to acquire the semaphore. If it fails, dump the output
1465 unsynchronized; still better than silently discarding it.
1466 We want to keep this lock for as little time as possible. */
1467 void *sem = acquire_semaphore ();
1468
1469# ifndef KMK /* this drives me bananas. */
1470 /* Log the working directory for this dump. */
1471 if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
1472 traced = log_working_directory (1);
1473# endif
1474
1475 if (outfd_not_empty)
1476 pump_from_tmp (out->out, stdout);
1477 if (errfd_not_empty && out->err != out->out)
1478 pump_from_tmp (out->err, stderr);
1479
1480# ifndef KMK /* this drives me bananas. */
1481 if (traced)
1482 log_working_directory (0);
1483# endif
1484
1485 /* Exit the critical section. */
1486 if (sem)
1487 release_semaphore (sem);
1488
1489# ifdef KMK
1490 if (!out->dont_truncate)
1491 { /* likely */ }
1492 else return;
1493# endif
1494 /* Truncate and reset the output, in case we use it again. */
1495 if (out->out != OUTPUT_NONE)
1496 {
1497 int e;
1498 lseek (out->out, 0, SEEK_SET);
1499 EINTRLOOP (e, ftruncate (out->out, 0));
1500 }
1501 if (out->err != OUTPUT_NONE && out->err != out->out)
1502 {
1503 int e;
1504 lseek (out->err, 0, SEEK_SET);
1505 EINTRLOOP (e, ftruncate (out->err, 0));
1506 }
1507 }
1508#endif
1509}
1510
1511# if defined(KMK) && !defined(CONFIG_WITH_OUTPUT_IN_MEMORY)
1512/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
1513void output_reset (struct output *out)
1514{
1515 if (out)
1516 {
1517 if (out->out != OUTPUT_NONE)
1518 {
1519 int e;
1520 lseek (out->out, 0, SEEK_SET);
1521 EINTRLOOP (e, ftruncate (out->out, 0));
1522 }
1523 if (out->err != OUTPUT_NONE && out->err != out->out)
1524 {
1525 int e;
1526 lseek (out->err, 0, SEEK_SET);
1527 EINTRLOOP (e, ftruncate (out->err, 0));
1528 }
1529 }
1530}
1531# endif
1532#endif /* NO_OUTPUT_SYNC */
1533
1534
1535
1536/* Provide support for temporary files. */
1537
1538#ifndef HAVE_STDLIB_H
1539# ifdef HAVE_MKSTEMP
1540int mkstemp (char *template);
1541# else
1542char *mktemp (char *template);
1543# endif
1544#endif
1545
1546FILE *
1547output_tmpfile (char **name, const char *template)
1548{
1549#ifdef HAVE_FDOPEN
1550 int fd;
1551#endif
1552
1553#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
1554# define TEMPLATE_LEN strlen (template)
1555#else
1556# define TEMPLATE_LEN L_tmpnam
1557#endif
1558 *name = xmalloc (TEMPLATE_LEN + 1);
1559 strcpy (*name, template);
1560
1561#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
1562 /* It's safest to use mkstemp(), if we can. */
1563 fd = mkstemp (*name);
1564 if (fd == -1)
1565 return 0;
1566 return fdopen (fd, "w");
1567#else
1568# ifdef HAVE_MKTEMP
1569 (void) mktemp (*name);
1570# else
1571 (void) tmpnam (*name);
1572# endif
1573
1574# ifdef HAVE_FDOPEN
1575 /* Can't use mkstemp(), but guard against a race condition. */
1576 EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
1577 if (fd == -1)
1578 return 0;
1579 return fdopen (fd, "w");
1580# else
1581 /* Not secure, but what can we do? */
1582 return fopen (*name, "w");
1583# endif
1584#endif
1585}
1586
1587
1588
1589/* This code is stolen from gnulib.
1590 If/when we abandon the requirement to work with K&R compilers, we can
1591 remove this (and perhaps other parts of GNU make!) and migrate to using
1592 gnulib directly.
1593
1594 This is called only through atexit(), which means die() has already been
1595 invoked. So, call exit() here directly. Apparently that works...?
1596*/
1597
1598/* Close standard output, exiting with status 'exit_failure' on failure.
1599 If a program writes *anything* to stdout, that program should close
1600 stdout and make sure that it succeeds before exiting. Otherwise,
1601 suppose that you go to the extreme of checking the return status
1602 of every function that does an explicit write to stdout. The last
1603 printf can succeed in writing to the internal stream buffer, and yet
1604 the fclose(stdout) could still fail (due e.g., to a disk full error)
1605 when it tries to write out that buffered data. Thus, you would be
1606 left with an incomplete output file and the offending program would
1607 exit successfully. Even calling fflush is not always sufficient,
1608 since some file systems (NFS and CODA) buffer written/flushed data
1609 until an actual close call.
1610
1611 Besides, it's wasteful to check the return value from every call
1612 that writes to stdout -- just let the internal stream state record
1613 the failure. That's what the ferror test is checking below.
1614
1615 It's important to detect such failures and exit nonzero because many
1616 tools (most notably 'make' and other build-management systems) depend
1617 on being able to detect failure in other tools via their exit status. */
1618
1619static void
1620close_stdout (void)
1621{
1622 int prev_fail = ferror (stdout);
1623#ifdef DEBUG_STDOUT_CLOSE_ISSUE
1624 if (prev_fail)
1625 my_stdout_error ("close_stdout", "error pending on entry!");
1626 errno = 0; SetLastError (0);
1627#endif
1628 int fclose_fail = fclose (stdout);
1629
1630 if (prev_fail || fclose_fail)
1631 {
1632#ifdef DEBUG_STDOUT_CLOSE_ISSUE
1633 if (fclose_fail)
1634 my_stdout_error ("close_stdout", "fclose failed!");
1635#endif
1636 if (fclose_fail)
1637 perror_with_name (_("write error: stdout"), "");
1638 else
1639 O (error, NILF, _("write error: stdout"));
1640 exit (MAKE_TROUBLE);
1641 }
1642#if defined(KBUILD_OS_WINDOWS) && defined(KMK)
1643 win_pipe_hack_terminate ();
1644#endif
1645}
1646
1647
1648
1649void
1650output_init (struct output *out)
1651{
1652#if defined(KBUILD_OS_WINDOWS) && defined(KMK)
1653 /* Apply workaround for asynchronous pipes on windows on first call. */
1654 static int s_not_first_call = 0;
1655 if (!s_not_first_call)
1656 {
1657 s_not_first_call = 1;
1658 win_pipe_hack_init ();
1659 }
1660#endif
1661
1662#ifdef DEBUG_STDOUT_CLOSE_ISSUE
1663 if (STREAM_OK (stdout) && ferror (stdout))
1664 my_stdout_error (out ? "output_init(out)" : "output_init(NULL)", "error pending entry!");
1665#endif
1666
1667 if (out)
1668 {
1669#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1670 out->out.head_seg = NULL;
1671 out->out.tail_seg = NULL;
1672 out->out.head_run = NULL;
1673 out->out.tail_run = NULL;
1674 out->err.head_seg = NULL;
1675 out->err.tail_seg = NULL;
1676 out->err.head_run = NULL;
1677 out->err.tail_run = NULL;
1678 out->err.total = 0;
1679 out->out.total = 0;
1680 out->seqno = 0;
1681#else
1682 out->out = out->err = OUTPUT_NONE;
1683#endif
1684 out->syncout = !!output_sync;
1685#ifdef KMK
1686 out->dont_truncate = 0;
1687#endif
1688 return;
1689 }
1690
1691 /* Configure this instance of make. Be sure stdout is line-buffered. */
1692
1693#ifdef HAVE_SETVBUF
1694# ifdef SETVBUF_REVERSED
1695 setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
1696# else /* setvbuf not reversed. */
1697 /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
1698 setvbuf (stdout, 0, _IOLBF, BUFSIZ);
1699# endif /* setvbuf reversed. */
1700#elif HAVE_SETLINEBUF
1701 setlinebuf (stdout);
1702#endif /* setlinebuf missing. */
1703
1704 /* Force stdout/stderr into append mode. This ensures parallel jobs won't
1705 lose output due to overlapping writes. */
1706 set_append_mode (fileno (stdout));
1707 set_append_mode (fileno (stderr));
1708
1709#ifdef DEBUG_STDOUT_CLOSE_ISSUE
1710 if (ferror (stdout))
1711 my_stdout_error ("output_init", "error pending on exit!");
1712# ifdef KBUILD_OS_WINDOWS
1713 {
1714 HANDLE const hStdOut = (HANDLE)_get_osfhandle(_fileno(stdout));
1715 DWORD const dwType = GetFileType(hStdOut);
1716 birdResolveImportsWorker();
1717 if ((dwType & ~FILE_TYPE_REMOTE) == FILE_TYPE_PIPE)
1718 {
1719 my_output_pipe_info (hStdOut, "output_init");
1720# if 0
1721 DWORD cbOutBuf = 0;
1722 DWORD cbInBuf = 0;
1723 BOOL const fRc2 = GetNamedPipeInfo(hStdOut, NULL, &cbOutBuf, &cbInBuf, NULL);
1724 if (cbInBuf != 0x1000)
1725 {
1726 DWORD dwMode = 0;
1727 if (GetNamedPipeHandleStateW(hStdOut, &dwMode, NULL, NULL, NULL, NULL, 0))
1728 {
1729 dwMode &= ~PIPE_WAIT;
1730 dwMode |= PIPE_NOWAIT;
1731 if (!SetNamedPipeHandleState(hStdOut, &dwMode, NULL, NULL))
1732 fprintf(stderr, "SetNamedPipeHandleState failed: %u\n", GetLastError());
1733 else
1734 {
1735 GetNamedPipeHandleStateW(hStdOut, &dwMode, NULL, NULL, NULL, NULL, 0);
1736 fprintf(stderr, "SetNamedPipeHandleState succeeded: %#x\n", dwMode);
1737 }
1738 }
1739 }
1740# endif
1741# endif
1742 }
1743 }
1744#endif
1745#ifdef HAVE_ATEXIT
1746 if (STREAM_OK (stdout))
1747 atexit (close_stdout);
1748#endif
1749}
1750
1751void
1752output_close (struct output *out)
1753{
1754 if (! out)
1755 {
1756 if (stdio_traced)
1757 log_working_directory (0);
1758 return;
1759 }
1760
1761#ifndef NO_OUTPUT_SYNC
1762 output_dump (out);
1763#endif
1764
1765#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1766 assert (out->out.total == 0);
1767 assert (out->out.head_seg == NULL);
1768 assert (out->err.total == 0);
1769 assert (out->err.head_seg == NULL);
1770#else
1771 if (out->out >= 0)
1772 close (out->out);
1773 if (out->err >= 0 && out->err != out->out)
1774 close (out->err);
1775#endif
1776
1777 output_init (out);
1778}
1779
1780/* We're about to generate output: be sure it's set up. */
1781void
1782output_start (void)
1783{
1784#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1785 /* If we're syncing output make sure the sempahore (win) is set up. */
1786 if (output_context && output_context->syncout)
1787 if (combined_output < 0)
1788 {
1789 combined_output = 0;
1790 combined_output = sync_init ();
1791 }
1792#else
1793#ifndef NO_OUTPUT_SYNC
1794 /* If we're syncing output make sure the temporary file is set up. */
1795 if (output_context && output_context->syncout)
1796 if (! OUTPUT_ISSET(output_context))
1797 setup_tmpfile (output_context);
1798#endif
1799#endif
1800
1801#ifndef KMK
1802 /* If we're not syncing this output per-line or per-target, make sure we emit
1803 the "Entering..." message where appropriate. */
1804 if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
1805#else
1806 /* Indiscriminately output "Entering..." and "Leaving..." message for each
1807 command line or target is plain annoying! And when there is no recursion
1808 it's actually inappropriate. Haven't got a simple way of detecting that,
1809 so back to the old behavior for now. [bird] */
1810#endif
1811 if (! stdio_traced && print_directory_flag)
1812 stdio_traced = log_working_directory (1);
1813}
1814
1815void
1816outputs (int is_err, const char *msg)
1817{
1818 if (! msg || *msg == '\0')
1819 return;
1820
1821 output_start ();
1822
1823 _outputs (output_context, is_err, msg);
1824}
1825
1826
1827
1828static struct fmtstring
1829 {
1830 char *buffer;
1831 size_t size;
1832 } fmtbuf = { NULL, 0 };
1833
1834static char *
1835get_buffer (size_t need)
1836{
1837 /* Make sure we have room. NEED includes space for \0. */
1838 if (need > fmtbuf.size)
1839 {
1840 fmtbuf.size += need * 2;
1841 fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
1842 }
1843
1844 fmtbuf.buffer[need-1] = '\0';
1845
1846 return fmtbuf.buffer;
1847}
1848
1849/* Print a message on stdout. */
1850
1851void
1852message (int prefix, size_t len, const char *fmt, ...)
1853{
1854 va_list args;
1855 char *p;
1856
1857 len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
1858 p = get_buffer (len);
1859
1860 if (prefix)
1861 {
1862 if (makelevel == 0)
1863 sprintf (p, "%s: ", program);
1864 else
1865 sprintf (p, "%s[%u]: ", program, makelevel);
1866 p += strlen (p);
1867 }
1868
1869 va_start (args, fmt);
1870 vsprintf (p, fmt, args);
1871 va_end (args);
1872
1873 strcat (p, "\n");
1874
1875 assert (fmtbuf.buffer[len-1] == '\0');
1876 outputs (0, fmtbuf.buffer);
1877}
1878
1879/* Print an error message. */
1880
1881void
1882error (const floc *flocp, size_t len, const char *fmt, ...)
1883{
1884 va_list args;
1885 char *p;
1886
1887 len += (strlen (fmt) + strlen (program)
1888 + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
1889 + INTSTR_LENGTH + 4 + 1 + 1);
1890 p = get_buffer (len);
1891
1892 if (flocp && flocp->filenm)
1893 sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
1894 else if (makelevel == 0)
1895 sprintf (p, "%s: ", program);
1896 else
1897 sprintf (p, "%s[%u]: ", program, makelevel);
1898 p += strlen (p);
1899
1900 va_start (args, fmt);
1901 vsprintf (p, fmt, args);
1902 va_end (args);
1903
1904 strcat (p, "\n");
1905
1906 assert (fmtbuf.buffer[len-1] == '\0');
1907 outputs (1, fmtbuf.buffer);
1908}
1909
1910/* Print an error message and exit. */
1911
1912void
1913fatal (const floc *flocp, size_t len, const char *fmt, ...)
1914{
1915 va_list args;
1916 const char *stop = _(". Stop.\n");
1917 char *p;
1918
1919 len += (strlen (fmt) + strlen (program)
1920 + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
1921 + INTSTR_LENGTH + 8 + strlen (stop) + 1);
1922 p = get_buffer (len);
1923
1924 if (flocp && flocp->filenm)
1925 sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
1926 else if (makelevel == 0)
1927 sprintf (p, "%s: *** ", program);
1928 else
1929 sprintf (p, "%s[%u]: *** ", program, makelevel);
1930 p += strlen (p);
1931
1932 va_start (args, fmt);
1933 vsprintf (p, fmt, args);
1934 va_end (args);
1935
1936 strcat (p, stop);
1937
1938 assert (fmtbuf.buffer[len-1] == '\0');
1939 outputs (1, fmtbuf.buffer);
1940
1941 die (MAKE_FAILURE);
1942}
1943
1944/* Print an error message from errno. */
1945
1946void
1947perror_with_name (const char *str, const char *name)
1948{
1949 const char *err = strerror (errno);
1950 OSSS (error, NILF, _("%s%s: %s"), str, name, err);
1951}
1952
1953/* Print an error message from errno and exit. */
1954
1955void
1956pfatal_with_name (const char *name)
1957{
1958 const char *err = strerror (errno);
1959 OSS (fatal, NILF, _("%s: %s"), name, err);
1960
1961 /* NOTREACHED */
1962}
Note: See TracBrowser for help on using the repository browser.