source: trunk/src/kmk/output.c@ 3662

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

kmk/output.c: Debugging code for the mysterious 'kmk: write error: stdout' problem...

  • Property svn:eol-style set to native
File size: 38.1 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#include "makeint.h"
18#include "job.h"
19
20/* GNU make no longer supports pre-ANSI89 environments. */
21
22#include <assert.h>
23#include <stdio.h>
24#include <stdarg.h>
25
26#ifdef HAVE_UNISTD_H
27# include <unistd.h>
28#endif
29
30#ifdef HAVE_FCNTL_H
31# include <fcntl.h>
32#else
33# include <sys/file.h>
34#endif
35
36#ifdef WINDOWS32
37# include <windows.h>
38# include <io.h>
39# ifndef CONFIG_NEW_WIN_CHILDREN
40# include "sub_proc.h"
41# else
42# include "w32/winchildren.h"
43# endif
44#endif /* WINDOWS32 */
45#ifdef KBUILD_OS_WINDOWS
46# include "console.h"
47#endif
48
49struct output *output_context = NULL;
50unsigned int stdio_traced = 0;
51
52#define OUTPUT_NONE (-1)
53
54#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
55
56#ifdef HAVE_FCNTL_H
57# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
58#else
59# define STREAM_OK(_s) 1
60#endif
61
62#if defined(KMK) && defined(KBUILD_OS_WINDOWS) && 1
63/* fflush wrapper w/ error checking + reporting for stdout.
64 This is to debug the mysterious 'kmk: write error: stdout' errors. */
65int g_fStdOutError = 0;
66
67static int my_fflush (FILE *pFile)
68{
69 if (pFile == stdout && !g_fStdOutError)
70 {
71 if (!ferror (pFile))
72 {
73 int rcRet = fflush (pFile);
74 g_fStdOutError = ferror(g_fStdOutError);
75 if (rcRet != EOF && !g_fStdOutError)
76 { /* likely */ }
77 else if (rcRet == EOF)
78 fprintf (stderr, "kmk: fflush(stdout): flush failed! errno=%d\n", errno);
79 else
80 fprintf (stderr, "kmk: fflush(stdout): error pending after successful flush! errno=%d\n", errno);
81
82 return rcRet;
83 }
84 else
85 {
86 fprintf (stderr, "kmk: fflush(stdout): error pending on entry! errno=%d\n", errno);
87 g_fStdOutError = 1;
88 }
89
90 }
91 return fflush (pFile);
92}
93
94# undef fflush
95# undef fflush(a_pFile) my_fflush(a_pFile)
96
97#endif
98
99
100#if defined(KMK) && !defined(NO_OUTPUT_SYNC)
101/* Non-negative if we're counting output lines.
102
103 This is used by die_with_job_output to decide whether the initial build
104 error needs to be repeated because there was too much output from parallel
105 jobs between it and the actual make termination. */
106int output_metered = -1;
107
108static void meter_output_block (char const *buffer, size_t len)
109{
110 while (len > 0)
111 {
112 char *nl = (char *)memchr (buffer, '\n', len);
113 size_t linelen;
114 if (nl)
115 {
116 linelen = nl - buffer + 1;
117 output_metered++;
118 }
119 else
120 linelen = len;
121 output_metered += linelen / 132;
122
123 /* advance */
124 buffer += linelen;
125 len -= linelen;
126 }
127}
128#endif
129
130
131#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
132# define MEMBUF_MIN_SEG_SIZE 4096
133# define MEMBUF_MAX_SEG_SIZE (512*1024)
134# define MEMBUF_MAX_MOVE_LEN ( MEMBUF_MIN_SEG_SIZE \
135 - offsetof (struct output_segment, runs) \
136 - sizeof (struct output_run))
137# define MEMBUF_MAX_TOTAL ( sizeof (void *) <= 4 \
138 ? (size_t)512*1024 : (size_t)16*1024*1024 )
139
140static void *acquire_semaphore (void);
141static void release_semaphore (void *);
142static int log_working_directory (int);
143
144/* Is make's stdout going to the same place as stderr?
145 Also, did we already sync_init (== -1)? */
146static int combined_output = -1;
147
148/* Helper for membuf_reset and output_reset */
149static membuf_reset (struct output *out)
150{
151 struct output_segment *seg;
152 while ((seg = out->out.head_seg))
153 {
154 out->out.head_seg = seg->next;
155 free (seg);
156 }
157 out->out.tail_seg = NULL;
158 out->out.tail_run = NULL;
159 out->out.head_run = NULL;
160 out->out.left = 0;
161 out->out.total = 0;
162
163 while ((seg = out->err.head_seg))
164 {
165 out->err.head_seg = seg->next;
166 free (seg);
167 }
168 out->err.tail_seg = NULL;
169 out->err.tail_run = NULL;
170 out->err.head_run = NULL;
171 out->err.left = 0;
172 out->err.total = 0;
173
174 out->seqno = 0;
175}
176
177/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
178void output_reset (struct output *out)
179{
180 if (out && (out->out.total || out->err.total))
181 membuf_reset (out);
182}
183
184/* Internal worker for output_dump and membuf_dump_most. */
185static void membuf_dump (struct output *out)
186{
187 if (out->out.total || out->err.total)
188 {
189 int traced = 0;
190 struct output_run *err_run;
191 struct output_run *out_run;
192 FILE *prevdst;
193
194 /* Try to acquire the semaphore. If it fails, dump the output
195 unsynchronized; still better than silently discarding it.
196 We want to keep this lock for as little time as possible. */
197 void *sem = acquire_semaphore ();
198# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
199 int prev_mode_out = _setmode (fileno (stdout), _O_BINARY);
200 int prev_mode_err = _setmode (fileno (stderr), _O_BINARY);
201# endif
202
203# ifndef KMK /* this drives me bananas. */
204 /* Log the working directory for this dump. */
205 if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
206 traced = log_working_directory (1);
207# endif
208
209 /* Work the out and err sequences in parallel. */
210 out_run = out->out.head_run;
211 err_run = out->err.head_run;
212 prevdst = NULL;
213 while (err_run || out_run)
214 {
215 FILE *dst;
216 const void *src;
217 size_t len;
218 if (out_run && (!err_run || out_run->seqno <= err_run->seqno))
219 {
220 src = out_run + 1;
221 len = out_run->len;
222 dst = stdout;
223 out_run = out_run->next;
224 }
225 else
226 {
227 src = err_run + 1;
228 len = err_run->len;
229 dst = stderr;
230 err_run = err_run->next;
231 }
232 if (dst != prevdst)
233 fflush (prevdst);
234 prevdst = dst;
235#ifdef KMK
236 if (output_metered < 0)
237 { /* likely */ }
238 else
239 meter_output_block (src, len);
240#endif
241# if 0 /* for debugging */
242 while (len > 0)
243 {
244 const char *nl = (const char *)memchr (src, '\n', len);
245 size_t line_len = nl ? nl - (const char *)src + 1 : len;
246 char *tmp = (char *)xmalloc (1 + line_len + 1 + 1);
247 tmp[0] = '{';
248 memcpy (&tmp[1], src, line_len);
249 tmp[1 + line_len] = '}';
250# ifdef KBUILD_OS_WINDOWS
251 maybe_con_fwrite (tmp, 1 + line_len + 1, 1, dst);
252# else
253 fwrite (tmp, 1 + line_len + 1, 1, dst);
254# endif
255 free (tmp);
256 src = (const char *)src + line_len;
257 len -= line_len;
258 }
259#else
260# ifdef KBUILD_OS_WINDOWS
261 maybe_con_fwrite (src, len, 1, dst);
262# else
263 fwrite (src, len, 1, dst);
264# endif
265# endif
266 }
267 if (prevdst)
268 fflush (prevdst);
269
270# ifndef KMK /* this drives me bananas. */
271 if (traced)
272 log_working_directory (0);
273# endif
274
275 /* Exit the critical section. */
276# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
277 _setmode (fileno (stdout), prev_mode_out);
278 _setmode (fileno (stderr), prev_mode_err);
279# endif
280 if (sem)
281 release_semaphore (sem);
282
283# ifdef KMK
284 if (!out->dont_truncate)
285 { /* likely */ }
286 else return;
287# endif
288
289 /* Free the segments and reset the state. */
290 membuf_reset (out);
291 }
292 else
293 assert (out->out.head_seg == NULL && out->err.head_seg == NULL);
294}
295
296/* Writes up to LEN bytes to the given segment.
297 Returns how much was actually written. */
298static size_t
299membuf_write_segment (struct output_membuf *membuf, struct output_segment *seg,
300 const char *src, size_t len, unsigned int *pseqno)
301{
302 size_t written = 0;
303 if (seg && membuf->left > 0)
304 {
305 struct output_run *run = membuf->tail_run;
306 char *dst = (char *)(run + 1) + run->len;
307 assert ((uintptr_t)run - (uintptr_t)seg < seg->size);
308
309 /* If the sequence number didn't change, then we can append
310 to the current run without further considerations. */
311 if (run->seqno == *pseqno)
312 written = len;
313 /* If the current run does not end with a newline, don't start a new
314 run till we encounter one. */
315 else if (dst[-1] != '\n')
316 {
317 char const *srcnl = (const char *)memchr (src, '\n', len);
318 written = srcnl ? srcnl - src + 1 : len;
319 }
320 /* Try create a new empty run and append to it. */
321 else
322 {
323 size_t const offnextrun = ( (uintptr_t)dst - (uintptr_t)(seg)
324 + sizeof(void *) - 1)
325 & ~(sizeof(void *) - 1);
326 if (offnextrun > seg->size - sizeof (struct output_run) * 2)
327 return 0; /* need new segment */
328
329 run = run->next = (struct output_run *)((char *)seg + offnextrun);
330 run->next = NULL;
331 run->seqno = ++(*pseqno);
332 run->len = 0;
333 membuf->tail_run = run;
334 membuf->left = seg->size - (offnextrun + sizeof (*run));
335 dst = (char *)(run + 1);
336 written = len;
337 }
338
339 /* Append to the current run. */
340 if (written > membuf->left)
341 written = membuf->left;
342 memcpy (dst, src, written);
343 run->len += written;
344 membuf->left -= written;
345 }
346 return written;
347}
348
349/* Helper for membuf_write_new_segment and membuf_dump_most that figures out
350 now much data needs to be moved from the previous run in order to make it
351 end with a newline. */
352static size_t membuf_calc_move_len (struct output_run *tail_run)
353{
354 size_t to_move = 0;
355 if (tail_run)
356 {
357 const char *data = (const char *)(tail_run + 1);
358 size_t off = tail_run->len;
359 while (off > 0 && data[off - 1] != '\n')
360 off--;
361 to_move = tail_run->len - off;
362 if (to_move >= MEMBUF_MAX_MOVE_LEN)
363 to_move = 0;
364 }
365 return to_move;
366}
367
368/* Allocates a new segment and writes to it.
369 This will take care to make sure the previous run terminates with
370 a newline so that we pass whole lines to fwrite when dumping. */
371static size_t
372membuf_write_new_segment (struct output_membuf *membuf, const char *src,
373 size_t len, unsigned int *pseqno)
374{
375 struct output_run *prev_run = membuf->tail_run;
376 struct output_segment *prev_seg = membuf->tail_seg;
377 size_t const to_move = membuf_calc_move_len (prev_run);
378 struct output_segment *new_seg;
379 size_t written;
380 char *dst;
381
382 /* Figure the the segment size. We start with MEMBUF_MIN_SEG_SIZE and double
383 it each time till we reach MEMBUF_MAX_SEG_SIZE. */
384 size_t const offset_runs = offsetof (struct output_segment, runs);
385 size_t segsize = !prev_seg ? MEMBUF_MIN_SEG_SIZE
386 : prev_seg->size >= MEMBUF_MAX_SEG_SIZE ? MEMBUF_MAX_SEG_SIZE
387 : prev_seg->size * 2;
388 while ( segsize < to_move + len + offset_runs + sizeof (struct output_run) * 2
389 && segsize < MEMBUF_MAX_SEG_SIZE)
390 segsize *= 2;
391
392 /* Allocate the segment and link it and the first run. */
393 new_seg = (struct output_segment *)xmalloc (segsize);
394 new_seg->size = segsize;
395 new_seg->next = NULL;
396 new_seg->runs[0].next = NULL;
397 if (!prev_seg)
398 {
399 membuf->head_seg = new_seg;
400 membuf->head_run = &new_seg->runs[0];
401 }
402 else
403 {
404 prev_seg->next = new_seg;
405 prev_run->next = &new_seg->runs[0];
406 }
407 membuf->tail_seg = new_seg;
408 membuf->tail_run = &new_seg->runs[0];
409 membuf->total += segsize;
410 membuf->left = segsize - sizeof (struct output_run) - offset_runs;
411
412 /* Initialize and write data to the first run. */
413 dst = (char *)&new_seg->runs[0]; /* Try bypass gcc array size cleverness. */
414 dst += sizeof (struct output_run);
415 assert (MEMBUF_MAX_MOVE_LEN < MEMBUF_MIN_SEG_SIZE);
416 if (to_move > 0)
417 {
418 /* Move to_move bytes from the previous run in hope that we'll get a
419 newline to soon. Afterwards call membuf_segment_write to work SRC. */
420 assert (prev_run != NULL);
421 assert (membuf->left >= to_move);
422 prev_run->len -= to_move;
423 new_seg->runs[0].len = to_move;
424 new_seg->runs[0].seqno = prev_run->seqno;
425 memcpy (dst, (const char *)(prev_run + 1) + prev_run->len, to_move);
426 membuf->left -= to_move;
427
428 written = membuf_write_segment (membuf, new_seg, src, len, pseqno);
429 }
430 else
431 {
432 /* Create a run with up to LEN from SRC. */
433 written = len;
434 if (written > membuf->left)
435 written = membuf->left;
436 new_seg->runs[0].len = written;
437 new_seg->runs[0].seqno = ++(*pseqno);
438 memcpy (dst, src, written);
439 membuf->left -= written;
440 }
441 return written;
442}
443
444/* Worker for output_write that will dump most of the output when we hit
445 MEMBUF_MAX_TOTAL on either of the two membuf structures, then free all the
446 output segments. Incomplete lines will be held over to the next buffers
447 and copied into new segments. */
448static void
449membuf_dump_most (struct output *out)
450{
451 size_t out_to_move = membuf_calc_move_len (out->out.tail_run);
452 size_t err_to_move = membuf_calc_move_len (out->err.tail_run);
453 if (!out_to_move && !err_to_move)
454 membuf_dump (out);
455 else
456 {
457 /* Allocate a stack buffer for holding incomplete lines. This should be
458 fine since we're only talking about max 2 * MEMBUF_MAX_MOVE_LEN.
459 The -1 on the sequence numbers, ise because membuf_write_new_segment
460 will increment them before use. */
461 unsigned int out_seqno = out_to_move ? out->out.tail_run->seqno - 1 : 0;
462 unsigned int err_seqno = err_to_move ? out->err.tail_run->seqno - 1 : 0;
463 char *tmp = alloca (out_to_move + err_to_move);
464 if (out_to_move)
465 {
466 out->out.tail_run->len -= out_to_move;
467 memcpy (tmp,
468 (char *)(out->out.tail_run + 1) + out->out.tail_run->len,
469 out_to_move);
470 }
471 if (err_to_move)
472 {
473 out->err.tail_run->len -= err_to_move;
474 memcpy (tmp + out_to_move,
475 (char *)(out->err.tail_run + 1) + out->err.tail_run->len,
476 err_to_move);
477 }
478
479 membuf_dump (out);
480
481 if (out_to_move)
482 {
483 size_t written = membuf_write_new_segment (&out->out, tmp,
484 out_to_move, &out_seqno);
485 assert (written == out_to_move); (void)written;
486 }
487 if (err_to_move)
488 {
489 size_t written = membuf_write_new_segment (&out->err,
490 tmp + out_to_move,
491 err_to_move, &err_seqno);
492 assert (written == err_to_move); (void)written;
493 }
494 }
495}
496
497
498
499/* write/fwrite like function, binary mode. */
500ssize_t
501output_write_bin (struct output *out, int is_err, const char *src, size_t len)
502{
503 size_t ret = len;
504 if (!out || !out->syncout)
505 {
506 FILE *f = is_err ? stderr : stdout;
507# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
508 /* On DOS platforms we need to disable \n -> \r\n converts that is common on
509 standard output/error. Also optimize for console output. */
510 int saved_errno;
511 int fd = fileno (f);
512 int prev_mode = _setmode (fd, _O_BINARY);
513 maybe_con_fwrite (src, len, 1, f);
514 if (fflush (f) == EOF)
515 ret = -1;
516 saved_errno = errno;
517 _setmode (fd, prev_mode);
518 errno = saved_errno;
519# else
520 fwrite (src, len, 1, f);
521 if (fflush (f) == EOF)
522 ret = -1;
523# endif
524 }
525 else
526 {
527 struct output_membuf *membuf = is_err ? &out->err : &out->out;
528 while (len > 0)
529 {
530 size_t runlen = membuf_write_segment (membuf, membuf->tail_seg, src, len, &out->seqno);
531 if (!runlen)
532 {
533 if (membuf->total < MEMBUF_MAX_TOTAL)
534 runlen = membuf_write_new_segment (membuf, src, len, &out->seqno);
535 else
536 membuf_dump_most (out);
537 }
538 /* advance */
539 len -= runlen;
540 src += runlen;
541 }
542 }
543 return ret;
544}
545
546#endif /* CONFIG_WITH_OUTPUT_IN_MEMORY */
547
548/* write/fwrite like function, text mode. */
549ssize_t
550output_write_text (struct output *out, int is_err, const char *src, size_t len)
551{
552#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
553# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
554 ssize_t ret = len;
555 if (!out || !out->syncout)
556 {
557 /* ASSUME fwrite does the desired conversion. */
558 FILE *f = is_err ? stderr : stdout;
559# ifdef KBUILD_OS_WINDOWS
560 if (maybe_con_fwrite (src, len, 1, f) < 0)
561 ret = -1;
562# else
563 fwrite (src, len, 1, f);
564# endif
565 if (fflush (f) == EOF)
566 ret = -1;
567 }
568 else
569 {
570 /* Work the buffer line by line, replacing each \n with \r\n. */
571 while (len > 0)
572 {
573 const char *nl = memchr ( src, '\n', len);
574 size_t line_len = nl ? nl - src : len;
575 output_write_bin (out, is_err, src, line_len);
576 if (!nl)
577 break;
578 output_write_bin (out, is_err, "\r\n", 2);
579 len -= line_len + 1;
580 src += line_len + 1;
581 }
582 }
583 return ret;
584# else
585 return output_write_bin (out, is_err, src, len);
586# endif
587#else
588 ssize_t ret = len;
589 if (! out || ! out->syncout)
590 {
591 FILE *f = is_err ? stderr : stdout;
592# ifdef KBUILD_OS_WINDOWS
593 maybe_con_fwrite(src, len, 1, f);
594# else
595 fwrite (src, len, 1, f);
596# endif
597 fflush (f);
598 }
599 else
600 {
601 int fd = is_err ? out->err : out->out;
602 int r;
603
604 EINTRLOOP (r, lseek (fd, 0, SEEK_END));
605 while (1)
606 {
607 EINTRLOOP (r, write (fd, src, len));
608 if ((size_t)r == len || r <= 0)
609 break;
610 len -= r;
611 src += r;
612 }
613 }
614 return ret;
615#endif
616}
617
618
619
620/* Write a string to the current STDOUT or STDERR. */
621static void
622_outputs (struct output *out, int is_err, const char *msg)
623{
624#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
625 output_write_text (out, is_err, msg, strlen (msg));
626#else /* !CONFIG_WITH_OUTPUT_IN_MEMORY */
627 if (! out || ! out->syncout)
628 {
629 FILE *f = is_err ? stderr : stdout;
630# ifdef KBUILD_OS_WINDOWS
631 maybe_con_fwrite(msg, strlen(msg), 1, f);
632# else
633 fputs (msg, f);
634# endif
635 fflush (f);
636 }
637 else
638 {
639 int fd = is_err ? out->err : out->out;
640 int len = strlen (msg);
641 int r;
642
643 EINTRLOOP (r, lseek (fd, 0, SEEK_END));
644 while (1)
645 {
646 EINTRLOOP (r, write (fd, msg, len));
647 if (r == len || r <= 0)
648 break;
649 len -= r;
650 msg += r;
651 }
652 }
653#endif /* !CONFIG_WITH_OUTPUT_IN_MEMORY */
654}
655
656
657/* Write a message indicating that we've just entered or
658 left (according to ENTERING) the current directory. */
659
660static int
661log_working_directory (int entering)
662{
663 static char *buf = NULL;
664 static unsigned int len = 0;
665 unsigned int need;
666 const char *fmt;
667 char *p;
668
669 /* Get enough space for the longest possible output. */
670 need = strlen (program) + INTSTR_LENGTH + 2 + 1;
671 if (starting_directory)
672 need += strlen (starting_directory);
673
674 /* Use entire sentences to give the translators a fighting chance. */
675 if (makelevel == 0)
676 if (starting_directory == 0)
677 if (entering)
678 fmt = _("%s: Entering an unknown directory\n");
679 else
680 fmt = _("%s: Leaving an unknown directory\n");
681 else
682 if (entering)
683 fmt = _("%s: Entering directory '%s'\n");
684 else
685 fmt = _("%s: Leaving directory '%s'\n");
686 else
687 if (starting_directory == 0)
688 if (entering)
689 fmt = _("%s[%u]: Entering an unknown directory\n");
690 else
691 fmt = _("%s[%u]: Leaving an unknown directory\n");
692 else
693 if (entering)
694 fmt = _("%s[%u]: Entering directory '%s'\n");
695 else
696 fmt = _("%s[%u]: Leaving directory '%s'\n");
697
698 need += strlen (fmt);
699
700 if (need > len)
701 {
702 buf = xrealloc (buf, need);
703 len = need;
704 }
705
706 p = buf;
707 if (print_data_base_flag)
708 {
709 *(p++) = '#';
710 *(p++) = ' ';
711 }
712
713 if (makelevel == 0)
714 if (starting_directory == 0)
715 sprintf (p, fmt , program);
716 else
717 sprintf (p, fmt, program, starting_directory);
718 else if (starting_directory == 0)
719 sprintf (p, fmt, program, makelevel);
720 else
721 sprintf (p, fmt, program, makelevel, starting_directory);
722
723 _outputs (NULL, 0, buf);
724
725 return 1;
726}
727
728/* Set a file descriptor to be in O_APPEND mode.
729 If it fails, just ignore it. */
730
731static void
732set_append_mode (int fd)
733{
734#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
735 int flags = fcntl (fd, F_GETFL, 0);
736 if (flags >= 0)
737 fcntl (fd, F_SETFL, flags | O_APPEND);
738#endif
739}
740
741
742
743#ifndef NO_OUTPUT_SYNC
744
745/* Semaphore for use in -j mode with output_sync. */
746static sync_handle_t sync_handle = -1;
747
748#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
749
750/* Set up the sync handle. Disables output_sync on error. */
751static int
752sync_init (void)
753{
754 int combined_output = 0;
755
756#ifdef WINDOWS32
757# ifdef CONFIG_NEW_WIN_CHILDREN
758 if (STREAM_OK (stdout))
759 {
760 if (STREAM_OK (stderr))
761 {
762 char mtxname[256];
763 sync_handle = create_mutex (mtxname, sizeof (mtxname));
764 if (sync_handle != -1)
765 {
766 prepare_mutex_handle_string (mtxname);
767 return same_stream (stdout, stderr);
768 }
769 perror_with_name ("output-sync suppressed: ", "create_mutex");
770 }
771 else
772 perror_with_name ("output-sync suppressed: ", "stderr");
773 }
774 else
775 perror_with_name ("output-sync suppressed: ", "stdout");
776 output_sync = OUTPUT_SYNC_NONE;
777
778# else /* !CONFIG_NEW_WIN_CHILDREN */
779 if ((!STREAM_OK (stdout) && !STREAM_OK (stderr))
780 || (sync_handle = create_mutex ()) == -1)
781 {
782 perror_with_name ("output-sync suppressed: ", "stderr");
783 output_sync = 0;
784 }
785 else
786 {
787 combined_output = same_stream (stdout, stderr);
788 prepare_mutex_handle_string (sync_handle);
789 }
790# endif /* !CONFIG_NEW_WIN_CHILDREN */
791
792#else
793 if (STREAM_OK (stdout))
794 {
795 struct stat stbuf_o, stbuf_e;
796
797 sync_handle = fileno (stdout);
798 combined_output = (fstat (fileno (stdout), &stbuf_o) == 0
799 && fstat (fileno (stderr), &stbuf_e) == 0
800 && stbuf_o.st_dev == stbuf_e.st_dev
801 && stbuf_o.st_ino == stbuf_e.st_ino);
802 }
803 else if (STREAM_OK (stderr))
804 sync_handle = fileno (stderr);
805 else
806 {
807 perror_with_name ("output-sync suppressed: ", "stderr");
808 output_sync = 0;
809 }
810#endif
811
812 return combined_output;
813}
814
815#ifndef CONFIG_WITH_OUTPUT_IN_MEMORY
816/* Support routine for output_sync() */
817static void
818pump_from_tmp (int from, FILE *to)
819{
820# ifdef KMK
821 char buffer[8192];
822# else
823 static char buffer[8192];
824#endif
825
826# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
827 int prev_mode;
828
829 /* "from" is opened by open_tmpfd, which does it in binary mode, so
830 we need the mode of "to" to match that. */
831 prev_mode = _setmode (fileno (to), O_BINARY);
832#endif
833
834 if (lseek (from, 0, SEEK_SET) == -1)
835 perror ("lseek()");
836
837 while (1)
838 {
839 int len;
840 EINTRLOOP (len, read (from, buffer, sizeof (buffer)));
841 if (len < 0)
842 perror ("read()");
843 if (len <= 0)
844 break;
845#ifdef KMK
846 if (output_metered < 0)
847 { /* likely */ }
848 else
849 meter_output_block (buffer, len);
850#endif
851 if (fwrite (buffer, len, 1, to) < 1)
852 {
853 perror ("fwrite()");
854 break;
855 }
856 fflush (to);
857 }
858
859# if defined (KBUILD_OS_WINDOWS) || defined (KBUILD_OS_OS2) || defined (KBUILD_OS_DOS)
860 /* Switch "to" back to its original mode, so that log messages by
861 Make have the same EOL format as without --output-sync. */
862 _setmode (fileno (to), prev_mode);
863#endif
864}
865#endif /* CONFIG_WITH_OUTPUT_IN_MEMORY */
866
867/* Obtain the lock for writing output. */
868static void *
869acquire_semaphore (void)
870{
871 static struct flock fl;
872
873 fl.l_type = F_WRLCK;
874 fl.l_whence = SEEK_SET;
875 fl.l_start = 0;
876 fl.l_len = 1;
877 if (fcntl (sync_handle, F_SETLKW, &fl) != -1)
878 return &fl;
879#ifdef KBUILD_OS_DARWIN /* F_SETLKW isn't supported on pipes */
880 if (errno != EBADF)
881#endif
882 perror ("fcntl()");
883 return NULL;
884}
885
886/* Release the lock for writing output. */
887static void
888release_semaphore (void *sem)
889{
890 struct flock *flp = (struct flock *)sem;
891 flp->l_type = F_UNLCK;
892 if (fcntl (sync_handle, F_SETLKW, flp) == -1)
893 perror ("fcntl()");
894}
895
896#ifndef CONFIG_WITH_OUTPUT_IN_MEMORY
897
898/* Returns a file descriptor to a temporary file. The file is automatically
899 closed/deleted on exit. Don't use a FILE* stream. */
900int
901output_tmpfd (void)
902{
903 int fd = -1;
904 FILE *tfile = tmpfile ();
905
906 if (! tfile)
907 {
908#ifdef KMK
909 if (output_context && output_context->syncout)
910 output_context->syncout = 0; /* Avoid inifinit recursion. */
911#endif
912 pfatal_with_name ("tmpfile");
913 }
914
915 /* Create a duplicate so we can close the stream. */
916 fd = dup (fileno (tfile));
917 if (fd < 0)
918 {
919#ifdef KMK
920 if (output_context && output_context->syncout)
921 output_context->syncout = 0; /* Avoid inifinit recursion. */
922#endif
923 pfatal_with_name ("dup");
924 }
925
926 fclose (tfile);
927
928 set_append_mode (fd);
929
930 return fd;
931}
932
933/* Adds file descriptors to the child structure to support output_sync; one
934 for stdout and one for stderr as long as they are open. If stdout and
935 stderr share a device they can share a temp file too.
936 Will reset output_sync on error. */
937static void
938setup_tmpfile (struct output *out)
939{
940 /* Is make's stdout going to the same place as stderr? */
941 static int combined_output = -1;
942
943 if (combined_output < 0)
944 {
945#ifdef KMK /* prevent infinite recursion if sync_init() calls perror_with_name. */
946 combined_output = 0;
947#endif
948 combined_output = sync_init ();
949 }
950
951 if (STREAM_OK (stdout))
952 {
953 int fd = output_tmpfd ();
954 if (fd < 0)
955 goto error;
956 CLOSE_ON_EXEC (fd);
957 out->out = fd;
958 }
959
960 if (STREAM_OK (stderr))
961 {
962 if (out->out != OUTPUT_NONE && combined_output)
963 out->err = out->out;
964 else
965 {
966 int fd = output_tmpfd ();
967 if (fd < 0)
968 goto error;
969 CLOSE_ON_EXEC (fd);
970 out->err = fd;
971 }
972 }
973
974 return;
975
976 /* If we failed to create a temp file, disable output sync going forward. */
977 error:
978 output_close (out);
979 output_sync = OUTPUT_SYNC_NONE;
980}
981
982#endif /* CONFIG_WITH_OUTPUT_IN_MEMORY */
983
984/* Synchronize the output of jobs in -j mode to keep the results of
985 each job together. This is done by holding the results in temp files,
986 one for stdout and potentially another for stderr, and only releasing
987 them to "real" stdout/stderr when a semaphore can be obtained. */
988
989void
990output_dump (struct output *out)
991{
992#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
993 membuf_dump (out);
994#else
995 int outfd_not_empty = FD_NOT_EMPTY (out->out);
996 int errfd_not_empty = FD_NOT_EMPTY (out->err);
997
998 if (outfd_not_empty || errfd_not_empty)
999 {
1000# ifndef KMK /* this drives me bananas. */
1001 int traced = 0;
1002# endif
1003
1004 /* Try to acquire the semaphore. If it fails, dump the output
1005 unsynchronized; still better than silently discarding it.
1006 We want to keep this lock for as little time as possible. */
1007 void *sem = acquire_semaphore ();
1008
1009# ifndef KMK /* this drives me bananas. */
1010 /* Log the working directory for this dump. */
1011 if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
1012 traced = log_working_directory (1);
1013# endif
1014
1015 if (outfd_not_empty)
1016 pump_from_tmp (out->out, stdout);
1017 if (errfd_not_empty && out->err != out->out)
1018 pump_from_tmp (out->err, stderr);
1019
1020# ifndef KMK /* this drives me bananas. */
1021 if (traced)
1022 log_working_directory (0);
1023# endif
1024
1025 /* Exit the critical section. */
1026 if (sem)
1027 release_semaphore (sem);
1028
1029# ifdef KMK
1030 if (!out->dont_truncate)
1031 { /* likely */ }
1032 else return;
1033# endif
1034 /* Truncate and reset the output, in case we use it again. */
1035 if (out->out != OUTPUT_NONE)
1036 {
1037 int e;
1038 lseek (out->out, 0, SEEK_SET);
1039 EINTRLOOP (e, ftruncate (out->out, 0));
1040 }
1041 if (out->err != OUTPUT_NONE && out->err != out->out)
1042 {
1043 int e;
1044 lseek (out->err, 0, SEEK_SET);
1045 EINTRLOOP (e, ftruncate (out->err, 0));
1046 }
1047 }
1048#endif
1049}
1050
1051# if defined(KMK) && !defined(CONFIG_WITH_OUTPUT_IN_MEMORY)
1052/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
1053void output_reset (struct output *out)
1054{
1055 if (out)
1056 {
1057 if (out->out != OUTPUT_NONE)
1058 {
1059 int e;
1060 lseek (out->out, 0, SEEK_SET);
1061 EINTRLOOP (e, ftruncate (out->out, 0));
1062 }
1063 if (out->err != OUTPUT_NONE && out->err != out->out)
1064 {
1065 int e;
1066 lseek (out->err, 0, SEEK_SET);
1067 EINTRLOOP (e, ftruncate (out->err, 0));
1068 }
1069 }
1070}
1071# endif
1072#endif /* NO_OUTPUT_SYNC */
1073
1074
1075
1076/* Provide support for temporary files. */
1077
1078#ifndef HAVE_STDLIB_H
1079# ifdef HAVE_MKSTEMP
1080int mkstemp (char *template);
1081# else
1082char *mktemp (char *template);
1083# endif
1084#endif
1085
1086FILE *
1087output_tmpfile (char **name, const char *template)
1088{
1089#ifdef HAVE_FDOPEN
1090 int fd;
1091#endif
1092
1093#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
1094# define TEMPLATE_LEN strlen (template)
1095#else
1096# define TEMPLATE_LEN L_tmpnam
1097#endif
1098 *name = xmalloc (TEMPLATE_LEN + 1);
1099 strcpy (*name, template);
1100
1101#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
1102 /* It's safest to use mkstemp(), if we can. */
1103 fd = mkstemp (*name);
1104 if (fd == -1)
1105 return 0;
1106 return fdopen (fd, "w");
1107#else
1108# ifdef HAVE_MKTEMP
1109 (void) mktemp (*name);
1110# else
1111 (void) tmpnam (*name);
1112# endif
1113
1114# ifdef HAVE_FDOPEN
1115 /* Can't use mkstemp(), but guard against a race condition. */
1116 EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
1117 if (fd == -1)
1118 return 0;
1119 return fdopen (fd, "w");
1120# else
1121 /* Not secure, but what can we do? */
1122 return fopen (*name, "w");
1123# endif
1124#endif
1125}
1126
1127
1128
1129/* This code is stolen from gnulib.
1130 If/when we abandon the requirement to work with K&R compilers, we can
1131 remove this (and perhaps other parts of GNU make!) and migrate to using
1132 gnulib directly.
1133
1134 This is called only through atexit(), which means die() has already been
1135 invoked. So, call exit() here directly. Apparently that works...?
1136*/
1137
1138/* Close standard output, exiting with status 'exit_failure' on failure.
1139 If a program writes *anything* to stdout, that program should close
1140 stdout and make sure that it succeeds before exiting. Otherwise,
1141 suppose that you go to the extreme of checking the return status
1142 of every function that does an explicit write to stdout. The last
1143 printf can succeed in writing to the internal stream buffer, and yet
1144 the fclose(stdout) could still fail (due e.g., to a disk full error)
1145 when it tries to write out that buffered data. Thus, you would be
1146 left with an incomplete output file and the offending program would
1147 exit successfully. Even calling fflush is not always sufficient,
1148 since some file systems (NFS and CODA) buffer written/flushed data
1149 until an actual close call.
1150
1151 Besides, it's wasteful to check the return value from every call
1152 that writes to stdout -- just let the internal stream state record
1153 the failure. That's what the ferror test is checking below.
1154
1155 It's important to detect such failures and exit nonzero because many
1156 tools (most notably 'make' and other build-management systems) depend
1157 on being able to detect failure in other tools via their exit status. */
1158
1159static void
1160close_stdout (void)
1161{
1162 int prev_fail = ferror (stdout);
1163 int fclose_fail = fclose (stdout);
1164
1165 if (prev_fail || fclose_fail)
1166 {
1167 if (fclose_fail)
1168 perror_with_name (_("write error: stdout"), "");
1169 else
1170 O (error, NILF, _("write error: stdout"));
1171 exit (MAKE_TROUBLE);
1172 }
1173}
1174
1175
1176
1177void
1178output_init (struct output *out)
1179{
1180 if (out)
1181 {
1182#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1183 out->out.head_seg = NULL;
1184 out->out.tail_seg = NULL;
1185 out->out.head_run = NULL;
1186 out->out.tail_run = NULL;
1187 out->err.head_seg = NULL;
1188 out->err.tail_seg = NULL;
1189 out->err.head_run = NULL;
1190 out->err.tail_run = NULL;
1191 out->err.total = 0;
1192 out->out.total = 0;
1193 out->seqno = 0;
1194#else
1195 out->out = out->err = OUTPUT_NONE;
1196#endif
1197 out->syncout = !!output_sync;
1198#ifdef KMK
1199 out->dont_truncate = 0;
1200#endif
1201 return;
1202 }
1203
1204 /* Configure this instance of make. Be sure stdout is line-buffered. */
1205
1206#ifdef HAVE_SETVBUF
1207# ifdef SETVBUF_REVERSED
1208 setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
1209# else /* setvbuf not reversed. */
1210 /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
1211 setvbuf (stdout, 0, _IOLBF, BUFSIZ);
1212# endif /* setvbuf reversed. */
1213#elif HAVE_SETLINEBUF
1214 setlinebuf (stdout);
1215#endif /* setlinebuf missing. */
1216
1217 /* Force stdout/stderr into append mode. This ensures parallel jobs won't
1218 lose output due to overlapping writes. */
1219 set_append_mode (fileno (stdout));
1220 set_append_mode (fileno (stderr));
1221
1222#ifdef HAVE_ATEXIT
1223 if (STREAM_OK (stdout))
1224 atexit (close_stdout);
1225#endif
1226}
1227
1228void
1229output_close (struct output *out)
1230{
1231 if (! out)
1232 {
1233 if (stdio_traced)
1234 log_working_directory (0);
1235 return;
1236 }
1237
1238#ifndef NO_OUTPUT_SYNC
1239 output_dump (out);
1240#endif
1241
1242#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1243 assert (out->out.total == 0);
1244 assert (out->out.head_seg == NULL);
1245 assert (out->err.total == 0);
1246 assert (out->err.head_seg == NULL);
1247#else
1248 if (out->out >= 0)
1249 close (out->out);
1250 if (out->err >= 0 && out->err != out->out)
1251 close (out->err);
1252#endif
1253
1254 output_init (out);
1255}
1256
1257/* We're about to generate output: be sure it's set up. */
1258void
1259output_start (void)
1260{
1261#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1262 /* If we're syncing output make sure the sempahore (win) is set up. */
1263 if (output_context && output_context->syncout)
1264 if (combined_output < 0)
1265 combined_output = sync_init ();
1266#else
1267#ifndef NO_OUTPUT_SYNC
1268 /* If we're syncing output make sure the temporary file is set up. */
1269 if (output_context && output_context->syncout)
1270 if (! OUTPUT_ISSET(output_context))
1271 setup_tmpfile (output_context);
1272#endif
1273#endif
1274
1275#ifndef KMK
1276 /* If we're not syncing this output per-line or per-target, make sure we emit
1277 the "Entering..." message where appropriate. */
1278 if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
1279#else
1280 /* Indiscriminately output "Entering..." and "Leaving..." message for each
1281 command line or target is plain annoying! And when there is no recursion
1282 it's actually inappropriate. Haven't got a simple way of detecting that,
1283 so back to the old behavior for now. [bird] */
1284#endif
1285 if (! stdio_traced && print_directory_flag)
1286 stdio_traced = log_working_directory (1);
1287}
1288
1289void
1290outputs (int is_err, const char *msg)
1291{
1292 if (! msg || *msg == '\0')
1293 return;
1294
1295 output_start ();
1296
1297 _outputs (output_context, is_err, msg);
1298}
1299
1300
1301
1302static struct fmtstring
1303 {
1304 char *buffer;
1305 size_t size;
1306 } fmtbuf = { NULL, 0 };
1307
1308static char *
1309get_buffer (size_t need)
1310{
1311 /* Make sure we have room. NEED includes space for \0. */
1312 if (need > fmtbuf.size)
1313 {
1314 fmtbuf.size += need * 2;
1315 fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
1316 }
1317
1318 fmtbuf.buffer[need-1] = '\0';
1319
1320 return fmtbuf.buffer;
1321}
1322
1323/* Print a message on stdout. */
1324
1325void
1326message (int prefix, size_t len, const char *fmt, ...)
1327{
1328 va_list args;
1329 char *p;
1330
1331 len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
1332 p = get_buffer (len);
1333
1334 if (prefix)
1335 {
1336 if (makelevel == 0)
1337 sprintf (p, "%s: ", program);
1338 else
1339 sprintf (p, "%s[%u]: ", program, makelevel);
1340 p += strlen (p);
1341 }
1342
1343 va_start (args, fmt);
1344 vsprintf (p, fmt, args);
1345 va_end (args);
1346
1347 strcat (p, "\n");
1348
1349 assert (fmtbuf.buffer[len-1] == '\0');
1350 outputs (0, fmtbuf.buffer);
1351}
1352
1353/* Print an error message. */
1354
1355void
1356error (const floc *flocp, size_t len, const char *fmt, ...)
1357{
1358 va_list args;
1359 char *p;
1360
1361 len += (strlen (fmt) + strlen (program)
1362 + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
1363 + INTSTR_LENGTH + 4 + 1 + 1);
1364 p = get_buffer (len);
1365
1366 if (flocp && flocp->filenm)
1367 sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
1368 else if (makelevel == 0)
1369 sprintf (p, "%s: ", program);
1370 else
1371 sprintf (p, "%s[%u]: ", program, makelevel);
1372 p += strlen (p);
1373
1374 va_start (args, fmt);
1375 vsprintf (p, fmt, args);
1376 va_end (args);
1377
1378 strcat (p, "\n");
1379
1380 assert (fmtbuf.buffer[len-1] == '\0');
1381 outputs (1, fmtbuf.buffer);
1382}
1383
1384/* Print an error message and exit. */
1385
1386void
1387fatal (const floc *flocp, size_t len, const char *fmt, ...)
1388{
1389 va_list args;
1390 const char *stop = _(". Stop.\n");
1391 char *p;
1392
1393 len += (strlen (fmt) + strlen (program)
1394 + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
1395 + INTSTR_LENGTH + 8 + strlen (stop) + 1);
1396 p = get_buffer (len);
1397
1398 if (flocp && flocp->filenm)
1399 sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
1400 else if (makelevel == 0)
1401 sprintf (p, "%s: *** ", program);
1402 else
1403 sprintf (p, "%s[%u]: *** ", program, makelevel);
1404 p += strlen (p);
1405
1406 va_start (args, fmt);
1407 vsprintf (p, fmt, args);
1408 va_end (args);
1409
1410 strcat (p, stop);
1411
1412 assert (fmtbuf.buffer[len-1] == '\0');
1413 outputs (1, fmtbuf.buffer);
1414
1415 die (MAKE_FAILURE);
1416}
1417
1418/* Print an error message from errno. */
1419
1420void
1421perror_with_name (const char *str, const char *name)
1422{
1423 const char *err = strerror (errno);
1424 OSSS (error, NILF, _("%s%s: %s"), str, name, err);
1425}
1426
1427/* Print an error message from errno and exit. */
1428
1429void
1430pfatal_with_name (const char *name)
1431{
1432 const char *err = strerror (errno);
1433 OSS (fatal, NILF, _("%s: %s"), name, err);
1434
1435 /* NOTREACHED */
1436}
Note: See TracBrowser for help on using the repository browser.