Exemple #1
0
char	*my_open(t_shell *shell, t_array *array, char **env, int *indicateur)
{
  int	i;
  char	*path;

  i = -1;
  if (all_check(shell, array, env) == 0)
    {
      if (shell->buffer[0][0] == '.')
	my_exec(shell, array, env);
      else
	{
	  while (shell->tab_path[++i] != NULL)
	    {
	      path = my_strcat(shell->tab_path[i], "/");
	      if ((access(
my_strcat(shell->tab_path[i], shell->buffer[0]), F_OK) == 0))
		{
		  *indicateur = *indicateur + 1;
		  return (path);
		}
	    }
	  my_error_2(shell->buffer[0]);
	}
    }
}
Exemple #2
0
/* Locking core for Windows.  This version does not need a temporary
   file but uses the plain lock file along with record locking.  We
   create this file here so that we later only need to do the file
   locking.  For error reporting it is useful to keep the name of the
   file in the handle.  */
static dotlock_t
dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
{
  LOCK_all_lockfiles ();
  h->next = all_lockfiles;
  all_lockfiles = h;

  h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 );
  if (!h->lockname)
    {
      all_lockfiles = h->next;
      UNLOCK_all_lockfiles ();
      jnlib_free (h);
      return NULL;
    }
  strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");

  /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
     along with FILE_SHARE_DELETE but that does not work due to a race
     condition: Despite the OPEN_ALWAYS flag CreateFile may return an
     error and we can't reliable create/open the lock file unless we
     would wait here until it works - however there are other valid
     reasons why a lock file can't be created and thus the process
     would not stop as expected but spin until Windows crashes.  Our
     solution is to keep the lock file open; that does not harm. */
  {
#ifdef HAVE_W32CE_SYSTEM
    wchar_t *wname = utf8_to_wchar (h->lockname);

    if (wname)
      h->lockhd = CreateFile (wname,
                              GENERIC_READ|GENERIC_WRITE,
                              FILE_SHARE_READ|FILE_SHARE_WRITE,
                              NULL, OPEN_ALWAYS, 0, NULL);
    else
      h->lockhd = INVALID_HANDLE_VALUE;
    jnlib_free (wname);
#else
    h->lockhd = CreateFile (h->lockname,
                            GENERIC_READ|GENERIC_WRITE,
                            FILE_SHARE_READ|FILE_SHARE_WRITE,
                            NULL, OPEN_ALWAYS, 0, NULL);
#endif
  }
  if (h->lockhd == INVALID_HANDLE_VALUE)
    {
      all_lockfiles = h->next;
      UNLOCK_all_lockfiles ();
      my_error_2 (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1));
      jnlib_free (h->lockname);
      jnlib_free (h);
      return NULL;
    }
  return h;
}
Exemple #3
0
/* Windows specific code of make_dotlock.  Returns 0 on success and -1 on
   error.  */
