mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
fixdep: use fflush() and ferror() to ensure successful write to files
Currently, fixdep checks the return value from (v)printf(), but it does not ensure the complete write to the .cmd file. printf() just writes data to the internal buffer, which usually succeeds. (Of course, it may fail for another reason, for example when the file descriptor is closed, but that is another story.) When the buffer (4k?) is full, an actual write occurs, and printf() may really fail. One of typical cases is "No space left on device" when the disk is full. The data remaining in the buffer will be pushed out to the file when the program exits, but we never know if it is successful. One straight-forward fix would be to add the following code at the end of the program. ret = fflush(stdout); if (ret < 0) { /* error handling */ } However, it is tedious to check the return code in all the call sites of printf(), fflush(), fclose(), and whatever can cause actual writes to the end device. Doing that lets the program bail out at the first failure but is usually not worth the effort. Instead, let's check the error status from ferror(). This is 'sticky', so you need to check it just once. You still need to call fflush(). Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Reviewed-by: David Laight <david.laight@aculab.com> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
This commit is contained in:
parent
bbc90bc1bd
commit
69304379ff
@ -105,25 +105,6 @@ static void usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the intended usage of this program, the stdout is redirected to .*.cmd
|
||||
* files. The return value of printf() must be checked to catch any error,
|
||||
* e.g. "No space left on device".
|
||||
*/
|
||||
static void xprintf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = vprintf(format, ap);
|
||||
if (ret < 0) {
|
||||
perror("fixdep");
|
||||
exit(1);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
struct item {
|
||||
struct item *next;
|
||||
unsigned int len;
|
||||
@ -189,7 +170,7 @@ static void use_config(const char *m, int slen)
|
||||
|
||||
define_config(m, slen, hash);
|
||||
/* Print out a dependency path from a symbol name. */
|
||||
xprintf(" $(wildcard include/config/%.*s) \\\n", slen, m);
|
||||
printf(" $(wildcard include/config/%.*s) \\\n", slen, m);
|
||||
}
|
||||
|
||||
/* test if s ends in sub */
|
||||
@ -318,13 +299,13 @@ static void parse_dep_file(char *m, const char *target)
|
||||
*/
|
||||
if (!saw_any_target) {
|
||||
saw_any_target = 1;
|
||||
xprintf("source_%s := %s\n\n",
|
||||
target, m);
|
||||
xprintf("deps_%s := \\\n", target);
|
||||
printf("source_%s := %s\n\n",
|
||||
target, m);
|
||||
printf("deps_%s := \\\n", target);
|
||||
}
|
||||
is_first_dep = 0;
|
||||
} else {
|
||||
xprintf(" %s \\\n", m);
|
||||
printf(" %s \\\n", m);
|
||||
}
|
||||
|
||||
buf = read_file(m);
|
||||
@ -347,8 +328,8 @@ static void parse_dep_file(char *m, const char *target)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
xprintf("\n%s: $(deps_%s)\n\n", target, target);
|
||||
xprintf("$(deps_%s):\n", target);
|
||||
printf("\n%s: $(deps_%s)\n\n", target, target);
|
||||
printf("$(deps_%s):\n", target);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -363,11 +344,22 @@ int main(int argc, char *argv[])
|
||||
target = argv[2];
|
||||
cmdline = argv[3];
|
||||
|
||||
xprintf("cmd_%s := %s\n\n", target, cmdline);
|
||||
printf("cmd_%s := %s\n\n", target, cmdline);
|
||||
|
||||
buf = read_file(depfile);
|
||||
parse_dep_file(buf, target);
|
||||
free(buf);
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
/*
|
||||
* In the intended usage, the stdout is redirected to .*.cmd files.
|
||||
* Call ferror() to catch errors such as "No space left on device".
|
||||
*/
|
||||
if (ferror(stdout)) {
|
||||
fprintf(stderr, "fixdep: not all data was written to the output\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user