Exemple #1
0
char *
xgetcwd ()
{
#if HAVE_GETCWD_NULL
  char *cwd = getcwd (NULL, 0);
  if (! cwd && errno == ENOMEM)
    xalloc_die ();
  return cwd;
#else

  /* The initial buffer size for the working directory.  A power of 2
     detects arithmetic overflow earlier, but is not required.  */
# ifndef INITIAL_BUFFER_SIZE
#  define INITIAL_BUFFER_SIZE 128
# endif

  size_t buf_size = INITIAL_BUFFER_SIZE;

  while (1)
    {
      char *buf = xmalloc (buf_size);
      char *cwd = getcwd (buf, buf_size);
      int saved_errno;
      if (cwd)
	return cwd;
      saved_errno = errno;
      free (buf);
      if (saved_errno != ERANGE)
	return NULL;
      buf_size *= 2;
      if (buf_size == 0)
	xalloc_die ();
    }
#endif
}
Exemple #2
0
static char *
savedirstream (DIR *dirp)
{
  char *name_space;
  size_t allocated = NAME_SIZE_DEFAULT;
  size_t used = 0;
  int save_errno;

  if (dirp == NULL)
    return NULL;

  name_space = xmalloc (allocated);

  for (;;)
    {
      struct dirent const *dp;
      char const *entry;

      errno = 0;
      dp = readdir (dirp);
      if (! dp)
	break;

      /* Skip "", ".", and "..".  "" is returned by at least one buggy
         implementation: Solaris 2.4 readdir on NFS file systems.  */
      entry = dp->d_name;
      if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
	{
	  size_t entry_size = _D_EXACT_NAMLEN (dp) + 1;
	  if (used + entry_size < used)
	    xalloc_die ();
	  if (allocated <= used + entry_size)
	    {
	      do
		{
		  if (2 * allocated < allocated)
		    xalloc_die ();
		  allocated *= 2;
		}
	      while (allocated <= used + entry_size);

	      name_space = xrealloc (name_space, allocated);
	    }
	  memcpy (name_space + used, entry, entry_size);
	  used += entry_size;
	}
    }
  name_space[used] = '\0';
  save_errno = errno;
  if (closedir (dirp) != 0)
    save_errno = errno;
  if (save_errno != 0)
    {
      free (name_space);
      errno = save_errno;
      return NULL;
    }
  return name_space;
}
Exemple #3
0
char *
savedir (const char *dir)
{
  DIR *dirp;
  struct dirent *dp;
  char *name_space;
  size_t allocated = NAME_SIZE_DEFAULT;
  size_t used = 0;
  int save_errno;

  dirp = opendir (dir);
  if (dirp == NULL)
    return NULL;

  name_space = xmalloc (allocated);

  errno = 0;
  while ((dp = readdir (dirp)) != NULL)
    {
      /* Skip "", ".", and "..".  "" is returned by at least one buggy
         implementation: Solaris 2.4 readdir on NFS filesystems.  */
      char const *entry = dp->d_name;
      if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
	{
	  size_t entry_size = strlen (entry) + 1;
	  if (used + entry_size < used)
	    xalloc_die ();
	  if (allocated <= used + entry_size)
	    {
	      do
		{
		  if (2 * allocated < allocated)
		    xalloc_die ();
		  allocated *= 2;
		}
	      while (allocated <= used + entry_size);

	      name_space = xrealloc (name_space, allocated);
	    }
	  memcpy (name_space + used, entry, entry_size);
	  used += entry_size;
	}
    }
  name_space[used] = '\0';
  save_errno = errno;
  if (CLOSEDIR (dirp) != 0)
    save_errno = errno;
  if (save_errno != 0)
    {
      free (name_space);
      errno = save_errno;
      return NULL;
    }
  return name_space;
}
Exemple #4
0
bool
read_files (struct file_data filevec[], bool pretend_binary)
{
  int i;
  bool skip_test = text | pretend_binary;
  bool appears_binary = pretend_binary | sip (&filevec[0], skip_test);

  if (filevec[0].desc != filevec[1].desc)
    appears_binary |= sip (&filevec[1], skip_test | appears_binary);
  else
    {
      filevec[1].buffer = filevec[0].buffer;
      filevec[1].bufsize = filevec[0].bufsize;
      filevec[1].buffered = filevec[0].buffered;
    }
  if (appears_binary)
    {
      set_binary_mode (filevec[0].desc, true);
      set_binary_mode (filevec[1].desc, true);
      return true;
    }

  find_identical_ends (filevec);

  equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1;
  if (PTRDIFF_MAX / sizeof *equivs <= equivs_alloc)
    xalloc_die ();
  equivs = xmalloc (equivs_alloc * sizeof *equivs);
  /* Equivalence class 0 is permanently safe for lines that were not
     hashed.  Real equivalence classes start at 1.  */
  equivs_index = 1;

  /* Allocate (one plus) a prime number of hash buckets.  Use a prime
     number between 1/3 and 2/3 of the value of equiv_allocs,
     approximately.  */
  for (i = 9; (size_t) 1 << i < equivs_alloc / 3; i++)
    continue;
  nbuckets = ((size_t) 1 << i) - prime_offset[i];
  if (PTRDIFF_MAX / sizeof *buckets <= nbuckets)
    xalloc_die ();
  buckets = zalloc ((nbuckets + 1) * sizeof *buckets);
  buckets++;

  for (i = 0; i < 2; i++)
    find_and_hash_each_line (&filevec[i]);

  filevec[0].equiv_max = filevec[1].equiv_max = equivs_index;

  free (equivs);
  free (buckets - 1);

  return false;
}
Exemple #5
0
static void
time_to_env (char *envar, struct timespec t)
{
  char buf[TIMESPEC_STRSIZE_BOUND];
  if (setenv (envar, code_timespec (t, buf), 1) != 0)
    xalloc_die ();
}
int
main (int argc _GL_UNUSED, char **argv)
{
  set_program_name (argv[0]);
  xalloc_die ();
  return 0;
}
Exemple #7
0
static inline void *
xnrealloc_inline (void *p, size_t n, size_t s)
{
    if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
        xalloc_die ();
    return p;
}
Exemple #8
0
static inline void *
x2nrealloc_inline (void *p, size_t *pn, size_t s)
{
    size_t n = *pn;

    if (! p)
    {
        if (! n)
        {
            /* The approximate size to use for initial small allocation
               requests, when the invoking code specifies an old size of
               zero.  64 bytes is the largest "small" request for the
               GNU C library malloc.  */
            enum { DEFAULT_MXFAST = 64 };

            n = DEFAULT_MXFAST / s;
            n += !n;
        }
    }
    else
    {
        if (SIZE_MAX / 2 / s < n)
            xalloc_die ();
        n *= 2;
    }

    *pn = n;
    return xrealloc (p, n * s);
}
Exemple #9
0
char *xstrdup(const char *s1)
{
	char *s = strdup(s1);
	if (s1 && !s)
		xalloc_die();
	return s;
}
Exemple #10
0
void *xmalloc(size_t size)
{
	void *ptr = malloc(size);
	if (size && !ptr)
		xalloc_die();
	return ptr;
}
Exemple #11
0
/* Create a vector of N_VECS bitsets, each of N_BITS, and of
   type TYPE.  */