static int
dotlock_take_w32 (dotlock_t h, long timeout)
{
  int wtime = 0;
  int w32err;
  OVERLAPPED ovl;

 again:
  /* Lock one byte at offset 0.  The offset is given by OVL.  */
  memset (&ovl, 0, sizeof ovl);
  if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
                              | LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ovl))
    {
      h->locked = 1;
      return 0; /* okay */
    }

  w32err = GetLastError ();
  if (w32err != ERROR_LOCK_VIOLATION)
    {
      my_error_2 (_("lock `%s' not made: %s\n"),
                  h->lockname, w32_strerror (w32err));
      return -1;
    }

  if (timeout)
    {
      /* Wait until lock has been released.  We use retry intervals of
         50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
      if (!wtime)
        wtime = 50;
      else if (wtime < 800)
        wtime *= 2;
      else if (wtime == 800)
        wtime = 2000;
      else if (wtime < 8000)
        wtime *= 2;

      if (timeout > 0)
        {
          if (wtime > timeout)
            wtime = timeout;
          timeout -= wtime;
        }

      if (wtime >= 800)
        my_info_1 (_("waiting for lock %s...\n"), h->lockname);

      Sleep (wtime);
      goto again;
    }

  return -1;
}
Exemple #4
0
/* Windows specific code of release_dotlock.  */
static int
dotlock_release_w32 (dotlock_t h)
{
  OVERLAPPED ovl;

  memset (&ovl, 0, sizeof ovl);
  if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
    {
      my_error_2 ("release_dotlock: error removing lockfile `%s': %s\n",
                  h->lockname, w32_strerror (-1));
      return -1;
    }

  return 0;
}
Exemple #5
0
/* Unix specific code of make_dotlock.  Returns 0 on success and -1 on
   error.  */
static int
dotlock_take_unix (dotlock_t h, long timeout)
{
  int wtime = 0;
  int sumtime = 0;
  int pid;
  int lastpid = -1;
  int ownerchanged;
  const char *maybe_dead="";
  int same_node;

 again:
  if (h->use_o_excl)
    {
      /* No hardlink support - use open(O_EXCL).  */
      int fd;

      do
        {
          jnlib_set_errno (0);
          fd = open (h->lockname, O_WRONLY|O_CREAT|O_EXCL,
                     S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
        }
      while (fd == -1 && errno == EINTR);

      if (fd == -1 && errno == EEXIST)
        ; /* Lock held by another process.  */
      else if (fd == -1)
        {
          my_error_2 ("lock not made: open(O_EXCL) of `%s' failed: %s\n",
                      h->lockname, strerror (errno));
          return -1;
        }
      else
        {
          char pidstr[16];

          snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid());
          if (write (fd, pidstr, 11 ) == 11
              && write (fd, h->tname + h->nodename_off,h->nodename_len)
              == h->nodename_len
              && write (fd, "\n", 1) == 1
              && !close (fd))
            {
              h->locked = 1;
              return 0;
            }
          /* Write error.  */
          my_error_2 ("lock not made: writing to `%s' failed: %s\n",
                      h->lockname, strerror (errno));
          close (fd);
          unlink (h->lockname);
          return -1;
        }
    }
  else /* Standard method:  Use hardlinks.  */
    {
      struct stat sb;

      link (h->tname, h->lockname);

      if (stat (h->tname, &sb))
        {
          my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
                      strerror (errno));
          /* In theory this might be a severe error: It is possible
             that link succeeded but stat failed due to changed
             permissions.  We can't do anything about it, though.  */
          return -1;
        }

      if (sb.st_nlink == 2)
        {
          h->locked = 1;
          return 0; /* Okay.  */
        }
    }

  /* Check for stale lock files.  */
  if ( (pid = read_lockfile (h, &same_node)) == -1 )
    {
      if ( errno != ENOENT )
        {
          my_info_0 ("cannot read lockfile\n");
          return -1;
        }
      my_info_0 ("lockfile disappeared\n");
      goto again;
    }
  else if ( pid == getpid() && same_node )
    {
      my_info_0 ("Oops: lock already held by us\n");
      h->locked = 1;
      return 0; /* okay */
    }
  else if ( same_node && kill (pid, 0) && errno == ESRCH )
    {
      /* Note: It is unlikley that we get a race here unless a pid is
         reused too fast or a new process with the same pid as the one
         of the stale file tries to lock right at the same time as we.  */
      my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
      unlink (h->lockname);
      goto again;
    }

  if (lastpid == -1)
    lastpid = pid;
  ownerchanged = (pid != lastpid);

  if (timeout)
    {
      struct timeval tv;

      /* Wait until lock has been released.  We use increasing retry
         intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s
         but reset it if the lock owner meanwhile changed.  */
      if (!wtime || ownerchanged)
        wtime = 50;
      else if (wtime < 800)
        wtime *= 2;
      else if (wtime == 800)
        wtime = 2000;
      else if (wtime < 8000)
        wtime *= 2;

      if (timeout > 0)
        {
          if (wtime > timeout)
            wtime = timeout;
          timeout -= wtime;
        }

      sumtime += wtime;
      if (sumtime >= 1500)
        {
          sumtime = 0;
          my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
                     pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
        }


      tv.tv_sec = wtime / 1000;
      tv.tv_usec = (wtime % 1000) * 1000;
      select (0, NULL, NULL, NULL, &tv);
      goto again;
    }

  jnlib_set_errno (EACCES);
  return -1;
}
Exemple #6
0
/* Locking core for Unix.  It used a temporary file and the link
   system call to make locking an atomic operation. */
