X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fmake-file.c;h=a5b68051ac4d6a6c431a9bded84e02a707a29bff;hb=7344ce41487d4294726d597b99bbef5c3cfa1ce6;hp=78875746f24ea2ff99860c5af75825da78e60fe4;hpb=3db83b515247dca69abbf7ad05d3dbdfec4b524c;p=pspp diff --git a/src/data/make-file.c b/src/data/make-file.c index 78875746f2..a5b68051ac 100644 --- a/src/data/make-file.c +++ b/src/data/make-file.c @@ -193,13 +193,12 @@ static void free_replace_file (struct replace_file *); static void unlink_replace_files (void); struct replace_file * -replace_file_start (const struct file_handle *fh, const char *mode, - mode_t permissions, FILE **fp) +replace_file_start_fd (const struct file_handle *fh, + bool binary, mode_t permissions, int *fd) { static bool registered; struct TS_stat s; struct replace_file *rf; - int fd; int saved_errno = errno; const char *file_name = fh_get_file_name (fh); @@ -211,8 +210,8 @@ replace_file_start (const struct file_handle *fh, const char *mode, if (Tstat (Tfile_name, &s) == 0 && !S_ISREG (s.st_mode)) { /* Open file descriptor. */ - fd = Topen (Tfile_name, O_WRONLY); - if (fd < 0) + *fd = Topen (Tfile_name, O_WRONLY); + if (*fd < 0) { saved_errno = errno; msg (ME, _("Opening %s for writing: %s."), @@ -221,18 +220,6 @@ replace_file_start (const struct file_handle *fh, const char *mode, return NULL; } - /* Open file as stream. */ - *fp = fdopen (fd, mode); - if (*fp == NULL) - { - saved_errno = errno; - msg (ME, _("Opening stream for %s: %s."), - file_name, strerror (saved_errno)); - close (fd); - free (Tfile_name); - return NULL; - } - rf = xzalloc (sizeof *rf); rf->file_name = NULL; rf->tmp_name = Tfile_name; @@ -266,8 +253,9 @@ replace_file_start (const struct file_handle *fh, const char *mode, rf->tmp_name = convert_to_filename_encoding (rf->tmp_name_verbatim, strlen (rf->tmp_name_verbatim), fh_get_file_name_encoding (fh)); /* Create file by that name. */ - fd = Topen (rf->tmp_name, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, permissions); - if (fd >= 0) + int flags = O_WRONLY | O_CREAT | O_EXCL | (binary ? O_BINARY : O_TEXT); + *fd = Topen (rf->tmp_name, flags, permissions); + if (*fd >= 0) break; if (errno != EEXIST) { @@ -279,29 +267,50 @@ replace_file_start (const struct file_handle *fh, const char *mode, } + /* Register file for deletion. */ + ll_push_head (&all_files, &rf->ll); + unblock_fatal_signals (); + + return rf; + + error: + unblock_fatal_signals (); + free_replace_file (rf); + *fd = -1; + errno = saved_errno; + return NULL; +} + +struct replace_file * +replace_file_start (const struct file_handle *fh, bool binary, + mode_t permissions, FILE **fp) +{ + struct replace_file *rf; + int fd; + + /* Open fd. */ + rf = replace_file_start_fd (fh, binary, permissions, &fd); + if (!rf) + goto error; + /* Open file as stream. */ - *fp = fdopen (fd, mode); + *fp = fdopen (fd, binary ? "wb" : "w"); if (*fp == NULL) { - saved_errno = errno; + int error = errno; msg (ME, _("Opening stream for temporary file %s: %s."), - rf->tmp_name_verbatim, strerror (saved_errno)); + rf->tmp_name_verbatim, strerror (error)); close (fd); - Tunlink (rf->tmp_name); + replace_file_abort (rf); + errno = error; + goto error; } - /* Register file for deletion. */ - ll_push_head (&all_files, &rf->ll); - unblock_fatal_signals (); - return rf; - error: - unblock_fatal_signals (); - free_replace_file (rf); +error: *fp = NULL; - errno = saved_errno; return NULL; }