Example #1
0
static int
lock_file_1 (char *lfname, int force)
{
  int err;
  int symlink_errno;
  USE_SAFE_ALLOCA;

  /* Call this first because it can GC.  */
  printmax_t boot = get_boot_time ();

  Lisp_Object luser_name = Fuser_login_name (Qnil);
  char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : "";
  Lisp_Object lhost_name = Fsystem_name ();
  char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : "";
  ptrdiff_t lock_info_size = (strlen (user_name) + strlen (host_name)
			      + 2 * INT_STRLEN_BOUND (printmax_t)
			      + sizeof "@.:");
  char *lock_info_str = SAFE_ALLOCA (lock_info_size);
  printmax_t pid = getpid ();

  esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd,
	    user_name, host_name, pid, boot);

  err = symlink (lock_info_str, lfname);
  if (errno == EEXIST && force)
    {
      unlink (lfname);
      err = symlink (lock_info_str, lfname);
    }

  symlink_errno = errno;
  SAFE_FREE ();
  errno = symlink_errno;
  return err == 0;
}
Example #2
0
static int
lock_file_1 (char *lfname, int force)
{
  register int err;
  time_t boot;
  const char *user_name;
  const char *host_name;
  char *lock_info_str;

  /* Call this first because it can GC.  */
  boot = get_boot_time ();

  if (STRINGP (Fuser_login_name (Qnil)))
    user_name = SSDATA (Fuser_login_name (Qnil));
  else
    user_name = "";
  if (STRINGP (Fsystem_name ()))
    host_name = SSDATA (Fsystem_name ());
  else
    host_name = "";
  lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
				  + LOCK_PID_MAX + 30);

  if (boot)
    sprintf (lock_info_str, "%s@%s.%lu:%lu", user_name, host_name,
	     (unsigned long) getpid (), (unsigned long) boot);
  else
    sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name,
	     (unsigned long) getpid ());

  err = symlink (lock_info_str, lfname);
  if (errno == EEXIST && force)
    {
      unlink (lfname);
      err = symlink (lock_info_str, lfname);
    }

  return err == 0;
}
Example #3
0
static int
current_lock_owner (lock_info_type *owner, char *lfname)
{
  int ret;
  ptrdiff_t len;
  lock_info_type local_owner;
  intmax_t n;
  char *at, *dot, *colon;
  char readlink_buf[READLINK_BUFSIZE];
  char *lfinfo = emacs_readlink (lfname, readlink_buf);

  /* If nonexistent lock file, all is well; otherwise, got strange error. */
  if (!lfinfo)
    return errno == ENOENT ? 0 : -1;

  /* Even if the caller doesn't want the owner info, we still have to
     read it to determine return value.  */
  if (!owner)
    owner = &local_owner;

  /* Parse [email protected]:BOOT_TIME.  If can't parse, return -1.  */
  /* The USER is everything before the last @.  */
  at = strrchr (lfinfo, '@');
  dot = strrchr (lfinfo, '.');
  if (!at || !dot)
    {
      if (lfinfo != readlink_buf)
	xfree (lfinfo);
      return -1;
    }
  len = at - lfinfo;
  owner->user = xmalloc (len + 1);
  memcpy (owner->user, lfinfo, len);
  owner->user[len] = 0;

  /* The PID is everything from the last `.' to the `:'.  */
  errno = 0;
  n = strtoimax (dot + 1, NULL, 10);
  owner->pid =
    ((0 <= n && n <= TYPE_MAXIMUM (pid_t)
      && (TYPE_MAXIMUM (pid_t) < INTMAX_MAX || errno != ERANGE))
     ? n : 0);

  colon = strchr (dot + 1, ':');
  /* After the `:', if there is one, comes the boot time.  */
  n = 0;
  if (colon)
    {
      errno = 0;
      n = strtoimax (colon + 1, NULL, 10);
    }
  owner->boot_time =
    ((0 <= n && n <= TYPE_MAXIMUM (time_t)
      && (TYPE_MAXIMUM (time_t) < INTMAX_MAX || errno != ERANGE))
     ? n : 0);

  /* The host is everything in between.  */
  len = dot - at - 1;
  owner->host = xmalloc (len + 1);
  memcpy (owner->host, at + 1, len);
  owner->host[len] = 0;

  /* We're done looking at the link info.  */
  if (lfinfo != readlink_buf)
    xfree (lfinfo);

  /* On current host?  */
  if (STRINGP (Fsystem_name ())
      && strcmp (owner->host, SSDATA (Fsystem_name ())) == 0)
    {
      if (owner->pid == getpid ())
        ret = 2; /* We own it.  */
      else if (owner->pid > 0
               && (kill (owner->pid, 0) >= 0 || errno == EPERM)
	       && (owner->boot_time == 0
		   || within_one_second (owner->boot_time, get_boot_time ())))
        ret = 1; /* An existing process on this machine owns it.  */
      /* The owner process is dead or has a strange pid (<=0), so try to
         zap the lockfile.  */
      else if (unlink (lfname) < 0)
        ret = -1;
      else
	ret = 0;
    }
  else
    { /* If we wanted to support the check for stale locks on remote machines,
         here's where we'd do it.  */
      ret = 1;
    }

  /* Avoid garbage.  */
  if (owner == &local_owner || ret <= 0)
    {
      FREE_LOCK_INFO (*owner);
    }
  return ret;
}
Example #4
0
static int
current_lock_owner (lock_info_type *owner, char *lfname)
{
  int len, ret;
  int local_owner = 0;
  char *at, *dot, *colon;
  char *lfinfo = 0;
  int bufsize = 50;
  /* Read arbitrarily-long contents of symlink.  Similar code in
     file-symlink-p in fileio.c.  */
  do
    {
      bufsize *= 2;
      lfinfo = (char *) xrealloc (lfinfo, bufsize);
      errno = 0;
      len = readlink (lfname, lfinfo, bufsize);
#ifdef ERANGE
      /* HP-UX reports ERANGE if the buffer is too small.  */
      if (len == -1 && errno == ERANGE)
	len = bufsize;
#endif
    }
  while (len >= bufsize);

  /* If nonexistent lock file, all is well; otherwise, got strange error. */
  if (len == -1)
    {
      xfree (lfinfo);
      return errno == ENOENT ? 0 : -1;
    }

  /* Link info exists, so `len' is its length.  Null terminate.  */
  lfinfo[len] = 0;

  /* Even if the caller doesn't want the owner info, we still have to
     read it to determine return value, so allocate it.  */
  if (!owner)
    {
      owner = (lock_info_type *) alloca (sizeof (lock_info_type));
      local_owner = 1;
    }

  /* Parse [email protected]:BOOT_TIME.  If can't parse, return -1.  */
  /* The USER is everything before the last @.  */
  at = strrchr (lfinfo, '@');
  dot = strrchr (lfinfo, '.');
  if (!at || !dot)
    {
      xfree (lfinfo);
      return -1;
    }
  len = at - lfinfo;
  owner->user = (char *) xmalloc (len + 1);
  strncpy (owner->user, lfinfo, len);
  owner->user[len] = 0;

  /* The PID is everything from the last `.' to the `:'.  */
  owner->pid = atoi (dot + 1);
  colon = dot;
  while (*colon && *colon != ':')
    colon++;
  /* After the `:', if there is one, comes the boot time.  */
  if (*colon == ':')
    owner->boot_time = atoi (colon + 1);
  else
    owner->boot_time = 0;

  /* The host is everything in between.  */
  len = dot - at - 1;
  owner->host = (char *) xmalloc (len + 1);
  strncpy (owner->host, at + 1, len);
  owner->host[len] = 0;

  /* We're done looking at the link info.  */
  xfree (lfinfo);

  /* On current host?  */
  if (STRINGP (Fsystem_name ())
      && strcmp (owner->host, SSDATA (Fsystem_name ())) == 0)
    {
      if (owner->pid == getpid ())
        ret = 2; /* We own it.  */
      else if (owner->pid > 0
               && (kill (owner->pid, 0) >= 0 || errno == EPERM)
	       && (owner->boot_time == 0
		   || within_one_second (owner->boot_time, get_boot_time ())))
        ret = 1; /* An existing process on this machine owns it.  */
      /* The owner process is dead or has a strange pid (<=0), so try to
         zap the lockfile.  */
      else if (unlink (lfname) < 0)
        ret = -1;
      else
	ret = 0;
    }
  else
    { /* If we wanted to support the check for stale locks on remote machines,
         here's where we'd do it.  */
      ret = 1;
    }

  /* Avoid garbage.  */
  if (local_owner || ret <= 0)
    {
      FREE_LOCK_INFO (*owner);
    }
  return ret;
}