static dotlock_t
dotlock_create_unix (dotlock_t h, const char *file_to_lock)
{
  int  fd = -1;
  char pidstr[16];
  const char *nodename;
  const char *dirpart;
  int dirpartlen;
  struct utsname utsbuf;
  size_t tnamelen;

  snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );

  /* Create a temporary file. */
  if ( uname ( &utsbuf ) )
    nodename = "unknown";
  else
    nodename = utsbuf.nodename;

  if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) )
    {
      dirpart = EXTSEP_S;
      dirpartlen = 1;
    }
  else
    {
      dirpartlen = dirpart - file_to_lock;
      dirpart = file_to_lock;
    }

  LOCK_all_lockfiles ();
  h->next = all_lockfiles;
  all_lockfiles = h;

  tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10 + 1;
  h->tname = jnlib_malloc (tnamelen + 1);
  if (!h->tname)
    {
      all_lockfiles = h->next;
      UNLOCK_all_lockfiles ();
      jnlib_free (h);
      return NULL;
    }
  h->nodename_len = strlen (nodename);

  snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
  h->nodename_off = strlen (h->tname);
  snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
           "%s.%d", nodename, (int)getpid ());

  do
    {
      jnlib_set_errno (0);
      fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
                 S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
    }
  while (fd == -1 && errno == EINTR);

  if ( fd == -1 )
    {
      all_lockfiles = h->next;
      UNLOCK_all_lockfiles ();
      my_error_2 (_("failed to create temporary file `%s': %s\n"),
                  h->tname, strerror(errno));
      jnlib_free (h->tname);
      jnlib_free (h);
      return NULL;
    }
  if ( write (fd, pidstr, 11 ) != 11 )
    goto write_failed;
  if ( write (fd, nodename, strlen (nodename) ) != strlen (nodename) )
    goto write_failed;
  if ( write (fd, "\n", 1 ) != 1 )
    goto write_failed;
  if ( close (fd) )
    goto write_failed;

  /* Check whether we support hard links.  */
  switch (use_hardlinks_p (h->tname))
    {
    case 0: /* Yes.  */
      break;
    case 1: /* No.  */
      unlink (h->tname);
      h->use_o_excl = 1;
      break;
    default:
      my_error_2 ("can't check whether hardlinks are supported for `%s': %s\n",
                  h->tname, strerror(errno));
      goto write_failed;
    }

  h->lockname = jnlib_malloc (strlen (file_to_lock) + 6 );
  if (!h->lockname)
    {
      all_lockfiles = h->next;
      UNLOCK_all_lockfiles ();
      unlink (h->tname);
      jnlib_free (h->tname);
      jnlib_free (h);
      return NULL;
    }
  strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
  UNLOCK_all_lockfiles ();
  if (h->use_o_excl)
    my_debug_1 ("locking for `%s' done via O_EXCL\n", h->lockname);

  return h;

 write_failed:
  all_lockfiles = h->next;
  UNLOCK_all_lockfiles ();
  my_error_2 (_("error writing to `%s': %s\n"), h->tname, strerror (errno));
  close (fd);
  unlink (h->tname);
  jnlib_free (h->tname);
  jnlib_free (h);
  return NULL;
}
Exemple #7
0
static int
read_lockfile (dotlock_t h, int *same_node )
{
  char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
                                   names are usually shorter. */
  int fd;
  int pid = -1;
  char *buffer, *p;
  size_t expected_len;
  int res, nread;

  *same_node = 0;
  expected_len = 10 + 1 + h->nodename_len + 1;
  if ( expected_len >= sizeof buffer_space)
    {
      buffer = jnlib_malloc (expected_len);
      if (!buffer)
        return -1;
    }
  else
    buffer = buffer_space;

  if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
    {
      int e = errno;
      my_info_2 ("error opening lockfile `%s': %s\n",
                 h->lockname, strerror(errno) );
      if (buffer != buffer_space)
        jnlib_free (buffer);
      jnlib_set_errno (e); /* Need to return ERRNO here. */
      return -1;
    }

  p = buffer;
  nread = 0;
  do
    {
      res = read (fd, p, expected_len - nread);
      if (res == -1 && errno == EINTR)
        continue;
      if (res < 0)
        {
          my_info_1 ("error reading lockfile `%s'\n", h->lockname );
          close (fd);
          if (buffer != buffer_space)
            jnlib_free (buffer);
          jnlib_set_errno (0); /* Do not return an inappropriate ERRNO. */
          return -1;
        }
      p += res;
      nread += res;
    }
  while (res && nread != expected_len);
  close(fd);

  if (nread < 11)
    {
      my_info_1 ("invalid size of lockfile `%s'\n", h->lockname);
      if (buffer != buffer_space)
        jnlib_free (buffer);
      jnlib_set_errno (0); /* Better don't return an inappropriate ERRNO. */
      return -1;
    }

  if (buffer[10] != '\n'
      || (buffer[10] = 0, pid = atoi (buffer)) == -1
      || !pid )
    {
      my_error_2 ("invalid pid %d in lockfile `%s'\n", pid, h->lockname);
      if (buffer != buffer_space)
        jnlib_free (buffer);
      jnlib_set_errno (0);
      return -1;
    }

  if (nread == expected_len
      && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
      && buffer[11+h->nodename_len] == '\n')
    *same_node = 1;

  if (buffer != buffer_space)
    jnlib_free (buffer);
  return pid;
}
Exemple #8
0
static duk_ret_t test_error_va_return(duk_context *ctx, void *udata) {
	(void) udata;
	duk_set_top(ctx, 0);

	return my_error_2(ctx, DUK_ERR_RANGE_ERROR, "my error %d %d %s", 123, 234, "foobar");
}