X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fsys-file-writer.c;h=acf9d5c0b681d4d702a52b81b6798bc93a54358c;hb=a9acce47d67e0ab35ce1690e4f1b1ac0121c2d78;hp=b21053c216a54c5fa3181d161d6cd795ec5ed0d0;hpb=c3bd77adba5746aae895e6a354aada4e694c0e3f;p=pspp diff --git a/src/data/sys-file-writer.c b/src/data/sys-file-writer.c index b21053c216..acf9d5c0b6 100644 --- a/src/data/sys-file-writer.c +++ b/src/data/sys-file-writer.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -41,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -49,9 +49,11 @@ #include "minmax.h" #include "unlocked-io.h" +#include "xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) +#define N_(msgid) (msgid) /* Compression bias used by PSPP. Values between (1 - COMPRESSION_BIAS) and (251 - COMPRESSION_BIAS) inclusive can be @@ -62,7 +64,9 @@ struct sfm_writer { struct file_handle *fh; /* File handle. */ + struct fh_lock *lock; /* Mutual exclusion for file. */ FILE *file; /* File stream. */ + struct replace_file *rf; /* Ticket for replacing output file. */ bool compress; /* 1=compressed, 0=not compressed. */ casenumber case_cnt; /* Number of cases written so far. */ @@ -148,9 +152,8 @@ struct casewriter * sfm_open_writer (struct file_handle *fh, struct dictionary *d, struct sfm_write_options opts) { - struct sfm_writer *w = NULL; + struct sfm_writer *w; mode_t mode; - FILE *file; int idx; int i; @@ -162,27 +165,12 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, opts.version = 3; } - /* Open file handle as an exclusive writer. */ - if (!fh_open (fh, FH_REF_FILE, "system file", "we")) - return NULL; - - /* Create the file on disk. */ - mode = S_IRUSR | S_IRGRP | S_IROTH; - if (opts.create_writeable) - mode |= S_IWUSR | S_IWGRP | S_IWOTH; - file = create_stream (fh_get_file_name (fh), "w", mode); - if (file == NULL) - { - msg (ME, _("Error opening \"%s\" for writing as a system file: %s."), - fh_get_file_name (fh), strerror (errno)); - fh_close (fh, "system file", "we"); - return NULL; - } - /* Create and initialize writer. */ w = xmalloc (sizeof *w); - w->fh = fh; - w->file = file; + w->fh = fh_ref (fh); + w->lock = NULL; + w->file = NULL; + w->rf = NULL; w->compress = opts.compress; w->case_cnt = 0; @@ -196,6 +184,26 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, w->segment_cnt = sfm_dictionary_to_sfm_vars (d, &w->sfm_vars, &w->sfm_var_cnt); + /* Open file handle as an exclusive writer. */ + /* 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_("system file"), FH_ACC_WRITE, true); + if (w->lock == NULL) + goto error; + + /* Create the file on disk. */ + 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), "wb", mode, + &w->file, NULL); + if (w->rf == NULL) + { + msg (ME, _("Error opening \"%s\" for writing as a system file: %s."), + fh_get_file_name (fh), strerror (errno)); + goto error; + } + /* Write the file header. */ write_header (w, d); @@ -239,6 +247,10 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, return casewriter_create (dict_get_next_value_idx (d), &sys_file_casewriter_class, w); + +error: + close_writer (w); + return NULL; } /* Returns value of X truncated to two least-significant digits. */ @@ -433,14 +445,14 @@ write_variable (struct sfm_writer *w, const struct variable *v) if (mv_has_range (mv)) { double x, y; - mv_peek_range (mv, &x, &y); + mv_get_range (mv, &x, &y); write_float (w, x); write_float (w, y); } for (i = 0; i < mv_n_values (mv); i++) { union value value; - mv_peek_value (mv, &value, i); + mv_get_value (mv, &value, i); write_value (w, &value, seg0_width); } @@ -724,9 +736,13 @@ close_writer (struct sfm_writer *w) if (!ok) msg (ME, _("An I/O error occurred writing system 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, "system file", "we"); + fh_unlock (w->lock); + fh_unref (w->fh); free (w->sfm_vars); free (w);