-
-#ifdef HAVE_MKDTEMP
-/* Creates and returns the name of a temporary directory. */
-static char *
-make_temp_dir (void)
-{
- const char *parent_dir;
- char *temp_dir;
-
- if (getenv ("TMPDIR") != NULL)
- parent_dir = getenv ("TMPDIR");
- else
- parent_dir = P_tmpdir;
-
- temp_dir = xmalloc (strlen (parent_dir) + 32);
- sprintf (temp_dir, "%s%cpsppXXXXXX", parent_dir, DIR_SEPARATOR);
- if (mkdtemp (temp_dir) == NULL)
- {
- msg (SE, _("%s: Creating temporary directory: %s."),
- temp_dir, strerror (errno));
- free (temp_dir);
- return NULL;
- }
- else
- return temp_dir;
-}
-#else /* !HAVE_MKDTEMP */
-/* Creates directory DIR. */
-static int
-do_mkdir (const char *dir)
-{
-#ifndef __MSDOS__
- return mkdir (dir, S_IRWXU);
-#else
- return mkdir (dir);
-#endif
-}
-
-/* Creates and returns the name of a temporary directory. */
-static char *
-make_temp_dir (void)
-{
- int i;
-
- for (i = 0; i < 100; i++)
- {
- char temp_dir[L_tmpnam + 1];
- if (tmpnam (temp_dir) == NULL)
- {
- msg (SE, _("Generating temporary directory name failed: %s."),
- strerror (errno));
- return NULL;
- }
- else if (do_mkdir (temp_dir) == 0)
- return xstrdup (temp_dir);
- }
-
- msg (SE, _("Creating temporary directory failed: %s."), strerror (errno));
- return NULL;
-}
-#endif /* !HAVE_MKDTEMP */
-
-/* Sets up to open temporary files. */
-static int
-init_external_sort (struct external_sort *xsrt)
-{
- /* Zero. */
- xsrt->temp_dir = NULL;
- xsrt->next_file_idx = 0;
-
- /* Huffman queue. */
- xsrt->run_cap = 512;
- xsrt->run_cnt = 0;
- xsrt->initial_runs = xmalloc (sizeof *xsrt->initial_runs * xsrt->run_cap);
-
- /* Temporary directory. */
- xsrt->temp_dir = make_temp_dir ();
- xsrt->temp_name = NULL;
- if (xsrt->temp_dir == NULL)
- return 0;
- xsrt->temp_name = xmalloc (strlen (xsrt->temp_dir) + 64);
-
- return 1;
-}
-
-/* Returns nonzero if we should return an error even though the
- operation succeeded. Useful for testing. */
-static int
-simulate_error (void)
-{
- static int op_err_cnt = -1;
- static int op_cnt;
-
- if (op_err_cnt == -1 || op_cnt++ < op_err_cnt)
- return 0;
- else
- {
- errno = 0;
- return 1;
- }
-}
-
-/* Removes the directory created for temporary files, if one
- exists. */
-static void
-rmdir_temp_dir (struct external_sort *xsrt)
-{
- if (xsrt->temp_dir != NULL && rmdir (xsrt->temp_dir) == -1)
- {
- msg (SW, _("%s: Error removing directory for temporary files: %s."),
- xsrt->temp_dir, strerror (errno));
- xsrt->temp_dir = NULL;
- }
-}
-
-/* Returns the name of temporary file number FILE_IDX for XSRT.
- The name is written into a static buffer, so be careful. */
-static char *
-get_temp_file_name (struct external_sort *xsrt, int file_idx)
-{
- assert (xsrt->temp_dir != NULL);
- sprintf (xsrt->temp_name, "%s%c%04d",
- xsrt->temp_dir, DIR_SEPARATOR, file_idx);
- return xsrt->temp_name;
-}
-
-/* Opens temporary file numbered FILE_IDX for XSRT with mode MODE
- and returns the FILE *. */
-static FILE *
-open_temp_file (struct external_sort *xsrt, int file_idx, const char *mode)
-{
- char *temp_file;
- FILE *file;
-
- temp_file = get_temp_file_name (xsrt, file_idx);
-
- file = fopen (temp_file, mode);
- if (simulate_error () || file == NULL)
- msg (SE, _("%s: Error opening temporary file for %s: %s."),
- temp_file, mode[0] == 'r' ? "reading" : "writing",
- strerror (errno));
-
- return file;
-}
-
-/* Closes FILE, which is the temporary file numbered FILE_IDX
- under XSRT. Returns nonzero only if successful. */
-static int
-close_temp_file (struct external_sort *xsrt, int file_idx, FILE *file)
-{
- if (file != NULL)
- {
- char *temp_file = get_temp_file_name (xsrt, file_idx);
- if (simulate_error () || fclose (file) == EOF)
- {
- msg (SE, _("%s: Error closing temporary file: %s."),
- temp_file, strerror (errno));
- return 0;
- }
- }
- return 1;
-}
-
-/* Delete temporary file numbered FILE_IDX for XSRT. */
-static void
-remove_temp_file (struct external_sort *xsrt, int file_idx)
-{
- if (file_idx != -1)
- {
- char *temp_file = get_temp_file_name (xsrt, file_idx);
- if (simulate_error () || remove (temp_file) != 0)
- msg (SW, _("%s: Error removing temporary file: %s."),
- temp_file, strerror (errno));
- }
-}
-
-/* Writes SIZE bytes from buffer DATA into FILE, which is
- temporary file numbered FILE_IDX from XSRT. */
-static int
-write_temp_file (struct external_sort *xsrt, int file_idx,
- FILE *file, const void *data, size_t size)
-{
- if (!simulate_error () && fwrite (data, size, 1, file) == 1)
- return 1;
- else
- {
- char *temp_file = get_temp_file_name (xsrt, file_idx);
- msg (SE, _("%s: Error writing temporary file: %s."),
- temp_file, strerror (errno));
- return 0;
- }
-}
-
-/* Reads SIZE bytes into buffer DATA into FILE, which is
- temporary file numbered FILE_IDX from XSRT. */
-static int
-read_temp_file (struct external_sort *xsrt, int file_idx,
- FILE *file, void *data, size_t size)
-{
- if (!simulate_error () && fread (data, size, 1, file) == 1)
- return 1;
- else
- {
- char *temp_file = get_temp_file_name (xsrt, file_idx);
- if (ferror (file))
- msg (SE, _("%s: Error reading temporary file: %s."),
- temp_file, strerror (errno));
- else
- msg (SE, _("%s: Unexpected end of temporary file."),
- temp_file);
- return 0;
- }
-}