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

Last change on this file since 3194 was 3194, checked in by bird, 7 years ago

kmk/win: Windows kmk now defaults to --output-sync=target. Fixed output sync on windows in nested make processes that got busted by winchildren and it's no inheritance policy.

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