Changeset 3140 for trunk/src/kmk/misc.c
- Timestamp:
- Mar 14, 2018, 10:28:10 PM (7 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk
-
Property svn:mergeinfo
set to
/vendor/gnumake/current merged eligible
-
Property svn:mergeinfo
set to
-
trunk/src/kmk/misc.c
r3068 r3140 1 1 /* Miscellaneous generic support functions for GNU Make. 2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 4 2010 Free Software Foundation, Inc. 2 Copyright (C) 1988-2016 Free Software Foundation, Inc. 5 3 This file is part of GNU Make. 6 4 … … 17 15 this program. If not, see <http://www.gnu.org/licenses/>. */ 18 16 19 #include "make.h" 17 #include "makeint.h" 18 #include "filedef.h" 20 19 #include "dep.h" 21 20 #include "debug.h" 21 22 /* GNU make no longer supports pre-ANSI89 environments. */ 23 24 #include <stdarg.h> 25 26 #ifdef HAVE_FCNTL_H 27 # include <fcntl.h> 28 #else 29 # include <sys/file.h> 30 #endif 31 22 32 #if defined (CONFIG_WITH_VALUE_LENGTH) || defined (CONFIG_WITH_ALLOC_CACHES) 23 33 # include <assert.h> … … 31 41 # endif 32 42 #endif 33 34 43 #if defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_PRINT_TIME_SWITCH) 35 44 # ifdef WINDOWS32 … … 48 57 #endif 49 58 50 /* Variadic functions. We go through contortions to allow proper function51 prototypes for both ANSI and pre-ANSI C compilers, and also for those52 which support stdarg.h vs. varargs.h, and finally those which have53 vfprintf(), etc. and those who have _doprnt... or nothing.54 55 This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and56 VA_END macros used here since we have multiple print functions. */57 58 #if USE_VARIADIC59 # if HAVE_STDARG_H60 # include <stdarg.h>61 # define VA_START(args, lastarg) va_start(args, lastarg)62 # else63 # include <varargs.h>64 # define VA_START(args, lastarg) va_start(args)65 # endif66 # if HAVE_VPRINTF67 # define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))68 # else69 # define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))70 # endif71 # define VA_END(args) va_end(args)72 #else73 /* We can't use any variadic interface! */74 # define va_alist a1, a2, a3, a4, a5, a6, a7, a875 # 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 #endif80 81 59 82 60 /* Compare strings *S1 and *S2. … … 108 86 #endif 109 87 { 110 register char *in, *out, *p; 111 register int backslash; 112 register unsigned int bs_write; 88 char *in, *out, *p; 113 89 114 90 #ifndef CONFIG_WITH_VALUE_LENGTH … … 143 119 { 144 120 /* BS_WRITE gets the number of quoted backslashes at 145 146 147 backslash = 0;148 bs_write = 0;121 the end just before IN, and BACKSLASH gets nonzero 122 if the next character is quoted. */ 123 unsigned int backslash = 0; 124 unsigned int bs_write = 0; 149 125 for (p = in - 1; p >= line && *p == '\\'; --p) 150 151 152 153 154 155 156 157 158 159 126 { 127 if (backslash) 128 ++bs_write; 129 backslash = !backslash; 130 131 /* It should be impossible to go back this far without exiting, 132 but if we do, we can't get the right answer. */ 133 if (in == out - 1) 134 abort (); 135 } 160 136 161 137 /* Output the appropriate number of backslashes. */ 162 138 while (bs_write-- > 0) 163 139 *out++ = '\\'; 164 140 165 141 /* Skip the newline. */ 166 142 ++in; 167 143 168 /* If the newline is escaped, discard following whitespace leaving just169 one space. POSIX requires that each backslash/newline/following170 whitespace sequence be reduced to a single space. */171 144 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 } 145 { 146 /* Backslash/newline handling: 147 In traditional GNU make all trailing whitespace, consecutive 148 backslash/newlines, and any leading non-newline whitespace on the 149 next line is reduced to a single space. 150 In POSIX, each backslash/newline and is replaced by a space. */ 151 while (ISBLANK (*in)) 152 ++in; 153 if (! posix_pedantic) 154 while (out > line && ISBLANK (out[-1])) 155 --out; 156 *out++ = ' '; 157 } 179 158 else 180 181 159 /* If the newline isn't quoted, put it in the output. */ 160 *out++ = '\n'; 182 161 183 162 /* Now copy the following line to the output. 184 163 Stop when we find backslashes followed by a newline. */ 185 164 while (*in != '\0') 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 165 if (*in == '\\') 166 { 167 p = in + 1; 168 while (*p == '\\') 169 ++p; 170 if (*p == '\n') 171 { 172 in = p; 173 break; 174 } 175 while (in < p) 176 *out++ = *in++; 177 } 178 else 179 *out++ = *in++; 201 180 } 202 181 … … 224 203 225 204 const char * 226 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H227 205 concat (unsigned int num, ...) 228 #else229 concat (num, va_alist)230 unsigned int num;231 va_dcl232 #endif233 206 { 234 207 static unsigned int rlen = 0; 235 208 static char *result = NULL; 236 unsigned int ri = 0; /* bird: must be unsigned */ 237 238 #if USE_VARIADIC 209 unsigned int ri = 0; 239 210 va_list args; 240 #endif 241 242 VA_START (args, num); 211 212 va_start (args, num); 243 213 244 214 while (num-- > 0) 245 215 { 246 216 const char *s = va_arg (args, const char *); 247 unsigned int l = s ? strlen (s) : 0;217 unsigned int l = xstrlen (s); 248 218 249 219 if (l == 0) … … 260 230 } 261 231 262 VA_END(args);232 va_end (args); 263 233 264 234 /* Get some more memory if we don't have enough space for the … … 276 246 277 247 278 /* Print a message on stdout. */279 280 void281 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H282 message (int prefix, const char *fmt, ...)283 #else284 message (prefix, fmt, va_alist)285 int prefix;286 const char *fmt;287 va_dcl288 #endif289 {290 #if USE_VARIADIC291 va_list args;292 #endif293 294 log_working_directory (1);295 296 if (fmt != 0)297 {298 #ifdef KBUILD_OS_WINDOWS299 char szMsg[16384];300 int cchMsg = 0;301 int cchUser;302 if (prefix)303 {304 if (makelevel == 0)305 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s: ", program);306 else307 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s[%u]: ", program, makelevel);308 }309 VA_START (args, fmt);310 cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);311 VA_END (args);312 if ( cchMsg < sizeof(szMsg)313 && cchUser >= 0)314 {315 extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);316 szMsg[cchMsg++] = '\n';317 maybe_con_fwrite(szMsg, cchMsg, 1, stdout);318 }319 else320 {321 #endif322 if (prefix)323 {324 if (makelevel == 0)325 printf ("%s: ", program);326 else327 printf ("%s[%u]: ", program, makelevel);328 }329 VA_START (args, fmt);330 VA_PRINTF (stdout, fmt, args);331 VA_END (args);332 putchar ('\n');333 #ifdef KBUILD_OS_WINDOWS334 }335 #endif336 }337 338 fflush (stdout);339 }340 341 /* Print an error message. */342 343 void344 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H345 error (const struct floc *flocp, const char *fmt, ...)346 #else347 error (flocp, fmt, va_alist)348 const struct floc *flocp;349 const char *fmt;350 va_dcl351 #endif352 {353 #if USE_VARIADIC354 va_list args;355 #endif356 #ifdef KMK357 char szMsg[16384];358 int cchMsg = 0;359 int cchUser;360 #endif361 362 log_working_directory (1);363 364 #ifdef KMK /* Try avoid getting the error split by child output. */365 if (flocp && flocp->filenm)366 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s:%lu: ", flocp->filenm, flocp->lineno);367 else if (makelevel == 0)368 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s: ", program);369 else370 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s[%u]: ", program, makelevel);371 372 VA_START (args, fmt);373 cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);374 VA_END (args);375 if ( cchMsg < (int)sizeof(szMsg)376 && cchUser >= 0)377 {378 extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);379 szMsg[cchMsg++] = '\n';380 maybe_con_fwrite(szMsg, cchMsg, 1, stderr);381 }382 else383 {384 #endif /* KMK */385 386 if (flocp && flocp->filenm)387 fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);388 else if (makelevel == 0)389 fprintf (stderr, "%s: ", program);390 else391 fprintf (stderr, "%s[%u]: ", program, makelevel);392 393 VA_START(args, fmt);394 VA_PRINTF (stderr, fmt, args);395 VA_END (args);396 397 putc ('\n', stderr);398 #ifdef KMK399 }400 #endif401 fflush (stderr);402 }403 404 /* Print an error message and exit. */405 406 void407 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H408 fatal (const struct floc *flocp, const char *fmt, ...)409 #else410 fatal (flocp, fmt, va_alist)411 const struct floc *flocp;412 const char *fmt;413 va_dcl414 #endif415 {416 #if USE_VARIADIC417 va_list args;418 #endif419 #ifdef KMK420 char szMsg[16384];421 int cchMsg = 0;422 int cchUser;423 const char *pszStop = _(". Stop.\n");424 int cchStop = (int)strlen(pszStop);425 #endif426 427 log_working_directory (1);428 429 #ifdef KMK /* Try avoid getting the error split by child output. */430 if (flocp && flocp->filenm)431 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s:%lu: *** ", flocp->filenm, flocp->lineno);432 else if (makelevel == 0)433 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s: *** ", program);434 else435 cchMsg = snprintf (szMsg, sizeof(szMsg), "%s[%u]: *** ", program, makelevel);436 437 VA_START (args, fmt);438 cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);439 VA_END (args);440 if ( cchMsg + cchStop <= (int)sizeof(szMsg)441 && cchUser >= 0)442 {443 extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);444 memcpy(&szMsg[cchMsg], pszStop, cchStop);445 cchMsg += cchStop;446 maybe_con_fwrite(szMsg, cchMsg, 1, stderr);447 }448 else449 {450 #endif /* KMK */451 if (flocp && flocp->filenm)452 fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);453 else if (makelevel == 0)454 fprintf (stderr, "%s: *** ", program);455 else456 fprintf (stderr, "%s[%u]: *** ", program, makelevel);457 458 VA_START(args, fmt);459 VA_PRINTF (stderr, fmt, args);460 VA_END (args);461 462 fputs (_(". Stop.\n"), stderr);463 #ifdef KMK464 }465 #endif466 467 die (2);468 }469 248 470 249 #ifndef HAVE_STRERROR 471 472 #undef strerror 473 250 #undef strerror 474 251 char * 475 252 strerror (int errnum) … … 488 265 } 489 266 #endif 490 491 /* Print an error message from errno. */492 493 void494 perror_with_name (const char *str, const char *name)495 {496 error (NILF, _("%s%s: %s"), str, name, strerror (errno));497 }498 499 /* Print an error message from errno and exit. */500 501 void502 pfatal_with_name (const char *name)503 {504 fatal (NILF, _("%s: %s"), name, strerror (errno));505 506 /* NOTREACHED */507 }508 267 509 268 … … 524 283 void *result = malloc (size ? size : 1); 525 284 if (result == 0) 526 fatal (NILF, _("virtual memory exhausted"));285 OUT_OF_MEM(); 527 286 528 287 #ifdef CONFIG_WITH_MAKE_STATS … … 543 302 void *result = calloc (size ? size : 1, 1); 544 303 if (result == 0) 545 fatal (NILF, _("virtual memory exhausted"));304 OUT_OF_MEM(); 546 305 547 306 #ifdef CONFIG_WITH_MAKE_STATS … … 574 333 result = ptr ? realloc (ptr, size) : malloc (size); 575 334 if (result == 0) 576 fatal (NILF, _("virtual memory exhausted"));335 OUT_OF_MEM(); 577 336 578 337 #ifdef CONFIG_WITH_MAKE_STATS … … 598 357 599 358 if (result == 0) 600 fatal (NILF, _("virtual memory exhausted"));359 OUT_OF_MEM(); 601 360 602 361 #ifdef CONFIG_WITH_MAKE_STATS … … 624 383 result = strndup (str, length); 625 384 if (result == 0) 626 fatal (NILF, _("virtual memory exhausted"));385 OUT_OF_MEM(); 627 386 #else 628 387 result = xmalloc (length + 1); … … 663 422 end_of_token (const char *s) 664 423 { 665 #if def KMK424 #if 0 /* @todo def KMK */ 666 425 for (;;) 667 426 { … … 685 444 686 445 #else 687 while (*s != '\0' && !isblank ((unsigned char)*s)) 688 ++s; 446 END_OF_TOKEN (s); 689 447 return (char *)s; 690 448 #endif 691 449 } 692 693 #ifdef WINDOWS32694 /*695 * Same as end_of_token, but take into account a stop character696 */697 char *698 end_of_token_w32 (const char *s, char stopchar)699 {700 const char *p = s;701 int backslash = 0;702 703 while (*p != '\0' && *p != stopchar704 && (backslash || !isblank ((unsigned char)*p)))705 {706 if (*p++ == '\\')707 {708 backslash = !backslash;709 while (*p == '\\')710 {711 backslash = !backslash;712 ++p;713 }714 }715 else716 backslash = 0;717 }718 719 return (char *)p;720 }721 #endif722 450 723 451 /* Return the address of the first nonwhitespace or null in the string S. */ … … 726 454 next_token (const char *s) 727 455 { 728 #if def KMK456 #if 0 /* @todo def KMK */ 729 457 for (;;) 730 458 { … … 748 476 749 477 #else /* !KMK */ 750 while (isblank ((unsigned char)*s)) 751 ++s; 478 NEXT_TOKEN (s); 752 479 return (char *)s; 753 480 #endif /* !KMK */ … … 932 659 933 660 934 /* Copy a chain of `struct dep'. For 2nd expansion deps, dup the name. */661 /* Copy a chain of 'struct dep'. For 2nd expansion deps, dup the name. */ 935 662 936 663 struct dep * … … 955 682 c->next = 0; 956 683 if (firstnew == 0) 957 684 firstnew = lastnew = c; 958 685 else 959 686 lastnew = lastnew->next = c; 960 687 961 688 d = d->next; … … 963 690 964 691 return firstnew; 965 }966 967 /* Free a chain of 'struct dep'. */968 969 void970 free_dep_chain (struct dep *d)971 {972 while (d != 0)973 {974 struct dep *df = d;975 d = d->next;976 free_dep (df);977 }978 692 } 979 693 … … 989 703 ns = ns->next; 990 704 #ifndef CONFIG_WITH_ALLOC_CACHES 991 free (t);705 free_ns (t); 992 706 #else 993 707 alloccache_free (&nameseq_cache, t); … … 997 711 998 712 713 #ifdef CONFIG_WITH_ALLOC_CACHES 714 715 void 716 free_dep_chain (struct dep *d) 717 { 718 while (d != 0) 719 { 720 struct dep *tofree = d; 721 d = d->next; 722 alloccache_free (&dep_cache, tofree); 723 } 724 } 725 726 void 727 free_goal_chain (struct goaldep *g) 728 { 729 while (g != 0) 730 { 731 struct goaldep *tofree = g; 732 g = g->next; 733 alloccache_free (&dep_cache, tofree); 734 } 735 } 736 737 #endif /* CONFIG_WITH_ALLOC_CACHES */ 738 739 999 740 1000 741 #if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI 1001 1002 742 /* If we don't have strcasecmp() (from POSIX), or anything that can substitute 1003 743 for it, define our own version. */ … … 1025 765 1026 766 #if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI 1027 1028 767 /* If we don't have strncasecmp() (from POSIX), or anything that can 1029 768 substitute for it, define our own version. */ … … 1053 792 1054 793 1055 #ifdef 794 #ifdef GETLOADAVG_PRIVILEGED 1056 795 1057 796 #ifdef POSIX … … 1066 805 #undef HAVE_SETREGID 1067 806 1068 #else 807 #else /* Not POSIX. */ 1069 808 1070 809 /* Some POSIX.1 systems have the seteuid and setegid functions. In a … … 1076 815 #undef HAVE_SETEGID 1077 816 1078 #endif 1079 1080 #ifndef 817 #endif /* POSIX. */ 818 819 #ifndef HAVE_UNISTD_H 1081 820 extern int getuid (), getgid (), geteuid (), getegid (); 1082 821 extern int setuid (), setgid (); … … 1084 823 extern int seteuid (); 1085 824 #else 1086 #ifdef 825 #ifdef HAVE_SETREUID 1087 826 extern int setreuid (); 1088 #endif 1089 #endif 827 #endif /* Have setreuid. */ 828 #endif /* Have seteuid. */ 1090 829 #ifdef HAVE_SETEGID 1091 830 extern int setegid (); 1092 831 #else 1093 #ifdef 832 #ifdef HAVE_SETREGID 1094 833 extern int setregid (); 1095 #endif 1096 #endif 1097 #endif 834 #endif /* Have setregid. */ 835 #endif /* Have setegid. */ 836 #endif /* No <unistd.h>. */ 1098 837 1099 838 /* Keep track of the user and group IDs for user- and make- access. */ 1100 839 static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1; 1101 #define access_inited(user_uid != -1)840 #define access_inited (user_uid != -1) 1102 841 static enum { make, user } current_access; 1103 842 … … 1116 855 1117 856 fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"), 1118 857 flavor, (unsigned long) geteuid (), (unsigned long) getuid (), 1119 858 (unsigned long) getegid (), (unsigned long) getgid ()); 1120 859 fflush (stderr); … … 1142 881 } 1143 882 1144 #endif 883 #endif /* GETLOADAVG_PRIVILEGED */ 1145 884 1146 885 /* Give the process appropriate permissions for access to … … 1149 888 user_access (void) 1150 889 { 1151 #ifdef 890 #ifdef GETLOADAVG_PRIVILEGED 1152 891 1153 892 if (!access_inited) … … 1162 901 which are the IDs of the process that exec'd make. */ 1163 902 1164 #ifdef 903 #ifdef HAVE_SETEUID 1165 904 1166 905 /* Modern systems have the seteuid/setegid calls which set only the … … 1170 909 pfatal_with_name ("user_access: seteuid"); 1171 910 1172 #else 1173 1174 #ifndef 911 #else /* Not HAVE_SETEUID. */ 912 913 #ifndef HAVE_SETREUID 1175 914 1176 915 /* System V has only the setuid/setgid calls to set user/group IDs. … … 1185 924 pfatal_with_name ("user_access: setuid"); 1186 925 1187 #else 926 #else /* HAVE_SETREUID. */ 1188 927 1189 928 /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs. … … 1197 936 pfatal_with_name ("user_access: setreuid"); 1198 937 1199 #endif 1200 #endif 1201 1202 #ifdef 938 #endif /* Not HAVE_SETREUID. */ 939 #endif /* HAVE_SETEUID. */ 940 941 #ifdef HAVE_SETEGID 1203 942 if (setegid (user_gid) < 0) 1204 943 pfatal_with_name ("user_access: setegid"); 1205 944 #else 1206 #ifndef 945 #ifndef HAVE_SETREGID 1207 946 if (setgid (user_gid) < 0) 1208 947 pfatal_with_name ("user_access: setgid"); … … 1217 956 log_access (_("User access")); 1218 957 1219 #endif 958 #endif /* GETLOADAVG_PRIVILEGED */ 1220 959 } 1221 960 … … 1225 964 make_access (void) 1226 965 { 1227 #ifdef 966 #ifdef GETLOADAVG_PRIVILEGED 1228 967 1229 968 if (!access_inited) … … 1235 974 /* See comments in user_access, above. */ 1236 975 1237 #ifdef 976 #ifdef HAVE_SETEUID 1238 977 if (seteuid (make_uid) < 0) 1239 978 pfatal_with_name ("make_access: seteuid"); 1240 979 #else 1241 #ifndef 980 #ifndef HAVE_SETREUID 1242 981 if (setuid (make_uid) < 0) 1243 982 pfatal_with_name ("make_access: setuid"); … … 1248 987 #endif 1249 988 1250 #ifdef 989 #ifdef HAVE_SETEGID 1251 990 if (setegid (make_gid) < 0) 1252 991 pfatal_with_name ("make_access: setegid"); 1253 992 #else 1254 #ifndef 993 #ifndef HAVE_SETREGID 1255 994 if (setgid (make_gid) < 0) 1256 995 pfatal_with_name ("make_access: setgid"); … … 1265 1004 log_access (_("Make access")); 1266 1005 1267 #endif 1006 #endif /* GETLOADAVG_PRIVILEGED */ 1268 1007 } 1269 1008 … … 1273 1012 child_access (void) 1274 1013 { 1275 #ifdef 1014 #ifdef GETLOADAVG_PRIVILEGED 1276 1015 1277 1016 if (!access_inited) … … 1281 1020 They cannot be changed back to make's. */ 1282 1021 1283 #ifndef 1022 #ifndef HAVE_SETREUID 1284 1023 if (setuid (user_uid) < 0) 1285 1024 pfatal_with_name ("child_access: setuid"); … … 1289 1028 #endif 1290 1029 1291 #ifndef 1030 #ifndef HAVE_SETREGID 1292 1031 if (setgid (user_gid) < 0) 1293 1032 pfatal_with_name ("child_access: setgid"); … … 1299 1038 log_access (_("Child access")); 1300 1039 1301 #endif /* GETLOADAVG_PRIVILEGED */ 1302 } 1303 1040 #endif /* GETLOADAVG_PRIVILEGED */ 1041 } 1304 1042 1305 1043 #ifdef NEED_GET_PATH_MAX … … 1313 1051 long int x = pathconf ("/", _PC_PATH_MAX); 1314 1052 if (x > 0) 1315 1053 value = x; 1316 1054 else 1317 1055 return MAXPATHLEN; 1318 1056 } 1319 1057 … … 1321 1059 } 1322 1060 #endif 1323 1324 1325 1326 /* This code is stolen from gnulib.1327 If/when we abandon the requirement to work with K&R compilers, we can1328 remove this (and perhaps other parts of GNU make!) and migrate to using1329 gnulib directly.1330 1331 This is called only through atexit(), which means die() has already been1332 invoked. So, call exit() here directly. Apparently that works...?1333 */1334 1335 /* Close standard output, exiting with status 'exit_failure' on failure.1336 If a program writes *anything* to stdout, that program should close1337 stdout and make sure that it succeeds before exiting. Otherwise,1338 suppose that you go to the extreme of checking the return status1339 of every function that does an explicit write to stdout. The last1340 printf can succeed in writing to the internal stream buffer, and yet1341 the fclose(stdout) could still fail (due e.g., to a disk full error)1342 when it tries to write out that buffered data. Thus, you would be1343 left with an incomplete output file and the offending program would1344 exit successfully. Even calling fflush is not always sufficient,1345 since some file systems (NFS and CODA) buffer written/flushed data1346 until an actual close call.1347 1348 Besides, it's wasteful to check the return value from every call1349 that writes to stdout -- just let the internal stream state record1350 the failure. That's what the ferror test is checking below.1351 1352 It's important to detect such failures and exit nonzero because many1353 tools (most notably `make' and other build-management systems) depend1354 on being able to detect failure in other tools via their exit status. */1355 1356 void1357 close_stdout (void)1358 {1359 int prev_fail = ferror (stdout);1360 int fclose_fail = fclose (stdout);1361 1362 if (prev_fail || fclose_fail)1363 {1364 if (fclose_fail)1365 error (NILF, _("write error: %s"), strerror (errno));1366 else1367 error (NILF, _("write error"));1368 exit (EXIT_FAILURE);1369 }1370 }1371 1061 1372 1062 #ifdef CONFIG_WITH_PRINT_STATS_SWITCH … … 1505 1195 else 1506 1196 { 1507 error (NILF, _("gettimeofday failed"));1197 O (error, NILF, _("gettimeofday failed")); 1508 1198 ts = -1; 1509 1199 } … … 1555 1245 } 1556 1246 if (sz >= size) 1557 fatal (NILF, _("format_elapsed_nano buffer overflow: %u written, %lu buffer"),1558 1247 ONN (fatal, NILF, _("format_elapsed_nano buffer overflow: %u written, %lu buffer"), 1248 sz, (unsigned long)size); 1559 1249 return sz; 1560 1250 } 1561 1251 #endif /* CONFIG_WITH_PRINT_TIME_SWITCH */ 1252
Note:
See TracChangeset
for help on using the changeset viewer.