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

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

kmk/output.c: fixed output_write_text return value.

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