bitset *
bitsetv_alloc (bitset_bindex n_vecs, bitset_bindex n_bits,
	       enum bitset_type type)
{
  size_t vector_bytes;
  size_t bytes;
  bitset *bsetv;
  bitset_bindex i;

  /* Determine number of bytes for each set.  */
  bytes = bitset_bytes (type, n_bits);

  /* If size calculation overflows, memory is exhausted.  */
  if (BITSET_SIZE_MAX / (sizeof (bitset) + bytes) <= n_vecs)
    xalloc_die ();

  /* Allocate vector table at head of bitset array.  */
  vector_bytes = (n_vecs + 1) * sizeof (bitset) + bytes - 1;
  vector_bytes -= vector_bytes % bytes;
  bsetv = xcalloc (1, vector_bytes + bytes * n_vecs);

  for (i = 0; i < n_vecs; i++)
    {
      bsetv[i] = (bitset) (void *) ((char *) bsetv + vector_bytes + i * bytes);

      bitset_init (bsetv[i], n_bits, type);
    }

  /* Null terminate table.  */
  bsetv[i] = 0;
  return bsetv;
}
Exemple #12
0
FTS *
xfts_open (char * const *argv, int options,
	   int (*compar) (const FTSENT **, const FTSENT **))
{
  FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);
  if (fts == NULL)
    {
      /* This can fail in three ways: out of memory, invalid bit_flags,
	 and one or more of the FILES is an empty string.  We could try
	 to decipher that errno==EINVAL means invalid bit_flags and
	 errno==ENOENT means there's an empty string, but that seems wrong.
	 Ideally, fts_open would return a proper error indicator.  For now,
	 we'll presume that the bit_flags are valid and just check for
	 empty strings.  */
      bool invalid_arg = false;
      for (; *argv; ++argv)
	{
	  if (**argv == '\0')
	    invalid_arg = true;
	}
      if (invalid_arg)
	error (EXIT_FAILURE, 0, _("invalid argument: %s"), quote (""));
      else
	xalloc_die ();
    }

  return fts;
}
Exemple #13
0
/* Record file, FILE, and dev/ino from *STATS, in the hash table, HT.
   If HT is NULL, return immediately.
   If memory allocation fails, exit immediately.  */
