Blame support/temp_file.c

Packit Service 82fcde
/* Temporary file handling for tests.
Packit Service 82fcde
   Copyright (C) 1998-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/* This is required to get an mkstemp which can create large files on
Packit Service 82fcde
   some 32-bit platforms. */
Packit Service 82fcde
#define _FILE_OFFSET_BITS 64
Packit Service 82fcde
Packit Service 82fcde
#include <support/temp_file.h>
Packit Service 82fcde
#include <support/temp_file-internal.h>
Packit Service 82fcde
#include <support/support.h>
Packit Service 82fcde
Packit Service 82fcde
#include <paths.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
Packit Service 82fcde
/* List of temporary files.  */
Packit Service 82fcde
static struct temp_name_list
Packit Service 82fcde
{
Packit Service 82fcde
  struct temp_name_list *next;
Packit Service 82fcde
  char *name;
Packit Service 82fcde
  pid_t owner;
Packit Service 82fcde
} *temp_name_list;
Packit Service 82fcde
Packit Service 82fcde
/* Location of the temporary files.  Set by the test skeleton via
Packit Service 82fcde
   support_set_test_dir.  The string is not be freed.  */
Packit Service 82fcde
static const char *test_dir = _PATH_TMP;
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
add_temp_file (const char *name)
Packit Service 82fcde
{
Packit Service 82fcde
  struct temp_name_list *newp
Packit Service 82fcde
    = (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
Packit Service 82fcde
  char *newname = strdup (name);
Packit Service 82fcde
  if (newname != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      newp->name = newname;
Packit Service 82fcde
      newp->next = temp_name_list;
Packit Service 82fcde
      newp->owner = getpid ();
Packit Service 82fcde
      temp_name_list = newp;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    free (newp);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
create_temp_file (const char *base, char **filename)
Packit Service 82fcde
{
Packit Service 82fcde
  char *fname;
Packit Service 82fcde
  int fd;
Packit Service 82fcde
Packit Service 82fcde
  fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base)
Packit Service 82fcde
			    + sizeof ("XXXXXX"));
Packit Service 82fcde
  strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX");
Packit Service 82fcde
Packit Service 82fcde
  fd = mkstemp (fname);
Packit Service 82fcde
  if (fd == -1)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("cannot open temporary file '%s': %m\n", fname);
Packit Service 82fcde
      free (fname);
Packit Service 82fcde
      return -1;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  add_temp_file (fname);
Packit Service 82fcde
  if (filename != NULL)
Packit Service 82fcde
    *filename = fname;
Packit Service 82fcde
  else
Packit Service 82fcde
    free (fname);
Packit Service 82fcde
Packit Service 82fcde
  return fd;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
char *
Packit Service 82fcde
support_create_temp_directory (const char *base)
Packit Service 82fcde
{
Packit Service 82fcde
  char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
Packit Service 82fcde
  if (mkdtemp (path) == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      printf ("error: mkdtemp (\"%s\"): %m", path);
Packit Service 82fcde
      exit (1);
Packit Service 82fcde
    }
Packit Service 82fcde
  add_temp_file (path);
Packit Service 82fcde
  return path;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Helper functions called by the test skeleton follow.  */
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
support_set_test_dir (const char *path)
Packit Service 82fcde
{
Packit Service 82fcde
  test_dir = path;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
support_delete_temp_files (void)
Packit Service 82fcde
{
Packit Service 82fcde
  pid_t pid = getpid ();
Packit Service 82fcde
  while (temp_name_list != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Only perform the removal if the path was registed in the same
Packit Service 82fcde
	 process, as identified by the PID.  (This assumes that the
Packit Service 82fcde
	 parent process which registered the temporary file sticks
Packit Service 82fcde
	 around, to prevent PID reuse.)  */
Packit Service 82fcde
      if (temp_name_list->owner == pid)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (remove (temp_name_list->name) != 0)
Packit Service 82fcde
	    printf ("warning: could not remove temporary file: %s: %m\n",
Packit Service 82fcde
		    temp_name_list->name);
Packit Service 82fcde
	}
Packit Service 82fcde
      free (temp_name_list->name);
Packit Service 82fcde
Packit Service 82fcde
      struct temp_name_list *next = temp_name_list->next;
Packit Service 82fcde
      free (temp_name_list);
Packit Service 82fcde
      temp_name_list = next;
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
support_print_temp_files (FILE *f)
Packit Service 82fcde
{
Packit Service 82fcde
  if (temp_name_list != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct temp_name_list *n;
Packit Service 82fcde
      fprintf (f, "temp_files=(\n");
Packit Service 82fcde
      for (n = temp_name_list; n != NULL; n = n->next)
Packit Service 82fcde
        fprintf (f, "  '%s'\n", n->name);
Packit Service 82fcde
      fprintf (f, ")\n");
Packit Service 82fcde
    }
Packit Service 82fcde
}