/* Temporary file handling for tests.
   Copyright (C) 1998-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

/* This is required to get an mkstemp which can create large files on
   some 32-bit platforms. */
#define _FILE_OFFSET_BITS 64

#include <support/temp_file.h>
#include <support/temp_file-internal.h>
#include <support/support.h>

#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* List of temporary files.  */
static struct temp_name_list
{
  struct temp_name_list *next;
  char *name;
  pid_t owner;
} *temp_name_list;

/* Location of the temporary files.  Set by the test skeleton via
   support_set_test_dir.  The string is not be freed.  */
static const char *test_dir = _PATH_TMP;

void
add_temp_file (const char *name)
{
  struct temp_name_list *newp
    = (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
  char *newname = strdup (name);
  if (newname != NULL)
    {
      newp->name = newname;
      newp->next = temp_name_list;
      newp->owner = getpid ();
      temp_name_list = newp;
    }
  else
    free (newp);
}

int
create_temp_file (const char *base, char **filename)
{
  char *fname;
  int fd;

  fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base)
			    + sizeof ("XXXXXX"));
  strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");

  fd = mkstemp (fname);
  if (fd == -1)
    {
      printf ("cannot open temporary file '%s': %m\n", fname);
      free (fname);
      return -1;
    }

  add_temp_file (fname);
  if (filename != NULL)
    *filename = fname;
  else
    free (fname);

  return fd;
}

char *
support_create_temp_directory (const char *base)
{
  char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
  if (mkdtemp (path) == NULL)
    {
      printf ("error: mkdtemp (\"%s\"): %m", path);
      exit (1);
    }
  add_temp_file (path);
  return path;
}

/* Helper functions called by the test skeleton follow.  */

void
support_set_test_dir (const char *path)
{
  test_dir = path;
}

void
support_delete_temp_files (void)
{
  pid_t pid = getpid ();
  while (temp_name_list != NULL)
    {
      /* Only perform the removal if the path was registed in the same
	 process, as identified by the PID.  (This assumes that the
	 parent process which registered the temporary file sticks
	 around, to prevent PID reuse.)  */
      if (temp_name_list->owner == pid)
	{
	  if (remove (temp_name_list->name) != 0)
	    printf ("warning: could not remove temporary file: %s: %m\n",
		    temp_name_list->name);
	}
      free (temp_name_list->name);

      struct temp_name_list *next = temp_name_list->next;
      free (temp_name_list);
      temp_name_list = next;
    }
}

void
support_print_temp_files (FILE *f)
{
  if (temp_name_list != NULL)
    {
      struct temp_name_list *n;
      fprintf (f, "temp_files=(\n");
      for (n = temp_name_list; n != NULL; n = n->next)
        fprintf (f, "  '%s'\n", n->name);
      fprintf (f, ")\n");
    }
}