void
record_file (Hash_table *ht, char const *file, struct stat const *stats)
{
  struct F_triple *ent;

  if (ht == NULL)
    return;

  ent = xmalloc (sizeof *ent);
  ent->name = xstrdup (file);
  ent->st_ino = stats->st_ino;
  ent->st_dev = stats->st_dev;

  {
    struct F_triple *ent_from_table = hash_insert (ht, ent);
    if (ent_from_table == NULL)
      {
        /* Insertion failed due to lack of memory.  */
        xalloc_die ();
      }

    if (ent_from_table != ent)
      {
        /* There was alread a matching entry in the table, so ENT was
           not inserted.  Free it.  */
        triple_free (ent);
      }
  }
}
Exemple #14
0
/* Return zero if TABLE contains a LEN-character long prefix of STRING,
   otherwise, insert a newly allocated copy of this prefix to TABLE and
   return 1.  If RETURN_PREFIX is not NULL, point it to the allocated
   copy. */
static bool
hash_string_insert_prefix (Hash_table **table, char const *string, size_t len,
			   const char **return_prefix)
{
  Hash_table *t = *table;
  char *s;
  char *e;

  if (len)
    {
      s = xmalloc (len + 1);
      memcpy (s, string, len);
      s[len] = 0;
    }
  else
    s = xstrdup (string);
  
  if (! ((t
	  || (*table = t = hash_initialize (0, 0, hash_string_hasher,
					    hash_string_compare, 0)))
	 && (e = hash_insert (t, s))))
    xalloc_die ();

  if (e == s)
    {
      if (return_prefix)
	*return_prefix = s;
      return 1;
    }
  else
    {
      free (s);
      return 0;
    }
}
Exemple #15
0
dico_stream_t
xdico_transcript_stream_create(dico_stream_t transport, dico_stream_t logstr,
			       const char *prefix[])
{
    struct transcript_stream *p = xmalloc(sizeof(*p));
    dico_stream_t stream;
    int rc = dico_stream_create(&stream, DICO_STREAM_READ|DICO_STREAM_WRITE,
				p);
    if (rc)
	xalloc_die();
    p->flags = TRANS_READ | TRANS_WRITE;
    if (prefix) {
	p->prefix[0] = xstrdup(prefix[0] ? prefix[0] : default_prefix[0]);
	p->prefix[1] = xstrdup(prefix[1] ? prefix[1] : default_prefix[1]);
    } else {
	p->prefix[0] = xstrdup(default_prefix[0]);
	p->prefix[1] = xstrdup(default_prefix[1]);
    }
    p->transport = transport;
    p->logstr = logstr;
    
    dico_stream_set_read(stream, transcript_read);
    dico_stream_set_write(stream, transcript_write);
    dico_stream_set_flush(stream, transcript_flush);
    dico_stream_set_close(stream, transcript_close);
    dico_stream_set_destroy(stream, transcript_destroy);
    dico_stream_set_ioctl(stream, transcript_ioctl);
    dico_stream_set_error_string(stream, transcript_strerror);
    dico_stream_set_buffer(stream, dico_buffer_line, 1024);

    return stream;
}
Exemple #16
0
void *xmalloc (size_t size)
{
    void *mem = malloc(size);
    if (mem == NULL)
        xalloc_die();
    return mem;
}
Exemple #17
0
void *xrealloc (void *ptr, size_t size)
{
    void *mem = realloc(ptr, size);
    if (mem == NULL)
        xalloc_die();
    return mem;
}
Exemple #18
0
void *xnrealloc( void *p, size_t n, size_t s )
{
  int edx;
  if ( (long long)0xffffffff / s < n )
    xalloc_die( );
  return xrealloc( p, s * n );
}
Exemple #19
0
extern char *
remember_copied (const char *name, ino_t ino, dev_t dev)
{
  struct Src_to_dest *ent;
  struct Src_to_dest *ent_from_table;

  ent = xmalloc (sizeof *ent);
  ent->name = xstrdup (name);
  ent->st_ino = ino;
  ent->st_dev = dev;

  ent_from_table = hash_insert (src_to_dest, ent);
  if (ent_from_table == NULL)
    {
      /* Insertion failed due to lack of memory.  */
      xalloc_die ();
    }

  /* Determine whether there was already an entry in the table
     with a matching key.  If so, free ENT (it wasn't inserted) and
     return the `name' from the table entry.  */
  if (ent_from_table != ent)
    {
      src_to_dest_free (ent);
      return (char *) ent_from_table->name;
    }

  /* New key;  insertion succeeded.  */
  return NULL;
}
Exemple #20
0
int
alias_install(const char *kw, int argc, char **argv, grecs_locus_t *ploc)
{
    struct alias *sample = xmalloc(sizeof(*sample)),
                  *ap;

    sample->kw = xstrdup(kw);
    sample->argc = argc;
    sample->argv = argv;
    sample->locus = *ploc;

    if (! ((alias_table
            || (alias_table = hash_initialize(0, 0,
                              alias_hasher,
                              alias_compare,
                              NULL)))
            && (ap = hash_insert(alias_table, sample))))
        xalloc_die();

    if (ap != sample) {
        free(sample->kw);
        free(sample);
        grecs_error(ploc, 0, _("alias `%s' already defined"), kw);
        grecs_error(&ap->locus, 0,
                    _("this is the location of the previous definition"));
        return 1; /* Found */
    }
    return 0;
}
Exemple #21
0
void *xnmalloc( size_t n, size_t s )
{
  int edx;
  if ( (long long)0xffffffff / s < n )
    xalloc_die( );
  return xmalloc( s * n );
}
Exemple #22
0
/* Allocates and returns N * M bytes of memory. */
static void *
xnmalloc (size_t n, size_t m)
{
  if ((size_t) -1 / m <= n)
    xalloc_die ();
  return xmalloc (n * m);
}
static bool
get_group_info (struct group_info *gi)
{
  int n_groups;
  int n_group_slots = getgroups (0, NULL);
  GETGROUPS_T *group;

  if (n_group_slots < 0)
    return false;

  /* Avoid xnmalloc, as it goes awry when SIZE_MAX < n_group_slots.  */
  if (xalloc_oversized (n_group_slots, sizeof *group))
    xalloc_die ();
  group = xmalloc (n_group_slots * sizeof *group);
  n_groups = getgroups (n_group_slots, group);

  /* In case of error, the user loses. */
  if (n_groups < 0)
    {
      free (group);
      return false;
    }

  gi->n_groups = n_groups;
  gi->group = group;

  return true;
}
Exemple #24
0
/* Check if FILE_NAME already exists and make a backup of it right now.
   Return success (nonzero) only if the backup is either unneeded, or
   successful.  For now, directories are considered to never need
   backup.  If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and
   so, we do not have to backup block or character devices, nor remote
   entities.  */
