X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fpor-file-writer.c;h=8a27f6b785ccc548d5a14436cfe221ee7476d3e6;hb=085d4563d8d5adfb3a2552d6ab1959c3fcacaee0;hp=cf4474569531ee723f2fbbb3ecb7a2b1e815b507;hpb=29956ba4326b9d6a2bc4d22a9f323902c7a08d43;p=pspp-builds.git diff --git a/src/data/por-file-writer.c b/src/data/por-file-writer.c index cf447456..8a27f6b7 100644 --- a/src/data/por-file-writer.c +++ b/src/data/por-file-writer.c @@ -19,36 +19,37 @@ #include #include -#include #include #include #include #include #include #include -#include #include #include #include #include #include +#include #include +#include #include #include #include #include -#include #include -#include #include #include #include #include +#include "xalloc.h" + #include "gettext.h" #define _(msgid) gettext (msgid) +#define N_(msgid) (msgid) /* Maximum width of a variable in a portable file. */ #define MAX_POR_WIDTH 255 @@ -57,7 +58,9 @@ struct pfm_writer { struct file_handle *fh; /* File handle. */ + struct fh_lock *lock; /* Lock on file handle. */ FILE *file; /* File stream. */ + struct replace_file *rf; /* Ticket for replacing output file. */ int lc; /* Number of characters on this line so far. */ @@ -74,7 +77,7 @@ struct pfm_var int fv; /* Starting case index. */ }; -static struct casewriter_class por_file_casewriter_class; +static const struct casewriter_class por_file_casewriter_class; static bool close_writer (struct pfm_writer *); static void buf_write (struct pfm_writer *, const void *, size_t); @@ -109,31 +112,14 @@ pfm_open_writer (struct file_handle *fh, struct dictionary *dict, { struct pfm_writer *w = NULL; mode_t mode; - int fd; size_t i; - /* Create file. */ - mode = S_IRUSR | S_IRGRP | S_IROTH; - if (opts.create_writeable) - mode |= S_IWUSR | S_IWGRP | S_IWOTH; - fd = open (fh_get_file_name (fh), O_WRONLY | O_CREAT | O_TRUNC, mode); - if (fd < 0) - goto open_error; - - /* Open file handle. */ - if (!fh_open (fh, FH_REF_FILE, "portable file", "we")) - goto error; - /* Initialize data structures. */ w = xmalloc (sizeof *w); - w->fh = fh; - w->file = fdopen (fd, "w"); - if (w->file == NULL) - { - close (fd); - goto open_error; - } - + w->fh = fh_ref (fh); + w->lock = NULL; + w->file = NULL; + w->rf = NULL; w->lc = 0; w->var_cnt = 0; w->vars = NULL; @@ -156,6 +142,26 @@ pfm_open_writer (struct file_handle *fh, struct dictionary *dict, w->digits = DBL_DIG; } + /* Lock file. */ + /* TRANSLATORS: this fragment will be interpolated into + messages in fh_lock() that identify types of files. */ + w->lock = fh_lock (fh, FH_REF_FILE, N_("portable file"), FH_ACC_WRITE, true); + if (w->lock == NULL) + goto error; + + /* Create file. */ + mode = S_IRUSR | S_IRGRP | S_IROTH; + if (opts.create_writeable) + mode |= S_IWUSR | S_IWGRP | S_IWOTH; + w->rf = replace_file_start (fh_get_file_name (fh), "w", mode, + &w->file, NULL); + if (w->rf == NULL) + { + msg (ME, _("Error opening \"%s\" for writing as a portable file: %s."), + fh_get_file_name (fh), strerror (errno)); + goto error; + } + /* Write file header. */ write_header (w); write_version_data (w); @@ -166,17 +172,12 @@ pfm_open_writer (struct file_handle *fh, struct dictionary *dict, buf_write (w, "F", 1); if (ferror (w->file)) goto error; - return casewriter_create (&por_file_casewriter_class, w); + return casewriter_create (dict_get_next_value_idx (dict), + &por_file_casewriter_class, w); - error: +error: close_writer (w); return NULL; - - open_error: - msg (ME, _("An error occurred while opening \"%s\" for writing " - "as a portable file: %s."), - fh_get_file_name (fh), strerror (errno)); - goto error; } /* Write NBYTES starting at BUF to the portable file represented by @@ -497,9 +498,13 @@ close_writer (struct pfm_writer *w) if (!ok) msg (ME, _("An I/O error occurred writing portable file \"%s\"."), fh_get_file_name (w->fh)); + + if (ok ? !replace_file_commit (w->rf) : !replace_file_abort (w->rf)) + ok = false; } - fh_close (w->fh, "portable file", "we"); + fh_unlock (w->lock); + fh_unref (w->fh); free (w->vars); free (w); @@ -772,7 +777,7 @@ format_trig_double (long double value, int base_10_precision, char output[]) 0...30**6, an invariant of the loop below. */ errno = 0; base_2_sig = frexp (value, &base_2_exp); - if (errno != 0 || !finite (base_2_sig)) + if (errno != 0 || !isfinite (base_2_sig)) goto missing_value; if (base_2_exp == 0 && base_2_sig == 0.) goto zero; @@ -893,7 +898,7 @@ format_trig_double (long double value, int base_10_precision, char output[]) return; } -static struct casewriter_class por_file_casewriter_class = +static const struct casewriter_class por_file_casewriter_class = { por_file_casewriter_write, por_file_casewriter_destroy,