VirtualBox

source: kBuild/trunk/src/kmk/output.c@ 3479

Last change on this file since 3479 was 3479, checked in by bird, 4 years ago

kmk: Added some refinements to the recent repeat-output-from-failing-command-in-die hack.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette