libbb: added xfdopen_for_read/write
No binary (build failed)
—
(log yok)
| @@ -42,10 +42,10 @@ static void convert(char *fn, int conv_type) | |
| i = mkstemp(temp_fn); | |
| if (i == -1 | |
| || fchmod(i, st.st_mode) == -1 | |
| - | || !(out = fdopen(i, "w+")) |
| ) { | |
| bb_simple_perror_msg_and_die(temp_fn); | |
| } | |
| + | out = xfdopen_for_write(i); |
| } | |
| while ((i = fgetc(in)) != EOF) { | |
| @@ -374,9 +374,7 @@ void blkid_read_cache(blkid_cache cache) | |
| DBG(DEBUG_CACHE, printf("reading cache file %s\n", | |
| cache->bic_filename)); | |
| - | file = fdopen(fd, "r"); |
| - | if (!file) |
| - | goto errout; |
| + | file = xfdopen_for_read(fd); |
| while (fgets(buf, sizeof(buf), file)) { | |
| blkid_dev dev; | |
| @@ -95,7 +95,7 @@ int blkid_flush_cache(blkid_cache cache) | |
| sprintf(tmp, "%s-XXXXXX", filename); | |
| fd = mkstemp(tmp); | |
| if (fd >= 0) { | |
| - | file = fdopen(fd, "w"); |
| + | file = xfdopen_for_write(fd); |
| opened = tmp; | |
| } | |
| fchmod(fd, 0644); | |
| @@ -1338,7 +1338,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv) | |
| nonstdoutfd = mkstemp(G.outname); | |
| if (-1 == nonstdoutfd) | |
| bb_perror_msg_and_die("can't create temp file %s", G.outname); | |
| - | G.nonstdout = fdopen(nonstdoutfd, "w"); |
| + | G.nonstdout = xfdopen_for_write(nonstdoutfd); |
| /* Set permissions/owner of output file */ | |
| fstat(fileno(file), &statbuf); | |
| @@ -658,21 +658,23 @@ extern char *xmalloc_fgetline(FILE *file) FAST_FUNC RETURNS_MALLOC; | |
| /* Same, but doesn't try to conserve space (may have some slack after the end) */ | |
| /* extern char *xmalloc_fgetline_fast(FILE *file) FAST_FUNC RETURNS_MALLOC; */ | |
| - | extern void die_if_ferror(FILE *file, const char *msg) FAST_FUNC; |
| - | extern void die_if_ferror_stdout(void) FAST_FUNC; |
| - | extern int fflush_all(void) FAST_FUNC; |
| - | extern void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC; |
| - | extern int fclose_if_not_stdin(FILE *file) FAST_FUNC; |
| - | extern FILE *xfopen(const char *filename, const char *mode) FAST_FUNC; |
| + | void die_if_ferror(FILE *file, const char *msg) FAST_FUNC; |
| + | void die_if_ferror_stdout(void) FAST_FUNC; |
| + | int fflush_all(void) FAST_FUNC; |
| + | void fflush_stdout_and_exit(int retval) NORETURN FAST_FUNC; |
| + | int fclose_if_not_stdin(FILE *file) FAST_FUNC; |
| + | FILE* xfopen(const char *filename, const char *mode) FAST_FUNC; |
| /* Prints warning to stderr and returns NULL on failure: */ | |
| - | extern FILE *fopen_or_warn(const char *filename, const char *mode) FAST_FUNC; |
| + | FILE* fopen_or_warn(const char *filename, const char *mode) FAST_FUNC; |
| /* "Opens" stdin if filename is special, else just opens file: */ | |
| - | extern FILE *xfopen_stdin(const char *filename) FAST_FUNC; |
| - | extern FILE *fopen_or_warn_stdin(const char *filename) FAST_FUNC; |
| - | extern FILE* fopen_for_read(const char *path) FAST_FUNC; |
| - | extern FILE* xfopen_for_read(const char *path) FAST_FUNC; |
| - | extern FILE* fopen_for_write(const char *path) FAST_FUNC; |
| - | extern FILE* xfopen_for_write(const char *path) FAST_FUNC; |
| + | FILE* xfopen_stdin(const char *filename) FAST_FUNC; |
| + | FILE* fopen_or_warn_stdin(const char *filename) FAST_FUNC; |
| + | FILE* fopen_for_read(const char *path) FAST_FUNC; |
| + | FILE* xfopen_for_read(const char *path) FAST_FUNC; |
| + | FILE* fopen_for_write(const char *path) FAST_FUNC; |
| + | FILE* xfopen_for_write(const char *path) FAST_FUNC; |
| + | FILE* xfdopen_for_read(int fd) FAST_FUNC; |
| + | FILE* xfdopen_for_write(int fd) FAST_FUNC; |
| int bb_pstrcmp(const void *a, const void *b) /* not FAST_FUNC! */; | |
| void qsort_string_vector(char **sv, unsigned count) FAST_FUNC; | |
| @@ -137,12 +137,7 @@ int FAST_FUNC update_passwd(const char *filename, | |
| fchown(new_fd, sb.st_uid, sb.st_gid); | |
| } | |
| errno = 0; | |
| - | new_fp = fdopen(new_fd, "w"); |
| - | if (!new_fp) { |
| - | bb_perror_nomsg(); |
| - | close(new_fd); |
| - | goto unlink_new; |
| - | } |
| + | new_fp = xfdopen_for_write(new_fd); |
| /* Backup file is "/etc/passwd-" */ | |
| *sfx_char = '-'; | |
| @@ -38,3 +38,19 @@ FILE* FAST_FUNC xfopen_for_write(const char *path) | |
| { | |
| return xfopen(path, "w"); | |
| } | |
| + | |
| + | static FILE* xfdopen_helper(unsigned fd_and_rw_bit) |
| + | { |
| + | FILE* fp = fdopen(fd_and_rw_bit >> 1, fd_and_rw_bit & 1 ? "w" : "r"); |
| + | if (!fp) |
| + | bb_error_msg_and_die(bb_msg_memory_exhausted); |
| + | return fp; |
| + | } |
| + | FILE* FAST_FUNC xfdopen_for_read(int fd) |
| + | { |
| + | return xfdopen_helper(fd << 1); |
| + | } |
| + | FILE* FAST_FUNC xfdopen_for_write(int fd) |
| + | { |
| + | return xfdopen_helper((fd << 1) + 1); |
| + | } |
| @@ -293,7 +293,7 @@ static int parse(const char *boundary, char **argv) | |
| } | |
| // parent dumps to fd[1] | |
| close(fd[0]); | |
| - | fp = fdopen(fd[1], "w"); |
| + | fp = xfdopen_for_write(fd[1]); |
| signal(SIGPIPE, SIG_IGN); // ignore EPIPE | |
| // or create a file for dump | |
| } else { | |
| @@ -93,7 +93,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |
| // save initial stdin since body is piped! | |
| xdup2(STDIN_FILENO, 3); | |
| - | G.fp0 = fdopen(3, "r"); |
| + | G.fp0 = xfdopen_for_read(3); |
| // parse options | |
| // -f is required. -H and -S are mutually exclusive | |
| @@ -227,7 +227,7 @@ static void fb_drawimage(void) | |
| int fd = open_zipped(G.image_filename); | |
| if (fd < 0) | |
| bb_simple_perror_msg_and_die(G.image_filename); | |
| - | theme_file = fdopen(fd, "r"); |
| + | theme_file = xfdopen_for_read(fd); |
| } | |
| head = xmalloc(256); | |
| @@ -384,11 +384,7 @@ static void write_out_dep_bb(int fd) | |
| FILE *fp; | |
| /* We want good error reporting. fdprintf is not good enough. */ | |
| - | fp = fdopen(fd, "w"); |
| - | if (!fp) { |
| - | close(fd); |
| - | goto err; |
| - | } |
| + | fp = xfdopen_for_write(fd); |
| i = 0; | |
| while (modinfo[i].pathname) { | |
| fprintf(fp, "%s%s%s\n" "%s%s\n", | |
| @@ -691,9 +691,7 @@ handle_dir_common(int opts) | |
| /* -n prevents user/groupname display, | |
| * which can be problematic in chroot */ | |
| ls_fd = popen_ls((opts & LONG_LISTING) ? "-l" : "-1"); | |
| - | ls_fp = fdopen(ls_fd, "r"); |
| - | if (!ls_fp) /* never happens. paranoia */ |
| - | bb_perror_msg_and_die("fdopen"); |
| + | ls_fp = xfdopen_for_read(ls_fd); |
| if (opts & USE_CTRL_CONN) { | |
| /* STAT <filename> */ | |
| @@ -1056,8 +1056,8 @@ static int popen2(FILE **in, FILE **out, char *command, char *param) | |
| /* parent */ | |
| close(infd.rd); | |
| close(outfd.wr); | |
| - | *in = fdopen(infd.wr, "w"); |
| - | *out = fdopen(outfd.rd, "r"); |
| + | *in = xfdopen_for_write(infd.wr); |
| + | *out = xfdopen_for_read(outfd.rd); |
| return pid; | |
| } | |
| @@ -761,8 +761,8 @@ static NOINLINE unsigned logdir_open(struct logdir *ld, const char *fn) | |
| } | |
| while ((ld->fdcur = open("current", O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600)) == -1) | |
| pause2cannot("open current", ld->name); | |
| - | /* we presume this cannot fail */ |
| - | ld->filecur = fdopen(ld->fdcur, "a"); //// |
| + | while ((ld->filecur = fdopen(ld->fdcur, "a")) == NULL) |
| + | pause2cannot("open current", ld->name); //// |
| setvbuf(ld->filecur, NULL, _IOFBF, linelen); //// | |
| close_on_exec_on(ld->fdcur); | |
| @@ -5301,25 +5301,22 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p) | |
| free(to_free); | |
| # endif | |
| close(channel[1]); | |
| - | //TODO: libbb: fdopen_or_die? |
| - | return fdopen(channel[0], "r"); |
| + | close_on_exec_on(channel[0]); |
| + | return xfdopen_for_read(channel[0]); |
| } | |
| /* Return code is exit status of the process that is run. */ | |
| static int process_command_subs(o_string *dest, const char *s) | |
| { | |
| - | FILE *pf; |
| + | FILE *fp; |
| struct in_str pipe_str; | |
| pid_t pid; | |
| int status, ch, eol_cnt; | |
| - | pf = generate_stream_from_string(s, &pid); |
| - | if (pf == NULL) |
| - | return 1; |
| - | close_on_exec_on(fileno(pf)); |
| + | fp = generate_stream_from_string(s, &pid); |
| /* Now send results of command back into original context */ | |
| - | setup_file_in_str(&pipe_str, pf); |
| + | setup_file_in_str(&pipe_str, fp); |
| eol_cnt = 0; | |
| while ((ch = i_getch(&pipe_str)) != EOF) { | |
| if (ch == '\n') { | |
| @@ -5334,7 +5331,7 @@ static int process_command_subs(o_string *dest, const char *s) | |
| } | |
| debug_printf("done reading from `cmd` pipe, closing it\n"); | |
| - | fclose(pf); |
| + | fclose(fp); |
| /* We need to extract exitcode. Test case | |
| * "true; echo `sleep 1; false` $?" | |
| * should print 1 */ | |