VirtualBox

source: kBuild/trunk/src/kmk/misc.c@ 2765

Last change on this file since 2765 was 2745, checked in by bird, 10 years ago

Some heap stats stuff.

  • Property svn:eol-style set to native
File size: 34.5 KB
Line 
1/* Miscellaneous generic support functions for GNU Make.
2Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
31998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
42010 Free Software Foundation, Inc.
5This file is part of GNU Make.
6
7GNU Make is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 3 of the License, or (at your option) any later
10version.
11
12GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License along with
17this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "make.h"
20#include "dep.h"
21#include "debug.h"
22#if defined (CONFIG_WITH_VALUE_LENGTH) || defined (CONFIG_WITH_ALLOC_CACHES)
23# include <assert.h>
24#endif
25#ifdef CONFIG_WITH_PRINT_STATS_SWITCH
26# ifdef __APPLE__
27# include <malloc/malloc.h>
28# endif
29# if defined(__GLIBC__) || defined(HAVE_MALLINFO)
30# include <malloc.h>
31# endif
32#endif
33
34#if defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_PRINT_TIME_SWITCH)
35# ifdef WINDOWS32
36# include <Windows.h>
37# endif
38#endif
39
40/* All bcopy calls in this file can be replaced by memcpy and save a tick or two. */
41#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
42# undef bcopy
43# if defined(__GNUC__) && defined(CONFIG_WITH_OPTIMIZATION_HACKS)
44# define bcopy(src, dst, size) __builtin_memcpy ((dst), (src), (size))
45# else
46# define bcopy(src, dst, size) memcpy ((dst), (src), (size))
47# endif
48#endif
49
50/* Variadic functions. We go through contortions to allow proper function
51 prototypes for both ANSI and pre-ANSI C compilers, and also for those
52 which support stdarg.h vs. varargs.h, and finally those which have
53 vfprintf(), etc. and those who have _doprnt... or nothing.
54
55 This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and
56 VA_END macros used here since we have multiple print functions. */
57
58#if USE_VARIADIC
59# if HAVE_STDARG_H
60# include <stdarg.h>
61# define VA_START(args, lastarg) va_start(args, lastarg)
62# else
63# include <varargs.h>
64# define VA_START(args, lastarg) va_start(args)
65# endif
66# if HAVE_VPRINTF
67# define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
68# else
69# define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
70# endif
71# define VA_END(args) va_end(args)
72#else
73/* We can't use any variadic interface! */
74# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
75# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
76# define VA_START(args, lastarg)
77# define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist)
78# define VA_END(args)
79#endif
80
81
82/* Compare strings *S1 and *S2.
83 Return negative if the first is less, positive if it is greater,
84 zero if they are equal. */
85
86int
87alpha_compare (const void *v1, const void *v2)
88{
89 const char *s1 = *((char **)v1);
90 const char *s2 = *((char **)v2);
91
92 if (*s1 != *s2)
93 return *s1 - *s2;
94 return strcmp (s1, s2);
95}
96
97
98/* Discard each backslash-newline combination from LINE.
99 Backslash-backslash-newline combinations become backslash-newlines.
100 This is done by copying the text at LINE into itself. */
101
102#ifndef CONFIG_WITH_VALUE_LENGTH
103void
104collapse_continuations (char *line)
105#else
106char *
107collapse_continuations (char *line, unsigned int linelen)
108#endif
109{
110 register char *in, *out, *p;
111 register int backslash;
112 register unsigned int bs_write;
113
114#ifndef CONFIG_WITH_VALUE_LENGTH
115 in = strchr (line, '\n');
116 if (in == 0)
117 return;
118#else
119 assert (strlen (line) == linelen);
120 in = memchr (line, '\n', linelen);
121 if (in == 0)
122 return line + linelen;
123 if (in == line || in[-1] != '\\')
124 {
125 do
126 {
127 unsigned int off_in = in - line;
128 if (off_in == linelen)
129 return in;
130 in = memchr (in + 1, '\n', linelen - off_in - 1);
131 if (in == 0)
132 return line + linelen;
133 }
134 while (in[-1] != '\\');
135 }
136#endif
137
138 out = in;
139 while (out > line && out[-1] == '\\')
140 --out;
141
142 while (*in != '\0')
143 {
144 /* BS_WRITE gets the number of quoted backslashes at
145 the end just before IN, and BACKSLASH gets nonzero
146 if the next character is quoted. */
147 backslash = 0;
148 bs_write = 0;
149 for (p = in - 1; p >= line && *p == '\\'; --p)
150 {
151 if (backslash)
152 ++bs_write;
153 backslash = !backslash;
154
155 /* It should be impossible to go back this far without exiting,
156 but if we do, we can't get the right answer. */
157 if (in == out - 1)
158 abort ();
159 }
160
161 /* Output the appropriate number of backslashes. */
162 while (bs_write-- > 0)
163 *out++ = '\\';
164
165 /* Skip the newline. */
166 ++in;
167
168 /* If the newline is escaped, discard following whitespace leaving just
169 one space. POSIX requires that each backslash/newline/following
170 whitespace sequence be reduced to a single space. */
171 if (backslash)
172 {
173 in = next_token (in);
174 /* Removing this loop will fix Savannah bug #16670: do we want to? */
175 while (out > line && isblank ((unsigned char)out[-1]))
176 --out;
177 *out++ = ' ';
178 }
179 else
180 /* If the newline isn't quoted, put it in the output. */
181 *out++ = '\n';
182
183 /* Now copy the following line to the output.
184 Stop when we find backslashes followed by a newline. */
185 while (*in != '\0')
186 if (*in == '\\')
187 {
188 p = in + 1;
189 while (*p == '\\')
190 ++p;
191 if (*p == '\n')
192 {
193 in = p;
194 break;
195 }
196 while (in < p)
197 *out++ = *in++;
198 }
199 else
200 *out++ = *in++;
201 }
202
203 *out = '\0';
204#ifdef CONFIG_WITH_VALUE_LENGTH
205 assert (strchr (line, '\0') == out);
206 return out;
207#endif
208}
209
210
211/* Print N spaces (used in debug for target-depth). */
212
213void
214print_spaces (unsigned int n)
215{
216 while (n-- > 0)
217 putchar (' ');
218}
219
220
221
222/* Return a string whose contents concatenate the NUM strings provided
223 This string lives in static, re-used memory. */
224
225const char *
226#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
227concat (unsigned int num, ...)
228#else
229concat (num, va_alist)
230 unsigned int num;
231 va_dcl
232#endif
233{
234 static unsigned int rlen = 0;
235 static char *result = NULL;
236 unsigned int ri = 0; /* bird: must be unsigned */
237
238#if USE_VARIADIC
239 va_list args;
240#endif
241
242 VA_START (args, num);
243
244 while (num-- > 0)
245 {
246 const char *s = va_arg (args, const char *);
247 unsigned int l = s ? strlen (s) : 0;
248
249 if (l == 0)
250 continue;
251
252 if (ri + l > rlen)
253 {
254 rlen = ((rlen ? rlen : 60) + l) * 2;
255 result = xrealloc (result, rlen);
256 }
257
258 memcpy (result + ri, s, l);
259 ri += l;
260 }
261
262 VA_END (args);
263
264 /* Get some more memory if we don't have enough space for the
265 terminating '\0'. */
266 if (ri == rlen)
267 {
268 rlen = (rlen ? rlen : 60) * 2;
269 result = xrealloc (result, rlen);
270 }
271
272 result[ri] = '\0';
273
274 return result;
275}
276
277
278/* Print a message on stdout. */
279
280void
281#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
282message (int prefix, const char *fmt, ...)
283#else
284message (prefix, fmt, va_alist)
285 int prefix;
286 const char *fmt;
287 va_dcl
288#endif
289{
290#if USE_VARIADIC
291 va_list args;
292#endif
293
294 log_working_directory (1);
295
296 if (fmt != 0)
297 {
298 if (prefix)
299 {
300 if (makelevel == 0)
301 printf ("%s: ", program);
302 else
303 printf ("%s[%u]: ", program, makelevel);
304 }
305 VA_START (args, fmt);
306 VA_PRINTF (stdout, fmt, args);
307 VA_END (args);
308 putchar ('\n');
309 }
310
311 fflush (stdout);
312}
313
314/* Print an error message. */
315
316void
317#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
318error (const struct floc *flocp, const char *fmt, ...)
319#else
320error (flocp, fmt, va_alist)
321 const struct floc *flocp;
322 const char *fmt;
323 va_dcl
324#endif
325{
326#if USE_VARIADIC
327 va_list args;
328#endif
329
330 log_working_directory (1);
331
332 if (flocp && flocp->filenm)
333 fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
334 else if (makelevel == 0)
335 fprintf (stderr, "%s: ", program);
336 else
337 fprintf (stderr, "%s[%u]: ", program, makelevel);
338
339 VA_START(args, fmt);
340 VA_PRINTF (stderr, fmt, args);
341 VA_END (args);
342
343 putc ('\n', stderr);
344 fflush (stderr);
345}
346
347/* Print an error message and exit. */
348
349void
350#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
351fatal (const struct floc *flocp, const char *fmt, ...)
352#else
353fatal (flocp, fmt, va_alist)
354 const struct floc *flocp;
355 const char *fmt;
356 va_dcl
357#endif
358{
359#if USE_VARIADIC
360 va_list args;
361#endif
362
363 log_working_directory (1);
364
365 if (flocp && flocp->filenm)
366 fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
367 else if (makelevel == 0)
368 fprintf (stderr, "%s: *** ", program);
369 else
370 fprintf (stderr, "%s[%u]: *** ", program, makelevel);
371
372 VA_START(args, fmt);
373 VA_PRINTF (stderr, fmt, args);
374 VA_END (args);
375
376 fputs (_(". Stop.\n"), stderr);
377
378 die (2);
379}
380
381#ifndef HAVE_STRERROR
382
383#undef strerror
384
385char *
386strerror (int errnum)
387{
388 extern int errno, sys_nerr;
389#ifndef __DECC
390 extern char *sys_errlist[];
391#endif
392 static char buf[] = "Unknown error 12345678901234567890";
393
394 if (errno < sys_nerr)
395 return sys_errlist[errnum];
396
397 sprintf (buf, _("Unknown error %d"), errnum);
398 return buf;
399}
400#endif
401
402/* Print an error message from errno. */
403
404void
405perror_with_name (const char *str, const char *name)
406{
407 error (NILF, _("%s%s: %s"), str, name, strerror (errno));
408}
409
410/* Print an error message from errno and exit. */
411
412void
413pfatal_with_name (const char *name)
414{
415 fatal (NILF, _("%s: %s"), name, strerror (errno));
416
417 /* NOTREACHED */
418}
419
420
421/* Like malloc but get fatal error if memory is exhausted. */
422/* Don't bother if we're using dmalloc; it provides these for us. */
423
424#if !defined(HAVE_DMALLOC_H) && !defined(ELECTRIC_HEAP) /* bird */
425
426#undef xmalloc
427#undef xcalloc
428#undef xrealloc
429#undef xstrdup
430
431void *
432xmalloc (unsigned int size)
433{
434 /* Make sure we don't allocate 0, for pre-ISO implementations. */
435 void *result = malloc (size ? size : 1);
436 if (result == 0)
437 fatal (NILF, _("virtual memory exhausted"));
438
439#ifdef CONFIG_WITH_MAKE_STATS
440 make_stats_allocations++;
441 if (make_expensive_statistics)
442 make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
443 else
444 make_stats_allocated += size;
445#endif
446 return result;
447}
448
449
450void *
451xcalloc (unsigned int size)
452{
453 /* Make sure we don't allocate 0, for pre-ISO implementations. */
454 void *result = calloc (size ? size : 1, 1);
455 if (result == 0)
456 fatal (NILF, _("virtual memory exhausted"));
457
458#ifdef CONFIG_WITH_MAKE_STATS
459 make_stats_allocations++;
460 if (make_expensive_statistics)
461 make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
462 else
463 make_stats_allocated += size;
464#endif
465 return result;
466}
467
468
469void *
470xrealloc (void *ptr, unsigned int size)
471{
472 void *result;
473#ifdef CONFIG_WITH_MAKE_STATS
474 if (make_expensive_statistics && ptr != NULL)
475 make_stats_allocated -= SIZE_OF_HEAP_BLOCK (ptr);
476 if (ptr)
477 make_stats_reallocations++;
478 else
479 make_stats_allocations++;
480#endif
481
482 /* Some older implementations of realloc() don't conform to ISO. */
483 if (! size)
484 size = 1;
485 result = ptr ? realloc (ptr, size) : malloc (size);
486 if (result == 0)
487 fatal (NILF, _("virtual memory exhausted"));
488
489#ifdef CONFIG_WITH_MAKE_STATS
490 if (make_expensive_statistics)
491 make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
492 else
493 make_stats_allocated += size;
494#endif
495 return result;
496}
497
498
499char *
500xstrdup (const char *ptr)
501{
502 char *result;
503
504#ifdef HAVE_STRDUP
505 result = strdup (ptr);
506#else
507 result = malloc (strlen (ptr) + 1);
508#endif
509
510 if (result == 0)
511 fatal (NILF, _("virtual memory exhausted"));
512
513#ifdef CONFIG_WITH_MAKE_STATS
514 make_stats_allocations++;
515 if (make_expensive_statistics)
516 make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
517 else
518 make_stats_allocated += strlen (ptr) + 1;
519#endif
520#ifdef HAVE_STRDUP
521 return result;
522#else
523 return strcpy (result, ptr);
524#endif
525}
526
527#endif /* HAVE_DMALLOC_H */
528
529char *
530xstrndup (const char *str, unsigned int length)
531{
532 char *result;
533
534#if defined(HAVE_STRNDUP) && !defined(KMK)
535 result = strndup (str, length);
536 if (result == 0)
537 fatal (NILF, _("virtual memory exhausted"));
538#else
539 result = xmalloc (length + 1);
540 if (length > 0)
541 strncpy (result, str, length);
542 result[length] = '\0';
543#endif
544
545 return result;
546}
547
548
549
550#ifndef CONFIG_WITH_OPTIMIZATION_HACKS /* This is really a reimplemntation of
551 memchr, only slower. It's been replaced by a macro in the header file. */
552
553/* Limited INDEX:
554 Search through the string STRING, which ends at LIMIT, for the character C.
555 Returns a pointer to the first occurrence, or nil if none is found.
556 Like INDEX except that the string searched ends where specified
557 instead of at the first null. */
558
559char *
560lindex (const char *s, const char *limit, int c)
561{
562 while (s < limit)
563 if (*s++ == c)
564 return (char *)(s - 1);
565
566 return 0;
567}
568#endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
569
570
571/* Return the address of the first whitespace or null in the string S. */
572
573char *
574end_of_token (const char *s)
575{
576#ifdef KMK
577 for (;;)
578 {
579 unsigned char ch0, ch1, ch2, ch3;
580
581 ch0 = *s;
582 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch0)))
583 return (char *)s;
584 ch1 = s[1];
585 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch1)))
586 return (char *)s + 1;
587 ch2 = s[2];
588 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch2)))
589 return (char *)s + 2;
590 ch3 = s[3];
591 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch3)))
592 return (char *)s + 3;
593
594 s += 4;
595 }
596
597#else
598 while (*s != '\0' && !isblank ((unsigned char)*s))
599 ++s;
600 return (char *)s;
601#endif
602}
603
604#ifdef WINDOWS32
605/*
606 * Same as end_of_token, but take into account a stop character
607 */
608char *
609end_of_token_w32 (const char *s, char stopchar)
610{
611 const char *p = s;
612 int backslash = 0;
613
614 while (*p != '\0' && *p != stopchar
615 && (backslash || !isblank ((unsigned char)*p)))
616 {
617 if (*p++ == '\\')
618 {
619 backslash = !backslash;
620 while (*p == '\\')
621 {
622 backslash = !backslash;
623 ++p;
624 }
625 }
626 else
627 backslash = 0;
628 }
629
630 return (char *)p;
631}
632#endif
633
634/* Return the address of the first nonwhitespace or null in the string S. */
635
636char *
637next_token (const char *s)
638{
639#ifdef KMK
640 for (;;)
641 {
642 unsigned char ch0, ch1, ch2, ch3;
643
644 ch0 = *s;
645 if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch0)))
646 return (char *)s;
647 ch1 = s[1];
648 if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch1)))
649 return (char *)s + 1;
650 ch2 = s[2];
651 if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch2)))
652 return (char *)s + 2;
653 ch3 = s[3];
654 if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch3)))
655 return (char *)s + 3;
656
657 s += 4;
658 }
659
660#else /* !KMK */
661 while (isblank ((unsigned char)*s))
662 ++s;
663 return (char *)s;
664#endif /* !KMK */
665}
666
667/* Find the next token in PTR; return the address of it, and store the length
668 of the token into *LENGTHPTR if LENGTHPTR is not nil. Set *PTR to the end
669 of the token, so this function can be called repeatedly in a loop. */
670
671char *
672find_next_token (const char **ptr, unsigned int *lengthptr)
673{
674#ifdef KMK
675 const char *p = *ptr;
676 const char *e;
677
678 /* skip blanks */
679# if 0 /* a moderate version */
680 for (;; p++)
681 {
682 unsigned char ch = *p;
683 if (!MY_IS_BLANK(ch))
684 {
685 if (!ch)
686 return NULL;
687 break;
688 }
689 }
690
691# else /* (too) big unroll */
692 for (;; p += 4)
693 {
694 unsigned char ch0, ch1, ch2, ch3;
695
696 ch0 = *p;
697 if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch0)))
698 {
699 if (!ch0)
700 return NULL;
701 break;
702 }
703 ch1 = p[1];
704 if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch1)))
705 {
706 if (!ch1)
707 return NULL;
708 p += 1;
709 break;
710 }
711 ch2 = p[2];
712 if (MY_PREDICT_FALSE(!MY_IS_BLANK(ch2)))
713 {
714 if (!ch2)
715 return NULL;
716 p += 2;
717 break;
718 }
719 ch3 = p[3];
720 if (MY_PREDICT_TRUE(!MY_IS_BLANK(ch3)))
721 {
722 if (!ch3)
723 return NULL;
724 p += 3;
725 break;
726 }
727 }
728# endif
729
730 /* skip ahead until EOS or blanks. */
731# if 0 /* a moderate version */
732 for (e = p + 1; ; e++)
733 {
734 unsigned char ch = *e;
735 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch)))
736 break;
737 }
738# else /* (too) big unroll */
739 for (e = p + 1; ; e += 4)
740 {
741 unsigned char ch0, ch1, ch2, ch3;
742
743 ch0 = *e;
744 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch0)))
745 break;
746 ch1 = e[1];
747 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch1)))
748 {
749 e += 1;
750 break;
751 }
752 ch2 = e[2];
753 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch2)))
754 {
755 e += 2;
756 break;
757 }
758 ch3 = e[3];
759 if (MY_PREDICT_FALSE(MY_IS_BLANK_OR_EOS(ch3)))
760 {
761 e += 3;
762 break;
763 }
764 }
765# endif
766 *ptr = e;
767
768 if (lengthptr != 0)
769 *lengthptr = e - p;
770
771 return (char *)p;
772
773#else
774 const char *p = next_token (*ptr);
775
776 if (*p == '\0')
777 return 0;
778
779 *ptr = end_of_token (p);
780 if (lengthptr != 0)
781 *lengthptr = *ptr - p;
782
783 return (char *)p;
784#endif
785}
786#ifdef KMK
787
788/* Same as find_next_token with two exception:
789 - The string ends at EOS or '\0'.
790 - We keep track of $() and ${}, allowing functions to be used. */
791
792char *
793find_next_token_eos (const char **ptr, const char *eos, unsigned int *lengthptr)
794{
795 const char *p = *ptr;
796 const char *e;
797 int level = 0;
798
799 /* skip blanks */
800 for (; p != eos; p++)
801 {
802 unsigned char ch = *p;
803 if (!MY_IS_BLANK(ch))
804 {
805 if (!ch)
806 return NULL;
807 break;
808 }
809 }
810 if (p == eos)
811 return NULL;
812
813 /* skip ahead until EOS or blanks. */
814 for (e = p; e != eos; e++)
815 {
816 unsigned char ch = *e;
817 if (MY_IS_BLANK_OR_EOS(ch))
818 {
819 if (!ch || level == 0)
820 break;
821 }
822 else if (ch == '$')
823 {
824 if (&e[1] != eos && (e[1] == '(' || e[1] == '{'))
825 {
826 level++;
827 e++;
828 }
829 }
830 else if ((ch == ')' || ch == '}') && level > 0)
831 level--;
832 }
833
834 *ptr = e;
835 if (lengthptr != 0)
836 *lengthptr = e - p;
837
838 return (char *)p;
839}
840
841#endif /* KMK */
842
843
844
845/* Copy a chain of `struct dep'. For 2nd expansion deps, dup the name. */
846
847struct dep *
848copy_dep_chain (const struct dep *d)
849{
850 struct dep *firstnew = 0;
851 struct dep *lastnew = 0;
852
853 while (d != 0)
854 {
855#ifndef CONFIG_WITH_ALLOC_CACHES
856 struct dep *c = xmalloc (sizeof (struct dep));
857#else
858 struct dep *c = alloccache_alloc(&dep_cache);
859#endif
860 memcpy (c, d, sizeof (struct dep));
861
862 /** @todo KMK: Check if we need this duplication! */
863 if (c->need_2nd_expansion)
864 c->name = xstrdup (c->name);
865
866 c->next = 0;
867 if (firstnew == 0)
868 firstnew = lastnew = c;
869 else
870 lastnew = lastnew->next = c;
871
872 d = d->next;
873 }
874
875 return firstnew;
876}
877
878/* Free a chain of 'struct dep'. */
879
880void
881free_dep_chain (struct dep *d)
882{
883 while (d != 0)
884 {
885 struct dep *df = d;
886 d = d->next;
887 free_dep (df);
888 }
889}
890
891/* Free a chain of struct nameseq.
892 For struct dep chains use free_dep_chain. */
893
894void
895free_ns_chain (struct nameseq *ns)
896{
897 while (ns != 0)
898 {
899 struct nameseq *t = ns;
900 ns = ns->next;
901#ifndef CONFIG_WITH_ALLOC_CACHES
902 free (t);
903#else
904 alloccache_free (&nameseq_cache, t);
905#endif
906 }
907}
908
909
910
911#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
912
913/* If we don't have strcasecmp() (from POSIX), or anything that can substitute
914 for it, define our own version. */
915
916int
917strcasecmp (const char *s1, const char *s2)
918{
919 while (1)
920 {
921 int c1 = (int) *(s1++);
922 int c2 = (int) *(s2++);
923
924 if (isalpha (c1))
925 c1 = tolower (c1);
926 if (isalpha (c2))
927 c2 = tolower (c2);
928
929 if (c1 != '\0' && c1 == c2)
930 continue;
931
932 return (c1 - c2);
933 }
934}
935#endif
936
937#if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI
938
939/* If we don't have strncasecmp() (from POSIX), or anything that can
940 substitute for it, define our own version. */
941
942int
943strncasecmp (const char *s1, const char *s2, int n)
944{
945 while (n-- > 0)
946 {
947 int c1 = (int) *(s1++);
948 int c2 = (int) *(s2++);
949
950 if (isalpha (c1))
951 c1 = tolower (c1);
952 if (isalpha (c2))
953 c2 = tolower (c2);
954
955 if (c1 != '\0' && c1 == c2)
956 continue;
957
958 return (c1 - c2);
959 }
960
961 return 0;
962}
963#endif
964
965
966#ifdef GETLOADAVG_PRIVILEGED
967
968#ifdef POSIX
969
970/* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
971 functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2,
972 for example) which claim to be POSIX.1 also have the BSD setreuid and
973 setregid functions, but they don't work as in BSD and only the POSIX.1
974 way works. */
975
976#undef HAVE_SETREUID
977#undef HAVE_SETREGID
978
979#else /* Not POSIX. */
980
981/* Some POSIX.1 systems have the seteuid and setegid functions. In a
982 POSIX-like system, they are the best thing to use. However, some
983 non-POSIX systems have them too but they do not work in the POSIX style
984 and we must use setreuid and setregid instead. */
985
986#undef HAVE_SETEUID
987#undef HAVE_SETEGID
988
989#endif /* POSIX. */
990
991#ifndef HAVE_UNISTD_H
992extern int getuid (), getgid (), geteuid (), getegid ();
993extern int setuid (), setgid ();
994#ifdef HAVE_SETEUID
995extern int seteuid ();
996#else
997#ifdef HAVE_SETREUID
998extern int setreuid ();
999#endif /* Have setreuid. */
1000#endif /* Have seteuid. */
1001#ifdef HAVE_SETEGID
1002extern int setegid ();
1003#else
1004#ifdef HAVE_SETREGID
1005extern int setregid ();
1006#endif /* Have setregid. */
1007#endif /* Have setegid. */
1008#endif /* No <unistd.h>. */
1009
1010/* Keep track of the user and group IDs for user- and make- access. */
1011static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
1012#define access_inited (user_uid != -1)
1013static enum { make, user } current_access;
1014
1015
1016/* Under -d, write a message describing the current IDs. */
1017
1018static void
1019log_access (const char *flavor)
1020{
1021 if (! ISDB (DB_JOBS))
1022 return;
1023
1024 /* All the other debugging messages go to stdout,
1025 but we write this one to stderr because it might be
1026 run in a child fork whose stdout is piped. */
1027
1028 fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
1029 flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
1030 (unsigned long) getegid (), (unsigned long) getgid ());
1031 fflush (stderr);
1032}
1033
1034
1035static void
1036init_access (void)
1037{
1038#ifndef VMS
1039 user_uid = getuid ();
1040 user_gid = getgid ();
1041
1042 make_uid = geteuid ();
1043 make_gid = getegid ();
1044
1045 /* Do these ever fail? */
1046 if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
1047 pfatal_with_name ("get{e}[gu]id");
1048
1049 log_access (_("Initialized access"));
1050
1051 current_access = make;
1052#endif
1053}
1054
1055#endif /* GETLOADAVG_PRIVILEGED */
1056
1057/* Give the process appropriate permissions for access to
1058 user data (i.e., to stat files, or to spawn a child process). */
1059void
1060user_access (void)
1061{
1062#ifdef GETLOADAVG_PRIVILEGED
1063
1064 if (!access_inited)
1065 init_access ();
1066
1067 if (current_access == user)
1068 return;
1069
1070 /* We are in "make access" mode. This means that the effective user and
1071 group IDs are those of make (if it was installed setuid or setgid).
1072 We now want to set the effective user and group IDs to the real IDs,
1073 which are the IDs of the process that exec'd make. */
1074
1075#ifdef HAVE_SETEUID
1076
1077 /* Modern systems have the seteuid/setegid calls which set only the
1078 effective IDs, which is ideal. */
1079
1080 if (seteuid (user_uid) < 0)
1081 pfatal_with_name ("user_access: seteuid");
1082
1083#else /* Not HAVE_SETEUID. */
1084
1085#ifndef HAVE_SETREUID
1086
1087 /* System V has only the setuid/setgid calls to set user/group IDs.
1088 There is an effective ID, which can be set by setuid/setgid.
1089 It can be set (unless you are root) only to either what it already is
1090 (returned by geteuid/getegid, now in make_uid/make_gid),
1091 the real ID (return by getuid/getgid, now in user_uid/user_gid),
1092 or the saved set ID (what the effective ID was before this set-ID
1093 executable (make) was exec'd). */
1094
1095 if (setuid (user_uid) < 0)
1096 pfatal_with_name ("user_access: setuid");
1097
1098#else /* HAVE_SETREUID. */
1099
1100 /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
1101 They may be set to themselves or each other. So you have two alternatives
1102 at any one time. If you use setuid/setgid, the effective will be set to
1103 the real, leaving only one alternative. Using setreuid/setregid, however,
1104 you can toggle between your two alternatives by swapping the values in a
1105 single setreuid or setregid call. */
1106
1107 if (setreuid (make_uid, user_uid) < 0)
1108 pfatal_with_name ("user_access: setreuid");
1109
1110#endif /* Not HAVE_SETREUID. */
1111#endif /* HAVE_SETEUID. */
1112
1113#ifdef HAVE_SETEGID
1114 if (setegid (user_gid) < 0)
1115 pfatal_with_name ("user_access: setegid");
1116#else
1117#ifndef HAVE_SETREGID
1118 if (setgid (user_gid) < 0)
1119 pfatal_with_name ("user_access: setgid");
1120#else
1121 if (setregid (make_gid, user_gid) < 0)
1122 pfatal_with_name ("user_access: setregid");
1123#endif
1124#endif
1125
1126 current_access = user;
1127
1128 log_access (_("User access"));
1129
1130#endif /* GETLOADAVG_PRIVILEGED */
1131}
1132
1133/* Give the process appropriate permissions for access to
1134 make data (i.e., the load average). */
1135void
1136make_access (void)
1137{
1138#ifdef GETLOADAVG_PRIVILEGED
1139
1140 if (!access_inited)
1141 init_access ();
1142
1143 if (current_access == make)
1144 return;
1145
1146 /* See comments in user_access, above. */
1147
1148#ifdef HAVE_SETEUID
1149 if (seteuid (make_uid) < 0)
1150 pfatal_with_name ("make_access: seteuid");
1151#else
1152#ifndef HAVE_SETREUID
1153 if (setuid (make_uid) < 0)
1154 pfatal_with_name ("make_access: setuid");
1155#else
1156 if (setreuid (user_uid, make_uid) < 0)
1157 pfatal_with_name ("make_access: setreuid");
1158#endif
1159#endif
1160
1161#ifdef HAVE_SETEGID
1162 if (setegid (make_gid) < 0)
1163 pfatal_with_name ("make_access: setegid");
1164#else
1165#ifndef HAVE_SETREGID
1166 if (setgid (make_gid) < 0)
1167 pfatal_with_name ("make_access: setgid");
1168#else
1169 if (setregid (user_gid, make_gid) < 0)
1170 pfatal_with_name ("make_access: setregid");
1171#endif
1172#endif
1173
1174 current_access = make;
1175
1176 log_access (_("Make access"));
1177
1178#endif /* GETLOADAVG_PRIVILEGED */
1179}
1180
1181/* Give the process appropriate permissions for a child process.
1182 This is like user_access, but you can't get back to make_access. */
1183void
1184child_access (void)
1185{
1186#ifdef GETLOADAVG_PRIVILEGED
1187
1188 if (!access_inited)
1189 abort ();
1190
1191 /* Set both the real and effective UID and GID to the user's.
1192 They cannot be changed back to make's. */
1193
1194#ifndef HAVE_SETREUID
1195 if (setuid (user_uid) < 0)
1196 pfatal_with_name ("child_access: setuid");
1197#else
1198 if (setreuid (user_uid, user_uid) < 0)
1199 pfatal_with_name ("child_access: setreuid");
1200#endif
1201
1202#ifndef HAVE_SETREGID
1203 if (setgid (user_gid) < 0)
1204 pfatal_with_name ("child_access: setgid");
1205#else
1206 if (setregid (user_gid, user_gid) < 0)
1207 pfatal_with_name ("child_access: setregid");
1208#endif
1209
1210 log_access (_("Child access"));
1211
1212#endif /* GETLOADAVG_PRIVILEGED */
1213}
1214
1215
1216#ifdef NEED_GET_PATH_MAX
1217unsigned int
1218get_path_max (void)
1219{
1220 static unsigned int value;
1221
1222 if (value == 0)
1223 {
1224 long int x = pathconf ("/", _PC_PATH_MAX);
1225 if (x > 0)
1226 value = x;
1227 else
1228 return MAXPATHLEN;
1229 }
1230
1231 return value;
1232}
1233#endif
1234
1235
1236
1237/* This code is stolen from gnulib.
1238 If/when we abandon the requirement to work with K&R compilers, we can
1239 remove this (and perhaps other parts of GNU make!) and migrate to using
1240 gnulib directly.
1241
1242 This is called only through atexit(), which means die() has already been
1243 invoked. So, call exit() here directly. Apparently that works...?
1244*/
1245
1246/* Close standard output, exiting with status 'exit_failure' on failure.
1247 If a program writes *anything* to stdout, that program should close
1248 stdout and make sure that it succeeds before exiting. Otherwise,
1249 suppose that you go to the extreme of checking the return status
1250 of every function that does an explicit write to stdout. The last
1251 printf can succeed in writing to the internal stream buffer, and yet
1252 the fclose(stdout) could still fail (due e.g., to a disk full error)
1253 when it tries to write out that buffered data. Thus, you would be
1254 left with an incomplete output file and the offending program would
1255 exit successfully. Even calling fflush is not always sufficient,
1256 since some file systems (NFS and CODA) buffer written/flushed data
1257 until an actual close call.
1258
1259 Besides, it's wasteful to check the return value from every call
1260 that writes to stdout -- just let the internal stream state record
1261 the failure. That's what the ferror test is checking below.
1262
1263 It's important to detect such failures and exit nonzero because many
1264 tools (most notably `make' and other build-management systems) depend
1265 on being able to detect failure in other tools via their exit status. */
1266
1267void
1268close_stdout (void)
1269{
1270 int prev_fail = ferror (stdout);
1271 int fclose_fail = fclose (stdout);
1272
1273 if (prev_fail || fclose_fail)
1274 {
1275 if (fclose_fail)
1276 error (NILF, _("write error: %s"), strerror (errno));
1277 else
1278 error (NILF, _("write error"));
1279 exit (EXIT_FAILURE);
1280 }
1281}
1282
1283#ifdef CONFIG_WITH_PRINT_STATS_SWITCH
1284/* Print heap statistics if supported by the platform. */
1285void
1286print_heap_stats (void)
1287{
1288 /* Darwin / Mac OS X */
1289# ifdef __APPLE__
1290 malloc_statistics_t s;
1291
1292 malloc_zone_statistics (NULL, &s);
1293 printf (_("\n# CRT Heap: %u bytes in use, in %u blocks, avg %u bytes/block\n"),
1294 (unsigned)s.size_in_use, (unsigned)s.blocks_in_use,
1295 (unsigned)(s.size_in_use / s.blocks_in_use));
1296 printf (_("# %u bytes max in use (high water mark)\n"),
1297 (unsigned)s.max_size_in_use);
1298 printf (_("# %u bytes reserved, %u bytes free (estimate)\n"),
1299 (unsigned)s.size_allocated,
1300 (unsigned)(s.size_allocated - s.size_in_use));
1301# endif /* __APPLE__ */
1302
1303 /* MSC / Windows */
1304# ifdef _MSC_VER
1305 unsigned int blocks_used = 0;
1306 unsigned int bytes_used = 0;
1307 unsigned int blocks_avail = 0;
1308 unsigned int bytes_avail = 0;
1309 _HEAPINFO hinfo;
1310
1311 memset (&hinfo, '\0', sizeof (hinfo));
1312 while (_heapwalk(&hinfo) == _HEAPOK)
1313 {
1314 if (hinfo._useflag == _USEDENTRY)
1315 {
1316 blocks_used++;
1317 bytes_used += hinfo._size;
1318 }
1319 else
1320 {
1321 blocks_avail++;
1322 bytes_avail += hinfo._size;
1323 }
1324 }
1325
1326 printf (_("\n# CRT Heap: %u bytes in use, in %u blocks, avg %u bytes/block\n"),
1327 bytes_used, blocks_used, bytes_used / blocks_used);
1328 printf (_("# %u bytes avail, in %u blocks, avg %u bytes/block\n"),
1329 bytes_avail, blocks_avail, bytes_avail / blocks_avail);
1330# endif /* _MSC_VER */
1331
1332 /* Darwin Libc sources indicates that something like this may be
1333 found in GLIBC, however, it's not in any current one... */
1334# if 0 /* ??? */
1335 struct mstats m;
1336
1337 m = mstats();
1338 printf (_("\n# CRT Heap: %zu blocks / %zu bytes in use, %zu blocks / %zu bytes free\n"),
1339 m.chunks_used, m.bytes_used, m.chunks_free, m.bytes_free);
1340 printf (_("# %zu bytes reserved\n"),
1341 m.bytes_total);
1342# endif /* ??? */
1343
1344 /* XVID2/XPG mallinfo (displayed per GLIBC documentation). */
1345# if defined(__GLIBC__) || defined(HAVE_MALLINFO)
1346 struct mallinfo m;
1347
1348 m = mallinfo();
1349 printf (_("\n# CRT Heap: %d bytes in use, %d bytes free\n"),
1350 m.uordblks, m.fordblks);
1351
1352 printf (_("# # free chunks=%d, # fastbin blocks=%d\n"),
1353 m.ordblks, m.smblks);
1354 printf (_("# # mapped regions=%d, space in mapped regions=%d\n"),
1355 m.hblks, m.hblkhd);
1356 printf (_("# non-mapped space allocated from system=%d\n"),
1357 m.arena);
1358 printf (_("# maximum total allocated space=%d\n"),
1359 m.usmblks);
1360 printf (_("# top-most releasable space=%d\n"),
1361 m.keepcost);
1362# endif /* __GLIBC__ || HAVE_MALLINFO */
1363
1364# ifdef CONFIG_WITH_MAKE_STATS
1365 printf(_("# %lu malloc calls, %lu realloc calls\n"),
1366 make_stats_allocations, make_stats_reallocations);
1367 printf(_("# %lu MBs alloc sum, not counting freed, add pinch of salt\n"), /* XXX: better wording */
1368 make_stats_allocated / (1024*1024));
1369# endif
1370
1371 /* XXX: windows */
1372}
1373#endif /* CONFIG_WITH_PRINT_STATS_SWITCH */
1374
1375#ifdef CONFIG_WITH_PRINT_TIME_SWITCH
1376/* Get a nanosecond timestamp, from a monotonic time source if
1377 possible. Returns -1 after calling error() on failure. */
1378
1379big_int
1380nano_timestamp (void)
1381{
1382 big_int ts;
1383#if defined (WINDOWS32)
1384 static int s_state = -1;
1385 static LARGE_INTEGER s_freq;
1386
1387 if (s_state == -1)
1388 s_state = QueryPerformanceFrequency (&s_freq);
1389 if (s_state)
1390 {
1391 LARGE_INTEGER pc;
1392 if (!QueryPerformanceCounter (&pc))
1393 {
1394 s_state = 0;
1395 return nano_timestamp ();
1396 }
1397 ts = (big_int)((long double)pc.QuadPart / (long double)s_freq.QuadPart * 1000000000);
1398 }
1399 else
1400 {
1401 /* fall back to low resolution system time. */
1402 LARGE_INTEGER bigint;
1403 FILETIME ft = {0,0};
1404 GetSystemTimeAsFileTime (&ft);
1405 bigint.u.LowPart = ft.dwLowDateTime;
1406 bigint.u.HighPart = ft.dwLowDateTime;
1407 ts = bigint.QuadPart * 100;
1408 }
1409
1410#elif HAVE_GETTIMEOFDAY
1411/* FIXME: Linux and others have the realtime clock_* api, detect and use it. */
1412 struct timeval tv;
1413 if (!gettimeofday (&tv, NULL))
1414 ts = (big_int)tv.tv_sec * 1000000000
1415 + tv.tv_usec * 1000;
1416 else
1417 {
1418 error (NILF, _("gettimeofday failed"));
1419 ts = -1;
1420 }
1421
1422#else
1423# error "PORTME"
1424#endif
1425
1426 return ts;
1427}
1428
1429/* Formats the elapsed time (nano seconds) in the manner easiest
1430 to read, with millisecond percision for larger numbers. */
1431
1432int
1433format_elapsed_nano (char *buf, size_t size, big_int ts)
1434{
1435 unsigned sz;
1436 if (ts < 1000)
1437 sz = sprintf (buf, "%uns", (unsigned)ts);
1438 else if (ts < 100000)
1439 sz = sprintf (buf, "%u.%03uus",
1440 (unsigned)(ts / 1000),
1441 (unsigned)(ts % 1000));
1442 else
1443 {
1444 ts /= 1000;
1445 if (ts < 1000)
1446 sz = sprintf (buf, "%uus", (unsigned)ts);
1447 else if (ts < 100000)
1448 sz = sprintf (buf, "%u.%03ums",
1449 (unsigned)(ts / 1000),
1450 (unsigned)(ts % 1000));
1451 else
1452 {
1453 ts /= 1000;
1454 if (ts < BIG_INT_C(60000))
1455 sz = sprintf (buf,
1456 "%u.%03us",
1457 (unsigned)(ts / 1000),
1458 (unsigned)(ts % 1000));
1459 else
1460 sz = sprintf (buf,
1461 "%um%u.%03us",
1462 (unsigned)( ts / BIG_INT_C(60000)),
1463 (unsigned)((ts % BIG_INT_C(60000)) / 1000),
1464 (unsigned)((ts % BIG_INT_C(60000)) % 1000));
1465 }
1466 }
1467 if (sz >= size)
1468 fatal (NILF, _("format_elapsed_nano buffer overflow: %u written, %lu buffer"),
1469 sz, (unsigned long)size);
1470 return sz;
1471}
1472#endif /* CONFIG_WITH_PRINT_TIME_SWITCH */
Note: See TracBrowser for help on using the repository browser.

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