VirtualBox

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

Last change on this file since 3633 was 3563, checked in by bird, 3 years ago

kmk/output.c: warning

  • 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# ifndef KMK /* this drives me bananas. */
964 int traced = 0;
965# endif
966
967 /* Try to acquire the semaphore. If it fails, dump the output
968 unsynchronized; still better than silently discarding it.
969 We want to keep this lock for as little time as possible. */
970 void *sem = acquire_semaphore ();
971
972# ifndef KMK /* this drives me bananas. */
973 /* Log the working directory for this dump. */
974 if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
975 traced = log_working_directory (1);
976# endif
977
978 if (outfd_not_empty)
979 pump_from_tmp (out->out, stdout);
980 if (errfd_not_empty && out->err != out->out)
981 pump_from_tmp (out->err, stderr);
982
983# ifndef KMK /* this drives me bananas. */
984 if (traced)
985 log_working_directory (0);
986# endif
987
988 /* Exit the critical section. */
989 if (sem)
990 release_semaphore (sem);
991
992# ifdef KMK
993 if (!out->dont_truncate)
994 { /* likely */ }
995 else return;
996# endif
997 /* Truncate and reset the output, in case we use it again. */
998 if (out->out != OUTPUT_NONE)
999 {
1000 int e;
1001 lseek (out->out, 0, SEEK_SET);
1002 EINTRLOOP (e, ftruncate (out->out, 0));
1003 }
1004 if (out->err != OUTPUT_NONE && out->err != out->out)
1005 {
1006 int e;
1007 lseek (out->err, 0, SEEK_SET);
1008 EINTRLOOP (e, ftruncate (out->err, 0));
1009 }
1010 }
1011#endif
1012}
1013
1014# if defined(KMK) && !defined(CONFIG_WITH_OUTPUT_IN_MEMORY)
1015/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
1016void output_reset (struct output *out)
1017{
1018 if (out)
1019 {
1020 if (out->out != OUTPUT_NONE)
1021 {
1022 int e;
1023 lseek (out->out, 0, SEEK_SET);
1024 EINTRLOOP (e, ftruncate (out->out, 0));
1025 }
1026 if (out->err != OUTPUT_NONE && out->err != out->out)
1027 {
1028 int e;
1029 lseek (out->err, 0, SEEK_SET);
1030 EINTRLOOP (e, ftruncate (out->err, 0));
1031 }
1032 }
1033}
1034# endif
1035#endif /* NO_OUTPUT_SYNC */
1036
1037
1038
1039/* Provide support for temporary files. */
1040
1041#ifndef HAVE_STDLIB_H
1042# ifdef HAVE_MKSTEMP
1043int mkstemp (char *template);
1044# else
1045char *mktemp (char *template);
1046# endif
1047#endif
1048
1049FILE *
1050output_tmpfile (char **name, const char *template)
1051{
1052#ifdef HAVE_FDOPEN
1053 int fd;
1054#endif
1055
1056#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
1057# define TEMPLATE_LEN strlen (template)
1058#else
1059# define TEMPLATE_LEN L_tmpnam
1060#endif
1061 *name = xmalloc (TEMPLATE_LEN + 1);
1062 strcpy (*name, template);
1063
1064#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
1065 /* It's safest to use mkstemp(), if we can. */
1066 fd = mkstemp (*name);
1067 if (fd == -1)
1068 return 0;
1069 return fdopen (fd, "w");
1070#else
1071# ifdef HAVE_MKTEMP
1072 (void) mktemp (*name);
1073# else
1074 (void) tmpnam (*name);
1075# endif
1076
1077# ifdef HAVE_FDOPEN
1078 /* Can't use mkstemp(), but guard against a race condition. */
1079 EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
1080 if (fd == -1)
1081 return 0;
1082 return fdopen (fd, "w");
1083# else
1084 /* Not secure, but what can we do? */
1085 return fopen (*name, "w");
1086# endif
1087#endif
1088}
1089
1090
1091
1092/* This code is stolen from gnulib.
1093 If/when we abandon the requirement to work with K&R compilers, we can
1094 remove this (and perhaps other parts of GNU make!) and migrate to using
1095 gnulib directly.
1096
1097 This is called only through atexit(), which means die() has already been
1098 invoked. So, call exit() here directly. Apparently that works...?
1099*/
1100
1101/* Close standard output, exiting with status 'exit_failure' on failure.
1102 If a program writes *anything* to stdout, that program should close
1103 stdout and make sure that it succeeds before exiting. Otherwise,
1104 suppose that you go to the extreme of checking the return status
1105 of every function that does an explicit write to stdout. The last
1106 printf can succeed in writing to the internal stream buffer, and yet
1107 the fclose(stdout) could still fail (due e.g., to a disk full error)
1108 when it tries to write out that buffered data. Thus, you would be
1109 left with an incomplete output file and the offending program would
1110 exit successfully. Even calling fflush is not always sufficient,
1111 since some file systems (NFS and CODA) buffer written/flushed data
1112 until an actual close call.
1113
1114 Besides, it's wasteful to check the return value from every call
1115 that writes to stdout -- just let the internal stream state record
1116 the failure. That's what the ferror test is checking below.
1117
1118 It's important to detect such failures and exit nonzero because many
1119 tools (most notably 'make' and other build-management systems) depend
1120 on being able to detect failure in other tools via their exit status. */
1121
1122static void
1123close_stdout (void)
1124{
1125 int prev_fail = ferror (stdout);
1126 int fclose_fail = fclose (stdout);
1127
1128 if (prev_fail || fclose_fail)
1129 {
1130 if (fclose_fail)
1131 perror_with_name (_("write error: stdout"), "");
1132 else
1133 O (error, NILF, _("write error: stdout"));
1134 exit (MAKE_TROUBLE);
1135 }
1136}
1137
1138
1139
1140void
1141output_init (struct output *out)
1142{
1143 if (out)
1144 {
1145#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1146 out->out.head_seg = NULL;
1147 out->out.tail_seg = NULL;
1148 out->out.head_run = NULL;
1149 out->out.tail_run = NULL;
1150 out->err.head_seg = NULL;
1151 out->err.tail_seg = NULL;
1152 out->err.head_run = NULL;
1153 out->err.tail_run = NULL;
1154 out->err.total = 0;
1155 out->out.total = 0;
1156 out->seqno = 0;
1157#else
1158 out->out = out->err = OUTPUT_NONE;
1159#endif
1160 out->syncout = !!output_sync;
1161#ifdef KMK
1162 out->dont_truncate = 0;
1163#endif
1164 return;
1165 }
1166
1167 /* Configure this instance of make. Be sure stdout is line-buffered. */
1168
1169#ifdef HAVE_SETVBUF
1170# ifdef SETVBUF_REVERSED
1171 setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
1172# else /* setvbuf not reversed. */
1173 /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
1174 setvbuf (stdout, 0, _IOLBF, BUFSIZ);
1175# endif /* setvbuf reversed. */
1176#elif HAVE_SETLINEBUF
1177 setlinebuf (stdout);
1178#endif /* setlinebuf missing. */
1179
1180 /* Force stdout/stderr into append mode. This ensures parallel jobs won't
1181 lose output due to overlapping writes. */
1182 set_append_mode (fileno (stdout));
1183 set_append_mode (fileno (stderr));
1184
1185#ifdef HAVE_ATEXIT
1186 if (STREAM_OK (stdout))
1187 atexit (close_stdout);
1188#endif
1189}
1190
1191void
1192output_close (struct output *out)
1193{
1194 if (! out)
1195 {
1196 if (stdio_traced)
1197 log_working_directory (0);
1198 return;
1199 }
1200
1201#ifndef NO_OUTPUT_SYNC
1202 output_dump (out);
1203#endif
1204
1205#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1206 assert (out->out.total == 0);
1207 assert (out->out.head_seg == NULL);
1208 assert (out->err.total == 0);
1209 assert (out->err.head_seg == NULL);
1210#else
1211 if (out->out >= 0)
1212 close (out->out);
1213 if (out->err >= 0 && out->err != out->out)
1214 close (out->err);
1215#endif
1216
1217 output_init (out);
1218}
1219
1220/* We're about to generate output: be sure it's set up. */
1221void
1222output_start (void)
1223{
1224#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
1225 /* If we're syncing output make sure the sempahore (win) is set up. */
1226 if (output_context && output_context->syncout)
1227 if (combined_output < 0)
1228 combined_output = sync_init ();
1229#else
1230#ifndef NO_OUTPUT_SYNC
1231 /* If we're syncing output make sure the temporary file is set up. */
1232 if (output_context && output_context->syncout)
1233 if (! OUTPUT_ISSET(output_context))
1234 setup_tmpfile (output_context);
1235#endif
1236#endif
1237
1238#ifndef KMK
1239 /* If we're not syncing this output per-line or per-target, make sure we emit
1240 the "Entering..." message where appropriate. */
1241 if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
1242#else
1243 /* Indiscriminately output "Entering..." and "Leaving..." message for each
1244 command line or target is plain annoying! And when there is no recursion
1245 it's actually inappropriate. Haven't got a simple way of detecting that,
1246 so back to the old behavior for now. [bird] */
1247#endif
1248 if (! stdio_traced && print_directory_flag)
1249 stdio_traced = log_working_directory (1);
1250}
1251
1252void
1253outputs (int is_err, const char *msg)
1254{
1255 if (! msg || *msg == '\0')
1256 return;
1257
1258 output_start ();
1259
1260 _outputs (output_context, is_err, msg);
1261}
1262
1263
1264
1265static struct fmtstring
1266 {
1267 char *buffer;
1268 size_t size;
1269 } fmtbuf = { NULL, 0 };
1270
1271static char *
1272get_buffer (size_t need)
1273{
1274 /* Make sure we have room. NEED includes space for \0. */
1275 if (need > fmtbuf.size)
1276 {
1277 fmtbuf.size += need * 2;
1278 fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
1279 }
1280
1281 fmtbuf.buffer[need-1] = '\0';
1282
1283 return fmtbuf.buffer;
1284}
1285
1286/* Print a message on stdout. */
1287
1288void
1289message (int prefix, size_t len, const char *fmt, ...)
1290{
1291 va_list args;
1292 char *p;
1293
1294 len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
1295 p = get_buffer (len);
1296
1297 if (prefix)
1298 {
1299 if (makelevel == 0)
1300 sprintf (p, "%s: ", program);
1301 else
1302 sprintf (p, "%s[%u]: ", program, makelevel);
1303 p += strlen (p);
1304 }
1305
1306 va_start (args, fmt);
1307 vsprintf (p, fmt, args);
1308 va_end (args);
1309
1310 strcat (p, "\n");
1311
1312 assert (fmtbuf.buffer[len-1] == '\0');
1313 outputs (0, fmtbuf.buffer);
1314}
1315
1316/* Print an error message. */
1317
1318void
1319error (const floc *flocp, size_t len, const char *fmt, ...)
1320{
1321 va_list args;
1322 char *p;
1323
1324 len += (strlen (fmt) + strlen (program)
1325 + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
1326 + INTSTR_LENGTH + 4 + 1 + 1);
1327 p = get_buffer (len);
1328
1329 if (flocp && flocp->filenm)
1330 sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
1331 else if (makelevel == 0)
1332 sprintf (p, "%s: ", program);
1333 else
1334 sprintf (p, "%s[%u]: ", program, makelevel);
1335 p += strlen (p);
1336
1337 va_start (args, fmt);
1338 vsprintf (p, fmt, args);
1339 va_end (args);
1340
1341 strcat (p, "\n");
1342
1343 assert (fmtbuf.buffer[len-1] == '\0');
1344 outputs (1, fmtbuf.buffer);
1345}
1346
1347/* Print an error message and exit. */
1348
1349void
1350fatal (const floc *flocp, size_t len, const char *fmt, ...)
1351{
1352 va_list args;
1353 const char *stop = _(". Stop.\n");
1354 char *p;
1355
1356 len += (strlen (fmt) + strlen (program)
1357 + (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
1358 + INTSTR_LENGTH + 8 + strlen (stop) + 1);
1359 p = get_buffer (len);
1360
1361 if (flocp && flocp->filenm)
1362 sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
1363 else if (makelevel == 0)
1364 sprintf (p, "%s: *** ", program);
1365 else
1366 sprintf (p, "%s[%u]: *** ", program, makelevel);
1367 p += strlen (p);
1368
1369 va_start (args, fmt);
1370 vsprintf (p, fmt, args);
1371 va_end (args);
1372
1373 strcat (p, stop);
1374
1375 assert (fmtbuf.buffer[len-1] == '\0');
1376 outputs (1, fmtbuf.buffer);
1377
1378 die (MAKE_FAILURE);
1379}
1380
1381/* Print an error message from errno. */
1382
1383void
1384perror_with_name (const char *str, const char *name)
1385{
1386 const char *err = strerror (errno);
1387 OSSS (error, NILF, _("%s%s: %s"), str, name, err);
1388}
1389
1390/* Print an error message from errno and exit. */
1391
1392void
1393pfatal_with_name (const char *name)
1394{
1395 const char *err = strerror (errno);
1396 OSS (fatal, NILF, _("%s: %s"), name, err);
1397
1398 /* NOTREACHED */
1399}
Note: See TracBrowser for help on using the repository browser.

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