/* Copyright (C) 2000-2014 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/>.  */

#include <errno.h>
#include <fcntl.h>
#include <mntent.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/statfs.h>
#include <bits/libc-lock.h>
#include "linux_fsinfo.h"

#include <kernel-features.h>


/* Mount point of the shared memory filesystem.  */
static struct
{
  char *dir;
  size_t dirlen;
} mountpoint;

/* This is the default directory.  */
static const char defaultdir[] = "/dev/shm/";

/* Protect the `mountpoint' variable above.  */
__libc_once_define (static, once);


#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
static bool have_o_cloexec;
#endif


/* Determine where the shmfs is mounted (if at all).  */
static void
where_is_shmfs (void)
{
  char buf[512];
  struct statfs f;
  struct mntent resmem;
  struct mntent *mp;
  FILE *fp;

  /* The canonical place is /dev/shm.  This is at least what the
     documentation tells everybody to do.  */
  if (__statfs (defaultdir, &f) == 0 && f.f_type == SHMFS_SUPER_MAGIC)
    {
      /* It is in the normal place.  */
      mountpoint.dir = (char *) defaultdir;
      mountpoint.dirlen = sizeof (defaultdir) - 1;

      return;
    }

  /* OK, do it the hard way.  Look through the /proc/mounts file and if
     this does not exist through /etc/fstab to find the mount point.  */
  fp = __setmntent ("/proc/mounts", "r");
  if (__builtin_expect (fp == NULL, 0))
    {
      fp = __setmntent (_PATH_MNTTAB, "r");
      if (__builtin_expect (fp == NULL, 0))
	/* There is nothing we can do.  Blind guesses are not helpful.  */
	return;
    }

  /* Now read the entries.  */
  while ((mp = __getmntent_r (fp, &resmem, buf, sizeof buf)) != NULL)
    /* The original name is "shm" but this got changed in early Linux
       2.4.x to "tmpfs".  */
    if (strcmp (mp->mnt_type, "tmpfs") == 0)
      {
	/* Found it.  There might be more than one place where the
           filesystem is mounted but one is enough for us.  */
	size_t namelen;

	/* First make sure this really is the correct entry.  At least
	   some versions of the kernel give wrong information because
	   of the implicit mount of the shmfs for SysV IPC.  */
	if (__statfs (mp->mnt_dir, &f) != 0 || f.f_type != SHMFS_SUPER_MAGIC)
	  continue;

	namelen = strlen (mp->mnt_dir);

	if (namelen == 0)
	  /* Hum, maybe some crippled entry.  Keep on searching.  */
	  continue;

	mountpoint.dir = (char *) malloc (namelen + 2);
	if (mountpoint.dir != NULL)
	  {
	    char *cp = __mempcpy (mountpoint.dir, mp->mnt_dir, namelen);
	    if (cp[-1] != '/')
	      *cp++ = '/';
	    *cp = '\0';
	    mountpoint.dirlen = cp - mountpoint.dir;
	  }

	break;
      }

  /* Close the stream.  */
  __endmntent (fp);
}


/* Open shared memory object.  This implementation assumes the shmfs
   implementation introduced in the late 2.3.x kernel series to be
   available.  Normally the filesystem will be mounted at /dev/shm but
   we fall back on searching for the actual mount point should opening
   such a file fail.  */
int
shm_open (const char *name, int oflag, mode_t mode)
{
  size_t namelen;
  char *fname;
  int fd;

  /* Determine where the shmfs is mounted.  */
  __libc_once (once, where_is_shmfs);

  /* If we don't know the mount points there is nothing we can do.  Ever.  */
  if (mountpoint.dir == NULL)
    {
      __set_errno (ENOSYS);
      return -1;
    }

  /* Construct the filename.  */
  while (name[0] == '/')
    ++name;

  namelen = strlen (name);

  /* Validate the filename.  */
  if (name[0] == '\0' || namelen > NAME_MAX || strchr (name, '/') != NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
  __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
	     name, namelen + 1);

#ifdef O_CLOEXEC
  oflag |= O_CLOEXEC;
#endif

  /* And get the file descriptor.
     XXX Maybe we should test each descriptor whether it really is for a
     file on the shmfs.  If this is what should be done the whole function
     should be revamped since we can determine whether shmfs is available
     while trying to open the file, all in one turn.  */
  fd = open (fname, oflag | O_NOFOLLOW, mode);
  if (fd != -1)
    {
#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
# ifdef O_CLOEXEC
      if (have_o_cloexec <= 0)
# endif
	{
	  /* We got a descriptor.  Now set the FD_CLOEXEC bit.  */
	  int flags = fcntl (fd, F_GETFD, 0);

	  if (__builtin_expect (flags, 0) >= 0)
	    {
# ifdef O_CLOEXEC
	      if (have_o_cloexec == 0)
		have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
	      if (have_o_cloexec < 0)
# endif
		{
		  flags |= FD_CLOEXEC;
		  flags = fcntl (fd, F_SETFD, flags);
		}
	    }

	  if (flags == -1)
	    {
	      /* Something went wrong.  We cannot return the descriptor.  */
	      int save_errno = errno;
	      close (fd);
	      fd = -1;
	      __set_errno (save_errno);
	    }
	}
#endif
    }
  else if (__builtin_expect (errno == EISDIR, 0))
    /* It might be better to fold this error with EINVAL since
       directory names are just another example for unsuitable shared
       object names and the standard does not mention EISDIR.  */
    __set_errno (EINVAL);

  return fd;
}


/* Unlink a shared memory object.  */
int
shm_unlink (const char *name)
{
  size_t namelen;
  char *fname;

  /* Determine where the shmfs is mounted.  */
  __libc_once (once, where_is_shmfs);

  if (mountpoint.dir == NULL)
    {
      /* We cannot find the shmfs.  If `name' is really a shared
	 memory object it must have been created by another process
	 and we have no idea where that process found the mountpoint.  */
      __set_errno (ENOENT);
      return -1;
    }

  /* Construct the filename.  */
  while (name[0] == '/')
    ++name;

  namelen = strlen (name);

  /* Validate the filename.  */
  if (name[0] == '\0' || namelen > NAME_MAX || strchr (name, '/') != NULL)
    {
      __set_errno (ENOENT);
      return -1;
    }

  fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
  __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
	     name, namelen + 1);

  /* And remove the file.  */
  int ret = unlink (fname);
  if (ret < 0 && errno == EPERM)
    __set_errno (EACCES);
  return ret;
}


/* Make sure the table is freed if we want to free everything before
   exiting.  */
libc_freeres_fn (freeit)
{
  if (mountpoint.dir != defaultdir)
    free (mountpoint.dir);
}
