Bug Summary

File:main.c
Location:line 507, column 3
Description:Potential memory leak

Annotated Source Code

1/*
2
3Copyright (c) 1993, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#include "def.h"
28#ifdef hpux
29#define sigvec sigvector
30#endif /* hpux */
31
32#ifdef X_POSIX_C_SOURCE
33#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
34#include <signal.h>
35#undef _POSIX_C_SOURCE
36#else
37#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
38#include <signal.h>
39#else
40#define _POSIX_SOURCE
41#include <signal.h>
42#undef _POSIX_SOURCE
43#endif
44#endif
45
46#include <stdarg.h>
47
48#ifdef __sun
49# include <sys/utsname.h>
50#endif
51
52#ifdef DEBUG
53int _debugmask;
54#endif
55
56/* #define DEBUG_DUMP */
57#ifdef DEBUG_DUMP
58#define DBG_PRINT(file, fmt, args) fprintf(file, fmt, args)
59#else
60#define DBG_PRINT(file, fmt, args) /* empty */
61#endif
62
63#define DASH_INC_PRE"#include \"" "#include \""
64#define DASH_INC_POST"\"" "\""
65
66const char *ProgramName;
67
68const char * const directives[] = {
69 "if",
70 "ifdef",
71 "ifndef",
72 "else",
73 "endif",
74 "define",
75 "undef",
76 "include",
77 "line",
78 "pragma",
79 "error",
80 "ident",
81 "sccs",
82 "elif",
83 "eject",
84 "warning",
85 "include_next",
86 NULL((void *)0)
87};
88
89#include "imakemdep.h"
90
91struct inclist inclist[ MAXFILES2048 ],
92 *inclistp = inclist,
93 *inclistnext = inclist,
94 maininclist;
95
96static char *filelist[ MAXFILES2048 ];
97const char *includedirs[ MAXDIRS64 + 1 ],
98 **includedirsnext = includedirs;
99char *notdotdot[ MAXDIRS64 ];
100static int cmdinc_count = 0;
101static char *cmdinc_list[ 2 * MAXINCFILES128 ];
102const char *objprefix = "";
103const char *objsuffix = OBJSUFFIX".o";
104static const char *startat = "# DO NOT DELETE";
105int width = 78;
106static boolean append = FALSE0;
107boolean printed = FALSE0;
108boolean verbose = FALSE0;
109boolean show_where_not = FALSE0;
110/* Warn on multiple includes of same file */
111boolean warn_multiple = FALSE0;
112
113static void setfile_cmdinc(struct filepointer *filep, long count, char **list);
114static void redirect(const char *line, const char *makefile);
115
116static void _X_NORETURN__attribute((noreturn))
117catch (int sig)
118{
119 fflush (stdout__stdoutp);
120 fatalerr ("got signal %d\n", sig);
121}
122
123#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(Lynx_22) || defined(__CYGWIN__)
124#define USGISH
125#endif
126
127#ifndef USGISH
128#ifdef X_NOT_POSIX
129#define sigaction sigvec
130#define sa_handler__sigaction_u.__sa_handler sv_handler
131#define sa_mask sv_mask
132#define sa_flags sv_flags
133#endif
134static struct sigaction sig_act;
135#endif /* USGISH */
136
137int
138main(int argc, char *argv[])
139{
140 char **fp = filelist;
141 const char **incp = includedirs;
142 char *p;
143 struct inclist *ip;
144 char *makefile = NULL((void *)0);
145 struct filepointer *filecontent;
146 const struct symtab *psymp = predefs;
147 const char *endmarker = NULL((void *)0);
148 char *defincdir = NULL((void *)0);
149 char **undeflist = NULL((void *)0);
150 int numundefs = 0, i;
151
152 ProgramName = argv[0];
153
154 while (psymp->s_name)
1
Loop condition is false. Execution continues on line 178
155 {
156 define2(psymp->s_name, psymp->s_value, &maininclist);
157 psymp++;
158 }
159#ifdef __sun
160 /* Solaris predefined values that are computed, not hardcoded */
161 {
162 struct utsname name;
163
164 if (uname(&name) >= 0) {
165 char osrevdef[SYS_NMLN + SYS_NMLN + 5];
166 snprintf(osrevdef, sizeof(osrevdef), "__%s_%s",__builtin___snprintf_chk (osrevdef, sizeof(osrevdef), 0, __builtin_object_size
(osrevdef, 2 > 1 ? 1 : 0), "__%s_%s", name.sysname, name.
release)
167 name.sysname, name.release)__builtin___snprintf_chk (osrevdef, sizeof(osrevdef), 0, __builtin_object_size
(osrevdef, 2 > 1 ? 1 : 0), "__%s_%s", name.sysname, name.
release)
;
168
169 for (p = osrevdef; *p != '\0'; p++) {
170 if (!isalnum(*p)) {
171 *p = '_';
172 }
173 }
174 define2(osrevdef, "1", &maininclist);
175 }
176 }
177#endif
178 if (argc == 2 && argv[1][0] == '@') {
2
Assuming 'argc' is not equal to 2
179 struct stat ast;
180 int afd;
181 char *args;
182 char **nargv;
183 int nargc;
184 char quotechar = '\0';
185
186 nargc = 1;
187 if ((afd = open(argv[1]+1, O_RDONLY0x0000)) < 0)
188 fatalerr("cannot open \"%s\"\n", argv[1]+1);
189 fstat(afd, &ast);
190 args = malloc(ast.st_size + 1);
191 if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
192 fatalerr("failed to read %s\n", argv[1]+1);
193 args[ast.st_size] = '\0';
194 close(afd);
195 for (p = args; *p; p++) {
196 if (quotechar) {
197 if (quotechar == '\\' ||
198 (*p == quotechar && p[-1] != '\\'))
199 quotechar = '\0';
200 continue;
201 }
202 switch (*p) {
203 case '\\':
204 case '"':
205 case '\'':
206 quotechar = *p;
207 break;
208 case ' ':
209 case '\n':
210 *p = '\0';
211 if (p > args && p[-1])
212 nargc++;
213 break;
214 }
215 }
216 if (p[-1])
217 nargc++;
218 nargv = malloc(nargc * sizeof(char *));
219 nargv[0] = argv[0];
220 argc = 1;
221 for (p = args; argc < nargc; p += strlen(p) + 1)
222 if (*p) nargv[argc++] = p;
223 argv = nargv;
224 }
225 for(argc--, argv++; argc; argc--, argv++) {
3
Loop condition is false. Execution continues on line 396
226 /* if looking for endmarker then check before parsing */
227 if (endmarker && strcmp (endmarker, *argv) == 0) {
228 endmarker = NULL((void *)0);
229 continue;
230 }
231 if (**argv != '-') {
232 /* treat +thing as an option for C++ */
233 if (endmarker && **argv == '+')
234 continue;
235 *fp++ = argv[0];
236 continue;
237 }
238 switch(argv[0][1]) {
239 case '-':
240 endmarker = &argv[0][2];
241 if (endmarker[0] == '\0') endmarker = "--";
242 break;
243 case 'D':
244 if (argv[0][2] == '\0') {
245 if (argc < 2)
246 fatalerr("Missing argument for -D\n");
247 argv++;
248 argc--;
249 }
250 for (p=argv[0] + 2; *p ; p++)
251 if (*p == '=') {
252 *p = ' ';
253 break;
254 }
255 define(argv[0] + 2, &maininclist);
256 break;
257 case 'I':
258 if (incp >= includedirs + MAXDIRS64)
259 fatalerr("Too many -I flags.\n");
260 *incp++ = argv[0]+2;
261 if (**(incp-1) == '\0') {
262 if (argc < 2)
263 fatalerr("Missing argument for -I\n");
264 *(incp-1) = *(++argv);
265 argc--;
266 }
267 break;
268 case 'U':
269 /* Undef's override all -D's so save them up */
270 numundefs++;
271 if (numundefs == 1)
272 undeflist = malloc(sizeof(char *));
273 else
274 undeflist = realloc(undeflist,
275 numundefs * sizeof(char *));
276 if (argv[0][2] == '\0') {
277 if (argc < 2)
278 fatalerr("Missing argument for -U\n");
279 argv++;
280 argc--;
281 }
282 undeflist[numundefs - 1] = argv[0] + 2;
283 break;
284 case 'Y':
285 defincdir = argv[0]+2;
286 break;
287 /* do not use if endmarker processing */
288 case 'a':
289 if (endmarker) break;
290 append = TRUE1;
291 break;
292 case 'w':
293 if (endmarker) break;
294 if (argv[0][2] == '\0') {
295 if (argc < 2)
296 fatalerr("Missing argument for -w\n");
297 argv++;
298 argc--;
299 width = atoi(argv[0]);
300 } else
301 width = atoi(argv[0]+2);
302 break;
303 case 'o':
304 if (endmarker) break;
305 if (argv[0][2] == '\0') {
306 if (argc < 2)
307 fatalerr("Missing argument for -o\n");
308 argv++;
309 argc--;
310 objsuffix = argv[0];
311 } else
312 objsuffix = argv[0]+2;
313 break;
314 case 'p':
315 if (endmarker) break;
316 if (argv[0][2] == '\0') {
317 if (argc < 2)
318 fatalerr("Missing argument for -p\n");
319 argv++;
320 argc--;
321 objprefix = argv[0];
322 } else
323 objprefix = argv[0]+2;
324 break;
325 case 'v':
326 if (endmarker) break;
327 verbose = TRUE1;
328#ifdef DEBUG
329 if (argv[0][2])
330 _debugmask = atoi(argv[0]+2);
331#endif
332 break;
333 case 's':
334 if (endmarker) break;
335 startat = argv[0]+2;
336 if (*startat == '\0') {
337 if (argc < 2)
338 fatalerr("Missing argument for -s\n");
339 startat = *(++argv);
340 argc--;
341 }
342 if (*startat != '#')
343 fatalerr("-s flag's value should start %s\n",
344 "with '#'.");
345 break;
346 case 'f':
347 if (endmarker) break;
348 makefile = argv[0]+2;
349 if (*makefile == '\0') {
350 if (argc < 2)
351 fatalerr("Missing argument for -f\n");
352 makefile = *(++argv);
353 argc--;
354 }
355 break;
356
357 case 'm':
358 warn_multiple = TRUE1;
359 break;
360
361 /* Ignore -O, -g so we can just pass ${CFLAGS} to
362 makedepend
363 */
364 case 'O':
365 case 'g':
366 break;
367 case 'i':
368 if (strcmp(&argv[0][1],"include") == 0) {
369 char *buf;
370 if (argc<2)
371 fatalerr("option -include is a "
372 "missing its parameter\n");
373 if (cmdinc_count >= MAXINCFILES128)
374 fatalerr("Too many -include flags.\n");
375 argc--;
376 argv++;
377 buf = malloc(strlen(DASH_INC_PRE"#include \"") +
378 strlen(argv[0]) +
379 strlen(DASH_INC_POST"\"") + 1);
380 if(!buf)
381 fatalerr("out of memory at "
382 "-include string\n");
383 cmdinc_list[2 * cmdinc_count + 0] = argv[0];
384 cmdinc_list[2 * cmdinc_count + 1] = buf;
385 cmdinc_count++;
386 break;
387 }
388 /* intentional fall through */
389 default:
390 if (endmarker) break;
391 /* fatalerr("unknown opt = %s\n", argv[0]); */
392 warning("ignoring option %s\n", argv[0]);
393 }
394 }
395 /* Now do the undefs from the command line */
396 for (i = 0; i < numundefs; i++)
4
Loop condition is false. Execution continues on line 398
397 undefine(undeflist[i], &maininclist);
398 if (numundefs > 0)
5
Taking false branch
399 free(undeflist);
400
401 if (!defincdir) {
6
Taking true branch
402#ifdef PREINCDIR
403 if (incp >= includedirs + MAXDIRS64)
404 fatalerr("Too many -I flags.\n");
405 *incp++ = PREINCDIR;
406#endif
407 if (incp >= includedirs + MAXDIRS64)
7
Taking false branch
408 fatalerr("Too many -I flags.\n");
409 *incp++ = INCLUDEDIR"/usr/include";
410
411#ifdef EXTRAINCDIR
412 if (incp >= includedirs + MAXDIRS64)
413 fatalerr("Too many -I flags.\n");
414 *incp++ = EXTRAINCDIR;
415#endif
416
417#ifdef POSTINCDIR
418 if (incp >= includedirs + MAXDIRS64)
419 fatalerr("Too many -I flags.\n");
420 *incp++ = POSTINCDIR;
421#endif
422 } else if (*defincdir) {
423 if (incp >= includedirs + MAXDIRS64)
424 fatalerr("Too many -I flags.\n");
425 *incp++ = defincdir;
426 }
427
428 redirect(startat, makefile);
429
430 /*
431 * catch signals.
432 */
433#ifdef USGISH
434/* should really reset SIGINT to SIG_IGN if it was. */
435#ifdef SIGHUP1
436 signal (SIGHUP1, catch);
437#endif
438 signal (SIGINT2, catch);
439#ifdef SIGQUIT3
440 signal (SIGQUIT3, catch);
441#endif
442 signal (SIGILL4, catch);
443#ifdef SIGBUS10
444 signal (SIGBUS10, catch);
445#endif
446 signal (SIGSEGV11, catch);
447#ifdef SIGSYS12
448 signal (SIGSYS12, catch);
449#endif
450#else
451 sig_act.sa_handler__sigaction_u.__sa_handler = catch;
452#if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
453 sigemptyset(&sig_act.sa_mask)(*(&sig_act.sa_mask) = 0, 0);
454 sigaddset(&sig_act.sa_mask, SIGINT)(*(&sig_act.sa_mask) |= __sigbits(2), 0);
455 sigaddset(&sig_act.sa_mask, SIGQUIT)(*(&sig_act.sa_mask) |= __sigbits(3), 0);
456#ifdef SIGBUS10
457 sigaddset(&sig_act.sa_mask, SIGBUS)(*(&sig_act.sa_mask) |= __sigbits(10), 0);
458#endif
459 sigaddset(&sig_act.sa_mask, SIGILL)(*(&sig_act.sa_mask) |= __sigbits(4), 0);
460 sigaddset(&sig_act.sa_mask, SIGSEGV)(*(&sig_act.sa_mask) |= __sigbits(11), 0);
461 sigaddset(&sig_act.sa_mask, SIGHUP)(*(&sig_act.sa_mask) |= __sigbits(1), 0);
462 sigaddset(&sig_act.sa_mask, SIGPIPE)(*(&sig_act.sa_mask) |= __sigbits(13), 0);
463#ifdef SIGSYS12
464 sigaddset(&sig_act.sa_mask, SIGSYS)(*(&sig_act.sa_mask) |= __sigbits(12), 0);
465#endif
466#else
467 sig_act.sa_mask = ((1<<(SIGINT2 -1))
468 |(1<<(SIGQUIT3-1))
469#ifdef SIGBUS10
470 |(1<<(SIGBUS10-1))
471#endif
472 |(1<<(SIGILL4-1))
473 |(1<<(SIGSEGV11-1))
474 |(1<<(SIGHUP1-1))
475 |(1<<(SIGPIPE13-1))
476#ifdef SIGSYS12
477 |(1<<(SIGSYS12-1))
478#endif
479 );
480#endif /* _POSIX_SOURCE */
481 sig_act.sa_flags = 0;
482 sigaction(SIGHUP1, &sig_act, (struct sigaction *)0);
483 sigaction(SIGINT2, &sig_act, (struct sigaction *)0);
484 sigaction(SIGQUIT3, &sig_act, (struct sigaction *)0);
485 sigaction(SIGILL4, &sig_act, (struct sigaction *)0);
486#ifdef SIGBUS10
487 sigaction(SIGBUS10, &sig_act, (struct sigaction *)0);
488#endif
489 sigaction(SIGSEGV11, &sig_act, (struct sigaction *)0);
490#ifdef SIGSYS12
491 sigaction(SIGSYS12, &sig_act, (struct sigaction *)0);
492#endif
493#endif /* USGISH */
494
495 /*
496 * now peruse through the list of files.
497 */
498 for(fp=filelist; *fp; fp++) {
8
Loop condition is true. Entering loop body
499 DBG_PRINT(stderr,"file: %s\n",*fp);
500 filecontent = getfile(*fp);
501 setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
502 ip = newinclude(*fp, (char *)NULL((void *)0));
503
504 find_includes(filecontent, ip, ip, 0, FALSE0);
505 freefile(filecontent);
506 recursive_pr_include(ip, ip->i_file, base_name(*fp));
9
Calling 'base_name'
12
Returned allocated memory
507 inc_clean();
13
Potential memory leak
508 }
509 if (printed)
510 printf("\n");
511 return 0;
512}
513
514
515struct filepointer *
516getfile(const char *file)
517{
518 int fd;
519 struct filepointer *content;
520 struct stat st;
521
522 content = malloc(sizeof(struct filepointer));
523 content->f_name = file;
524 if ((fd = open(file, O_RDONLY0x0000)) < 0) {
525 warning("cannot open \"%s\"\n", file);
526 content->f_p = content->f_base = content->f_end = malloc(1);
527 *content->f_p = '\0';
528 return(content);
529 }
530 fstat(fd, &st);
531 content->f_base = malloc(st.st_size+1);
532 if (content->f_base == NULL((void *)0))
533 fatalerr("cannot allocate mem\n");
534 if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
535 fatalerr("failed to read %s\n", file);
536 close(fd);
537 content->f_len = st.st_size+1;
538 content->f_p = content->f_base;
539 content->f_end = content->f_base + st.st_size;
540 *content->f_end = '\0';
541 content->f_line = 0;
542 content->cmdinc_count = 0;
543 content->cmdinc_list = NULL((void *)0);
544 content->cmdinc_line = 0;
545 return(content);
546}
547
548void
549setfile_cmdinc(struct filepointer* filep, long count, char** list)
550{
551 filep->cmdinc_count = count;
552 filep->cmdinc_list = list;
553 filep->cmdinc_line = 0;
554}
555
556void
557freefile(struct filepointer *fp)
558{
559 free(fp->f_base);
560 free(fp);
561}
562
563int
564match(const char *str, const char * const *list)
565{
566 int i;
567
568 for (i=0; *list; i++, list++)
569 if (strcmp(str, *list) == 0)
570 return(i);
571 return(-1);
572}
573
574/*
575 * Get the next line. We only return lines beginning with '#' since that
576 * is all this program is ever interested in.
577 */
578char *getnextline(struct filepointer *filep)
579{
580 char *p, /* walking pointer */
581 *eof, /* end of file pointer */
582 *bol; /* beginning of line pointer */
583 int lineno; /* line number */
584 boolean whitespace = FALSE0;
585
586 /*
587 * Fake the "-include" line files in form of #include to the
588 * start of each file.
589 */
590 if (filep->cmdinc_line < filep->cmdinc_count) {
591 char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
592 char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
593 filep->cmdinc_line++;
594 sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST)__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2
> 1 ? 1 : 0), "%s%s%s","#include \"",inc,"\"")
;
595 DBG_PRINT(stderr,"%s\n",buf);
596 return(buf);
597 }
598
599 p = filep->f_p;
600 eof = filep->f_end;
601 if (p >= eof)
602 return((char *)NULL((void *)0));
603 lineno = filep->f_line;
604
605 for (bol = p--; ++p < eof; ) {
606 if ((bol == p) && ((*p == ' ') || (*p == '\t')))
607 {
608 /* Consume leading white-spaces for this line */
609 while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
610 {
611 p++;
612 bol++;
613 }
614 whitespace = TRUE1;
615 }
616
617 if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
618 /* Consume C comments */
619 *(p++) = ' ';
620 *(p++) = ' ';
621 while (p < eof && *p) {
622 if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
623 *(p++) = ' ';
624 *(p++) = ' ';
625 break;
626 }
627 if (*p == '\n')
628 lineno++;
629 *(p++) = ' ';
630 }
631 --p;
632 }
633 else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
634 /* Consume C++ comments */
635 *(p++) = ' ';
636 *(p++) = ' ';
637 while (p < eof && *p) {
638 if (*p == '\\' && (p+1) < eof &&
639 *(p+1) == '\n') {
640 *(p++) = ' ';
641 lineno++;
642 }
643 else if (*p == '?' && (p+3) < eof &&
644 *(p+1) == '?' &&
645 *(p+2) == '/' &&
646 *(p+3) == '\n') {
647 *(p++) = ' ';
648 *(p++) = ' ';
649 *(p++) = ' ';
650 lineno++;
651 }
652 else if (*p == '\n')
653 break; /* to process end of line */
654 *(p++) = ' ';
655 }
656 --p;
657 }
658 else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
659 /* Consume backslash line terminations */
660 *(p++) = ' ';
661 *p = ' ';
662 lineno++;
663 }
664 else if (*p == '?' && (p+3) < eof &&
665 *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
666 /* Consume trigraph'ed backslash line terminations */
667 *(p++) = ' ';
668 *(p++) = ' ';
669 *(p++) = ' ';
670 *p = ' ';
671 lineno++;
672 }
673 else if (*p == '\n') {
674 lineno++;
675 if (*bol == '#') {
676 char *cp;
677
678 *(p++) = '\0';
679 /* punt lines with just # (yacc generated) */
680 for (cp = bol+1;
681 *cp && (*cp == ' ' || *cp == '\t'); cp++);
682 if (*cp) goto done;
683 --p;
684 }
685 bol = p+1;
686 whitespace = FALSE0;
687 }
688 }
689 if (*bol != '#')
690 bol = NULL((void *)0);
691done:
692 filep->f_p = p;
693 filep->f_line = lineno;
694#ifdef DEBUG_DUMP
695 if (bol)
696 DBG_PRINT(stderr,"%s\n",bol);
697#endif
698 return(bol);
699}
700
701/*
702 * Strip the file name down to what we want to see in the Makefile.
703 * It will have objprefix and objsuffix around it.
704 */
705char *base_name(const char *in_file)
706{
707 char *p;
708 char *file = strdup(in_file);
10
Memory is allocated
709 for(p=file+strlen(file); p>file && *p != '.'; p--) ;
710
711 if (*p == '.')
11
Taking false branch
712 *p = '\0';
713 return(file);
714}
715
716#ifndef HAVE_RENAME1
717int rename (char *from, char *to)
718{
719 (void) unlink (to);
720 if (link (from, to) == 0) {
721 unlink (from);
722 return 0;
723 } else {
724 return -1;
725 }
726}
727#endif /* !HAVE_RENAME */
728
729static void
730redirect(const char *line, const char *makefile)
731{
732 struct stat st;
733 FILE *fdin, *fdout;
734 char backup[ BUFSIZ1024 ],
735 buf[ BUFSIZ1024 ];
736 boolean found = FALSE0;
737 size_t len;
738
739 /*
740 * if makefile is "-" then let it pour onto stdout.
741 */
742 if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
743 puts(line);
744 return;
745 }
746
747 /*
748 * use a default if makefile is not specified.
749 */
750 if (!makefile) {
751 if (stat("Makefile", &st) == 0)
752 makefile = "Makefile";
753 else if (stat("makefile", &st) == 0)
754 makefile = "makefile";
755 else
756 fatalerr("[mM]akefile is not present\n");
757 }
758 else {
759 if (stat(makefile, &st) != 0)
760 fatalerr("\"%s\" is not present\n", makefile);
761 }
762
763 snprintf(backup, sizeof(backup), "%s.bak", makefile)__builtin___snprintf_chk (backup, sizeof(backup), 0, __builtin_object_size
(backup, 2 > 1 ? 1 : 0), "%s.bak", makefile)
;
764 unlink(backup);
765
766 /* rename() won't work on WIN32, CYGWIN, or CIFS if src file is open */
767 if (rename(makefile, backup) < 0)
768 fatalerr("cannot rename %s to %s\n", makefile, backup);
769 if ((fdin = fopen(backup, "r")) == NULL((void *)0)) {
770 if (rename(backup, makefile) < 0)
771 warning("renamed %s to %s, but can't move it back\n",
772 makefile, backup);
773 fatalerr("cannot open \"%s\"\n", makefile);
774 }
775 if ((fdout = freopen(makefile, "w", stdout__stdoutp)) == NULL((void *)0))
776 fatalerr("cannot open \"%s\"\n", backup);
777 len = strlen(line);
778 while (!found && fgets(buf, BUFSIZ1024, fdin)) {
779 if (*buf == '#' && strncmp(line, buf, len) == 0)
780 found = TRUE1;
781 fputs(buf, fdout);
782 }
783 if (!found) {
784 if (verbose)
785 warning("Adding new delimiting line \"%s\" and dependencies...\n",
786 line);
787 puts(line); /* same as fputs(fdout); but with newline */
788 } else if (append) {
789 while (fgets(buf, BUFSIZ1024, fdin)) {
790 fputs(buf, fdout);
791 }
792 }
793 fflush(fdout);
794#ifndef HAVE_FCHMOD1
795 chmod(makefile, st.st_mode);
796#else
797 fchmod(fileno(fdout), st.st_mode);
798#endif /* HAVE_FCHMOD */
799}
800
801void
802fatalerr(const char *msg, ...)
803{
804 va_list args;
805 fprintf(stderr__stderrp, "%s: error: ", ProgramName);
806 va_start(args, msg)__builtin_va_start(args, msg);
807 vfprintf(stderr__stderrp, msg, args);
808 va_end(args)__builtin_va_end(args);
809 exit (1);
810}
811
812void
813warning(const char *msg, ...)
814{
815 va_list args;
816 fprintf(stderr__stderrp, "%s: warning: ", ProgramName);
817 va_start(args, msg)__builtin_va_start(args, msg);
818 vfprintf(stderr__stderrp, msg, args);
819 va_end(args)__builtin_va_end(args);
820}
821
822void
823warning1(const char *msg, ...)
824{
825 va_list args;
826 va_start(args, msg)__builtin_va_start(args, msg);
827 vfprintf(stderr__stderrp, msg, args);
828 va_end(args)__builtin_va_end(args);
829}