#if defined _WIN32 || defined __WIN32__
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
-#define UNICODE 1
#include <windows.h>
#define TS_stat _stat
#define Tunlink _wunlink
return -1;
}
-static TCHAR *
+TCHAR *
convert_to_filename_encoding (const char *s, size_t len, const char *current_encoding)
{
const char *enc = current_encoding;
- if (0 == strcmp (current_encoding, "Auto"))
+ if (NULL == enc || 0 == strcmp (enc, "Auto"))
enc = locale_charset ();
return (TCHAR *) recode_string ("UTF-16LE", enc, s, len);
#else
-typedef char TCHAR;
#define TS_stat stat
#define Trename rename
#define Tunlink unlink
#define Topen open
#define Tstat stat
-static TCHAR *
+TCHAR *
convert_to_filename_encoding (const char *s, size_t len UNUSED, const char *current_encoding UNUSED)
{
- /* Non-windows systems don't care about the encoding.
+ /* Non-windows systems don't care about the encoding.
The string is copied here, to be consistent with the w32 case. */
return xstrdup (s);
}
char *tmp_name_verbatim;
const char *file_name_verbatim;
};
-
+
static struct ll_list all_files = LL_INITIALIZER (all_files);
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);
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;
+ saved_errno = errno;
msg (ME, _("Opening %s for writing: %s."),
file_name, strerror (saved_errno));
free (Tfile_name);
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;
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)
{
}
+ /* 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;
}