bool
maybe_backup_file (const char *file_name, bool this_is_the_archive)
{
  struct stat file_stat;

  assign_string (&before_backup_name, file_name);

  /* A run situation may exist between Emacs or other GNU programs trying to
     make a backup for the same file simultaneously.  If theoretically
     possible, real problems are unlikely.  Doing any better would require a
     convention, GNU-wide, for all programs doing backups.  */

  assign_string (&after_backup_name, 0);

  /* Check if we really need to backup the file.  */

  if (this_is_the_archive && _remdev (file_name))
    return true;

  if (deref_stat (file_name, &file_stat) != 0)
    {
      if (errno == ENOENT)
	return true;

      stat_error (file_name);
      return false;
    }

  if (S_ISDIR (file_stat.st_mode))
    return true;

  if (this_is_the_archive
      && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
    return true;

  after_backup_name = find_backup_file_name (file_name, backup_type);
  if (! after_backup_name)
    xalloc_die ();

  if (renameat (chdir_fd, before_backup_name, chdir_fd, after_backup_name)
      == 0)
    {
      if (verbose_option)
	fprintf (stdlis, _("Renaming %s to %s\n"),
		 quote_n (0, before_backup_name),
		 quote_n (1, after_backup_name));
      return true;
    }
  else
    {
      /* The backup operation failed.  */
      int e = errno;
      ERROR ((0, e, _("%s: Cannot rename to %s"),
	      quotearg_colon (before_backup_name),
	      quote_n (1, after_backup_name)));
      assign_string (&after_backup_name, 0);
      return false;
    }
}
Exemple #25
0
char *
xgetcwd (void)
{
  char *cwd = getcwd (NULL, 0);
  if (! cwd && errno == ENOMEM)
    xalloc_die ();
  return cwd;
}
Exemple #26
0
void
init_backup_hash_table (void)
{
  file_id_table = hash_initialize (0, NULL, file_id_hasher,
				   file_id_comparator, free);
  if (!file_id_table)
    xalloc_die ();
}
Exemple #27
0
int
xgetgroups (char const *username, gid_t gid, gid_t **groups)
{
  int result = mgetgroups (username, gid, groups);
  if (result == -1 && errno == ENOMEM)
    xalloc_die ();
  return result;
}
char *
xpath_concat (const char *dir, const char *base, char **base_in_result)
{
  char *res = path_concat (dir, base, base_in_result);
  if (! res)
    xalloc_die ();
  return res;
}
Exemple #29
0
char *
xreadlink (char const *filename)
{
  char *result = areadlink (filename);
  if (result == NULL && errno == ENOMEM)
    xalloc_die ();
  return result;
}
Exemple #30
0
void *
xmalloc (size_t n)
{
  void *p = malloc (n);
  if (!p && n != 0)
    xalloc_die ();
  return p;
}