Esempio n. 1
0
static char *
getttyname (int fd, dev_t mydev, ino_t myino, int save, int *dostat)
{
  static const char dev[] = "/dev";
  static size_t namelen;
  struct stat st;
  DIR *dirstream;
  struct dirent *d;

  dirstream = __opendir (dev);
  if (dirstream == NULL)
    {
      *dostat = -1;
      return NULL;
    }

  while ((d = __readdir (dirstream)) != NULL)
    if (((ino_t) d->d_fileno == myino || *dostat)
	&& strcmp (d->d_name, "stdin")
	&& strcmp (d->d_name, "stdout")
	&& strcmp (d->d_name, "stderr"))
      {
	size_t dlen = _D_ALLOC_NAMLEN (d);
	if (sizeof (dev) + dlen > namelen)
	  {
	    free (getttyname_name);
	    namelen = 2 * (sizeof (dev) + dlen); /* Big enough.  */
	    getttyname_name = malloc (namelen);
	    if (! getttyname_name)
	      {
		*dostat = -1;
		/* Perhaps it helps to free the directory stream buffer.  */
		(void) __closedir (dirstream);
		return NULL;
	      }
	    *((char *) __mempcpy (getttyname_name, dev, sizeof (dev) - 1))
	      = '/';
	  }
	(void) __mempcpy (&getttyname_name[sizeof (dev)], d->d_name, dlen);
	if (stat (getttyname_name, &st) == 0
#ifdef _STATBUF_ST_RDEV
	    && S_ISCHR (st.st_mode) && st.st_rdev == mydev
#else
	    && (ino_t) d->d_fileno == myino && st.st_dev == mydev
#endif
	   )
	  {
	    (void) __closedir (dirstream);
	    __ttyname = getttyname_name;
	    __set_errno (save);
	    return getttyname_name;
	  }
      }

  (void) __closedir (dirstream);
  __set_errno (save);
  return NULL;
}
Esempio n. 2
0
static void
msort_with_tmp (void *b, size_t n, size_t s, __compar_fn_t cmp,
		char *t)
{
  char *tmp;
  char *b1, *b2;
  size_t n1, n2;

  if (n <= 1)
    return;

  n1 = n / 2;
  n2 = n - n1;
  b1 = b;
  b2 = (char *) b + (n1 * s);

  msort_with_tmp (b1, n1, s, cmp, t);
  msort_with_tmp (b2, n2, s, cmp, t);

  tmp = t;

  if (s == OPSIZ && (b1 - (char *) 0) % OPSIZ == 0)
    /* We are operating on aligned words.  Use direct word stores.  */
    while (n1 > 0 && n2 > 0)
      {
	if ((*cmp) (b1, b2) <= 0)
	  {
	    --n1;
	    *((op_t *) tmp)++ = *((op_t *) b1)++;
	  }
	else
	  {
	    --n2;
	    *((op_t *) tmp)++ = *((op_t *) b2)++;
	  }
      }
  else
    while (n1 > 0 && n2 > 0)
      {
	if ((*cmp) (b1, b2) <= 0)
	  {
	    tmp = (char *) __mempcpy (tmp, b1, s);
	    b1 += s;
	    --n1;
	  }
	else
	  {
	    tmp = (char *) __mempcpy (tmp, b2, s);
	    b2 += s;
	    --n2;
	  }
      }
  if (n1 > 0)
    memcpy (tmp, b1, n1 * s);
  memcpy (b, t, (n - n2) * s);
}
Esempio n. 3
0
static _IO_size_t
_IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
{
  _IO_size_t have;
  char *read_ptr = fp->_IO_read_ptr;
  char *s = (char *) data;

  have = fp->_IO_read_end - fp->_IO_read_ptr;

  if (have < n)
    {
      if (__glibc_unlikely (_IO_in_backup (fp)))
	{
#ifdef _LIBC
	  s = __mempcpy (s, read_ptr, have);
#else
	  memcpy (s, read_ptr, have);
	  s += have;
#endif
	  n -= have;
	  _IO_switch_to_main_get_area (fp);
	  read_ptr = fp->_IO_read_ptr;
	  have = fp->_IO_read_end - fp->_IO_read_ptr;
	}

      if (have < n)
	{
	  /* Check that we are mapping all of the file, in case it grew.  */
	  if (__glibc_unlikely (mmap_remap_check (fp)))
	    /* We punted mmap, so complete with the vanilla code.  */
	    return s - (char *) data + _IO_XSGETN (fp, data, n);

	  read_ptr = fp->_IO_read_ptr;
	  have = fp->_IO_read_end - read_ptr;
	}
    }

  if (have < n)
    fp->_flags |= _IO_EOF_SEEN;

  if (have != 0)
    {
      have = MIN (have, n);
#ifdef _LIBC
      s = __mempcpy (s, read_ptr, have);
#else
      memcpy (s, read_ptr, have);
      s += have;
#endif
      fp->_IO_read_ptr = read_ptr + have;
    }

  return s - (char *) data;
}
Esempio n. 4
0
/* 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);

  /* 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_CLOEXEC | O_NOFOLLOW, mode);
  if (fd == -1 && __glibc_unlikely (errno == EISDIR))
    /* 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;
}
Esempio n. 5
0
nis_name
nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen)
{
  size_t i = 0;

  buffer[0] = '\0';

  while (name[i] != '.' && name[i] != '\0')
    i++;

  if (i > buflen - 1)
    {
      __set_errno (ERANGE);
      return NULL;
    }

  if (i > 0)
    {
      if ((size_t)i >= buflen)
	{
	  __set_errno (ERANGE);
	  return NULL;
	}

      *((char *) __mempcpy (buffer, name, i)) = '\0';
    }

  return buffer;
}
Esempio n. 6
0
nis_name
nis_name_of_r (const_nis_name name, char *buffer, size_t buflen)
{
  char *local_domain;
  int diff;

  local_domain = nis_local_directory ();

  diff = strlen (name) - strlen (local_domain);
  if (diff <= 0)
    return NULL;

  if (strcmp (&name[diff], local_domain) != 0)
    return NULL;

  if ((size_t) diff >= buflen)
    {
      __set_errno (ERANGE);
      return NULL;
    }

  *((char *) __mempcpy (buffer, name, diff - 1)) = '\0';

  if (diff - 1 == 0)
    return NULL;

  return buffer;
}
Esempio n. 7
0
static _IO_size_t
_IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
{
  struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack;

  if (fp->_IO_write_ptr + n > fp->_IO_write_end)
    {
      int size;

      /* We need some more memory.  First shrink the buffer to the
	 space we really currently need.  */
      obstack_blank_fast (obstack, fp->_IO_write_ptr - fp->_IO_write_end);

      /* Now grow for N bytes, and put the data there.  */
      obstack_grow (obstack, data, n);

      /* Setup the buffer pointers again.  */
      fp->_IO_write_base = obstack_base (obstack);
      fp->_IO_write_ptr = obstack_next_free (obstack);
      size = obstack_room (obstack);
      fp->_IO_write_end = fp->_IO_write_ptr + size;
      /* Now allocate the rest of the current chunk.  */
      obstack_blank_fast (obstack, size);
    }
  else
    fp->_IO_write_ptr = __mempcpy (fp->_IO_write_ptr, data, n);

  return n;
}
Esempio n. 8
0
static int
internal_function
find_module (const char *directory, const char *filename,
	     struct __gconv_step *result)
{
  size_t dirlen = strlen (directory);
  size_t fnamelen = strlen (filename) + 1;
  char fullname[dirlen + fnamelen];
  int status = __GCONV_NOCONV;

  memcpy (__mempcpy (fullname, directory, dirlen), filename, fnamelen);

  result->__shlib_handle = __gconv_find_shlib (fullname);
  if (result->__shlib_handle != NULL)
    {
      status = __GCONV_OK;

      result->__modname = NULL;
      result->__fct = result->__shlib_handle->fct;
      result->__init_fct = result->__shlib_handle->init_fct;
      result->__end_fct = result->__shlib_handle->end_fct;

      /* These settings can be overridden by the init function.  */
      result->__btowc_fct = NULL;
      result->__data = NULL;

      /* Call the init function.  */
      if (result->__init_fct != NULL)
	status = DL_CALL_FCT (result->__init_fct, (result));
    }

  return status;
}
Esempio n. 9
0
/* Open a master pseudo terminal and return its file descriptor.  */
int
__getpt (void)
{
  char buf[sizeof (_PATH_PTY) + 2];
  const char *p, *q;
  char *s;

  s = __mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1);
  /* s[0] and s[1] will be filled in the loop.  */
  s[2] = '\0';

  for (p = __libc_ptyname1; *p != '\0'; ++p)
    {
      s[0] = *p;

      for (q = __libc_ptyname2; *q != '\0'; ++q)
	{
	  int fd;

	  s[1] = *q;

	  fd = __open (buf, O_RDWR);
	  if (fd != -1)
	    return fd;

	  if (errno == ENOENT)
	    return -1;
	}
    }

  __set_errno (ENOENT);
  return -1;
}
Esempio n. 10
0
const char *
_dl_get_origin (void)
{
  char linkval[PATH_MAX];
  char *result;
  int len;
  INTERNAL_SYSCALL_DECL (err);

  len = INTERNAL_SYSCALL (readlinkat, err, 4, AT_FDCWD, "/proc/self/exe",
                          linkval, sizeof (linkval));
  if (! INTERNAL_SYSCALL_ERROR_P (len, err) && len > 0 && linkval[0] != '[')
    {
      /* We can use this value.  */
      assert (linkval[0] == '/');
      while (len > 1 && linkval[len - 1] != '/')
	--len;
      result = (char *) malloc (len + 1);
      if (result == NULL)
	result = (char *) -1;
      else if (len == 1)
	memcpy (result, "/", 2);
      else
	*((char *) __mempcpy (result, linkval, len - 1)) = '\0';
    }
  else
    {
      result = (char *) -1;
      /* We use the environment variable LD_ORIGIN_PATH.  If it is set make
	 a copy and strip out trailing slashes.  */
      if (GLRO(dl_origin_path) != NULL)
	{
	  size_t len = strlen (GLRO(dl_origin_path));
	  result = (char *) malloc (len + 1);
	  if (result == NULL)
	    result = (char *) -1;
	  else
	    {
	      char *cp = __mempcpy (result, GLRO(dl_origin_path), len);
	      while (cp > result + 1 && cp[-1] == '/')
		--cp;
	      *cp = '\0';
	    }
	}
    }

  return result;
}
Esempio n. 11
0
internal_function attribute_compat_text_section
getttyname (const char *dev, dev_t mydev, ino64_t myino, int save, int *dostat)
{
  static size_t namelen;
  struct stat64 st;
  DIR *dirstream;
  struct dirent64 *d;
  size_t devlen = strlen (dev) + 1;

  dirstream = __opendir (dev);
  if (dirstream == NULL)
    {
      *dostat = -1;
      return NULL;
    }

  while ((d = __readdir64 (dirstream)) != NULL)
    if ((d->d_fileno == myino || *dostat)
	&& strcmp (d->d_name, "stdin")
	&& strcmp (d->d_name, "stdout")
	&& strcmp (d->d_name, "stderr"))
      {
	size_t dlen = _D_ALLOC_NAMLEN (d);
	if (devlen + dlen > namelen)
	  {
	    free (getttyname_name);
	    namelen = 2 * (devlen + dlen); /* Big enough.  */
	    getttyname_name = malloc (namelen);
	    if (! getttyname_name)
	      {
		*dostat = -1;
		/* Perhaps it helps to free the directory stream buffer.  */
		(void) __closedir (dirstream);
		return NULL;
	      }
	    *((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/';
	  }
	memcpy (&getttyname_name[devlen], d->d_name, dlen);
	if (__xstat64 (_STAT_VER, getttyname_name, &st) == 0
#ifdef _STATBUF_ST_RDEV
	    && S_ISCHR (st.st_mode) && st.st_rdev == mydev
#else
	    && d->d_fileno == myino && st.st_dev == mydev
#endif
	   )
	  {
	    (void) __closedir (dirstream);
#if 0
	    __ttyname = getttyname_name;
#endif
	    __set_errno (save);
	    return getttyname_name;
	  }
      }

  (void) __closedir (dirstream);
  __set_errno (save);
  return NULL;
}
Esempio n. 12
0
void *
__mempcpy_chk (void *dstpp, const void *srcpp, size_t len, size_t dstlen)
{
  if (__glibc_unlikely (dstlen < len))
    __chk_fail ();

  return __mempcpy (dstpp, srcpp, len);
}
Esempio n. 13
0
wchar_t *
__wmempcpy_chk (wchar_t *s1, const wchar_t *s2, size_t n, size_t ns1)
{
  if (__glibc_unlikely (ns1 < n))
    __chk_fail ();
  return (wchar_t *) __mempcpy ((char *) s1, (char *) s2,
				n * sizeof (wchar_t));
}
Esempio n. 14
0
internal_function
getttyname (const char *dev, dev_t mydev, ino64_t myino, int save)
{
  static size_t namelen;
  struct stat64 st;
  DIR *dirstream;
  struct dirent *d;
  size_t devlen = strlen (dev) + 1;

  dirstream = __opendir (dev);
  if (dirstream == NULL)
    {
      return NULL;
    }

  while ((d = __readdir (dirstream)) != NULL)
    if (d->d_fileno == myino)
      {
	size_t dlen = _D_ALLOC_NAMLEN (d);
	if (devlen + dlen > namelen)
	  {
	    free (getttyname_name);
	    namelen = 2 * (devlen + dlen); /* Big enough.  */
	    getttyname_name = malloc (namelen);
	    if (! getttyname_name)
	      {
		/* Perhaps it helps to free the directory stream buffer.  */
		(void) __closedir (dirstream);
		return NULL;
	      }
	  }
	/* Always recopy dev since it may be master or slave.  */
	*((char *) __mempcpy (getttyname_name, dev, devlen - 1)) = '/';

	memcpy (&getttyname_name[devlen], d->d_name, dlen);
	if (__xstat64 (_STAT_VER, getttyname_name, &st) == 0
#ifdef _STATBUF_ST_RDEV
	    && S_ISCHR (st.st_mode) && st.st_rdev == mydev
#else
	    && d->d_fileno == myino && st.st_dev == mydev
#endif
	   )
	  {
	    (void) __closedir (dirstream);
#if 0
	    __ttyname = getttyname_name;
#endif
	    __set_errno (save);
	    return getttyname_name;
	  }
      }

  (void) __closedir (dirstream);
  __set_errno (save);
  return NULL;
}
Esempio n. 15
0
error_t
_hurd_xattr_list (io_t port, void *buffer, size_t *size)
{
  size_t total = 0;
  char *bufp = buffer;
  inline void add (const char *name, size_t len)
    {
      total += len;
      if (bufp != NULL && total <= *size)
	bufp = __mempcpy (bufp, name, len);
    }
Esempio n. 16
0
/* 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;
}
Esempio n. 17
0
/* Write data pointed by the buffers described by VECTOR, which
   is a vector of COUNT 'struct iovec's, to file descriptor FD.
   The data is written in the order specified.
   Operates just like 'write' (see <unistd.h>) except that the data
   are taken from VECTOR instead of a contiguous buffer.  */
ssize_t
__libc_writev (int fd, const struct iovec *vector, int count)
{
  /* Find the total number of bytes to be written.  */
  size_t bytes = 0;
  for (int i = 0; i < count; ++i)
    {
      /* Check for ssize_t overflow.  */
      if (SSIZE_MAX - bytes < vector[i].iov_len)
	{
	  __set_errno (EINVAL);
	  return -1;
	}
      bytes += vector[i].iov_len;
    }

  /* Allocate a temporary buffer to hold the data.  We should normally
     use alloca since it's faster and does not require synchronization
     with other threads.  But we cannot if the amount of memory
     required is too large.  */
  char *buffer;
  char *malloced_buffer = NULL;
  if (__libc_use_alloca (bytes))
    buffer = (char *) __alloca (bytes);
  else
    {
      malloced_buffer = buffer = (char *) malloc (bytes);
      if (buffer == NULL)
	/* XXX I don't know whether it is acceptable to try writing
	   the data in chunks.  Probably not so we just fail here.  */
	return -1;
    }

  /* Copy the data into BUFFER.  */
  size_t to_copy = bytes;
  char *bp = buffer;
  for (int i = 0; i < count; ++i)
    {
      size_t copy = MIN (vector[i].iov_len, to_copy);

      bp = __mempcpy ((void *) bp, (void *) vector[i].iov_base, copy);

      to_copy -= copy;
      if (to_copy == 0)
	break;
    }

  ssize_t bytes_written = __write (fd, buffer, bytes);

  free(malloced_buffer);

  return bytes_written;
}
Esempio n. 18
0
/* Remove shared memory object.  */
int
shm_unlink (const char *name)
{
    size_t namelen;
    char *fname;

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

    if (name[0] == '\0')
    {
        /* The name "/" is not supported.  */
        __set_errno (EINVAL);
        return -1;
    }

    namelen = strlen (name);
    fname = (char *) __alloca (sizeof SHMDIR - 1 + namelen + 1);
    __mempcpy (__mempcpy (fname, SHMDIR, sizeof SHMDIR - 1),
               name, namelen + 1);

    return unlink (name);
}
Esempio n. 19
0
internal_ucs4le_loop_unaligned (struct __gconv_step *step,
				struct __gconv_step_data *step_data,
				const unsigned char **inptrp,
				const unsigned char *inend,
				unsigned char **outptrp, unsigned char *outend,
				size_t *irreversible)
{
  const unsigned char *inptr = *inptrp;
  unsigned char *outptr = *outptrp;
  size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
  int result;

# if __BYTE_ORDER == __BIG_ENDIAN
  /* Sigh, we have to do some real work.  */
  size_t cnt;

  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
    {
      outptr[0] = inptr[3];
      outptr[1] = inptr[2];
      outptr[2] = inptr[1];
      outptr[3] = inptr[0];
    }

  *inptrp = inptr;
  *outptrp = outptr;
# elif __BYTE_ORDER == __LITTLE_ENDIAN
  /* Simply copy the data.  */
  *inptrp = inptr + n_convert * 4;
  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
# else
#  error "This endianess is not supported."
# endif

  /* Determine the status.  */
  if (*inptrp == inend)
    result = __GCONV_EMPTY_INPUT;
  else if (*inptrp + 4 > inend)
    result = __GCONV_INCOMPLETE_INPUT;
  else
    {
      assert (*outptrp + 4 > outend);
      result = __GCONV_FULL_OUTPUT;
    }

  return result;
}
Esempio n. 20
0
/* Append BUF, of length BUF_LEN to *TO, of length *TO_LEN, reallocating and
   updating *TO & *TO_LEN appropriately.  If an allocation error occurs,
   *TO's old value is freed, and *TO is set to 0.  */
static void
str_append (char **to, size_t *to_len, const char *buf, const size_t buf_len)
{
  size_t new_len = *to_len + buf_len;
  char *new_to = realloc (*to, new_len + 1);

  if (new_to)
    {
      *((char *) __mempcpy (new_to + *to_len, buf, buf_len)) = '\0';
      *to = new_to;
      *to_len = new_len;
    }
  else
    {
      free (*to);
      *to = 0;
    }
}
Esempio n. 21
0
nis_name
nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen)
{
  size_t i = 0;

  buffer[0] = '\0';

  while (name[i] != '.' && name[i] != '\0')
    i++;

  if (__glibc_unlikely (i >= buflen))
    {
      __set_errno (ERANGE);
      return NULL;
    }

  *((char *) __mempcpy (buffer, name, i)) = '\0';

  return buffer;
}
Esempio n. 22
0
_IO_size_t
_IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
{
  const char *s = (char *) data;
  _IO_size_t more = n;
  if (more <= 0)
    return 0;
  for (;;)
    {
      /* Space available. */
      if (f->_IO_write_ptr < f->_IO_write_end)
	{
	  _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
	  if (count > more)
	    count = more;
	  if (count > 20)
	    {
#ifdef _LIBC
	      f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
#else
	      memcpy (f->_IO_write_ptr, s, count);
	      f->_IO_write_ptr += count;
#endif
	      s += count;
	    }
	  else if (count)
	    {
	      char *p = f->_IO_write_ptr;
	      _IO_ssize_t i;
	      for (i = count; --i >= 0; )
		*p++ = *s++;
	      f->_IO_write_ptr = p;
	    }
	  more -= count;
	}
      if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
	break;
      more--;
    }
  return n - more;
}
Esempio n. 23
0
void
_dl_exception_create (struct dl_exception *exception, const char *objname,
                      const char *errstring)
{
  if (objname == NULL)
    objname = "";
  size_t len_objname = strlen (objname) + 1;
  size_t len_errstring = strlen (errstring) + 1;
  char *errstring_copy = malloc (len_objname + len_errstring);
  if (errstring_copy != NULL)
    {
      /* Make a copy of the object file name and the error string.  */
      exception->objname = memcpy (__mempcpy (errstring_copy,
                                              errstring, len_errstring),
                                   objname, len_objname);
      exception->errstring = errstring_copy;
      adjust_message_buffer (exception);
    }
  else
    oom_exception (exception);
}
Esempio n. 24
0
internal_ucs4_loop (struct __gconv_step *step,
		    struct __gconv_step_data *step_data,
		    const unsigned char **inptrp, const unsigned char *inend,
		    unsigned char **outptrp, unsigned char *outend,
		    size_t *irreversible)
{
  const unsigned char *inptr = *inptrp;
  unsigned char *outptr = *outptrp;
  size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
  int result;

#if __BYTE_ORDER == __LITTLE_ENDIAN
  /* Sigh, we have to do some real work.  */
  size_t cnt;
  uint32_t *outptr32 = (uint32_t *) outptr;

  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);

  *inptrp = inptr;
  *outptrp = (unsigned char *) outptr32;
#elif __BYTE_ORDER == __BIG_ENDIAN
  /* Simply copy the data.  */
  *inptrp = inptr + n_convert * 4;
  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
#else
# error "This endianess is not supported."
#endif

  /* Determine the status.  */
  if (*inptrp == inend)
    result = __GCONV_EMPTY_INPUT;
  else if (*outptrp + 4 > outend)
    result = __GCONV_FULL_OUTPUT;
  else
    result = __GCONV_INCOMPLETE_INPUT;

  return result;
}
Esempio n. 25
0
_IO_size_t
_IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
{
  _IO_size_t more = n;
  char *s = (char*) data;
  for (;;)
    {
      /* Data available. */
      if (fp->_IO_read_ptr < fp->_IO_read_end)
	{
	  _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
	  if (count > more)
	    count = more;
	  if (count > 20)
	    {
#ifdef _LIBC
	      s = __mempcpy (s, fp->_IO_read_ptr, count);
#else
	      memcpy (s, fp->_IO_read_ptr, count);
	      s += count;
#endif
	      fp->_IO_read_ptr += count;
	    }
	  else if (count)
	    {
	      char *p = fp->_IO_read_ptr;
	      int i = (int) count;
	      while (--i >= 0)
		*s++ = *p++;
	      fp->_IO_read_ptr = p;
	    }
	    more -= count;
	}
      if (more == 0 || __underflow (fp) == EOF)
	break;
    }
  return n - more;
}
Esempio n. 26
0
const char *
_dl_get_origin (void)
{
  char *result = (char *) -1;
  /* We use the environment variable LD_ORIGIN_PATH.  If it is set make
     a copy and strip out trailing slashes.  */
  if (GLRO(dl_origin_path) != NULL)
    {
      size_t len = strlen (GLRO(dl_origin_path));
      result = (char *) malloc (len + 1);
      if (result == NULL)
	result = (char *) -1;
      else
	{
	  char *cp = __mempcpy (result, GLRO(dl_origin_path), len);
	  while (cp > result + 1 && cp[-1] == '/')
	    --cp;
	  *cp = '\0';
	}
    }

  return result;
}
Esempio n. 27
0
/* Return a string describing the errno code in ERRNUM.  */
char *
__strerror_r (int errnum, char *buf, size_t buflen)
{
  if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
			|| _sys_errlist_internal[errnum] == NULL, 0))
    {
      /* Buffer we use to print the number in.  For a maximum size for
	 `int' of 8 bytes we never need more than 20 digits.  */
      char numbuf[21];
      const char *unk = _("Unknown error ");
      size_t unklen = strlen (unk);
      char *p, *q;
      bool negative = errnum < 0;

      numbuf[20] = '\0';
      p = _itoa_word (abs (errnum), &numbuf[20], 10, 0);

      /* Now construct the result while taking care for the destination
	 buffer size.  */
      q = __mempcpy (buf, unk, MIN (unklen, buflen));
      if (negative && unklen < buflen)
	{
	  *q++ = '-';
	  ++unklen;
	}
      if (unklen < buflen)
	memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen));

      /* Terminate the string in any case.  */
      if (buflen > 0)
	buf[buflen - 1] = '\0';

      return buf;
    }

  return (char *) _(_sys_errlist_internal[errnum]);
}
Esempio n. 28
0
static void
exchange (char **argv, struct _getopt_data *d)
{
  int bottom = d->__first_nonopt;
  int middle = d->__last_nonopt;
  int top = d->optind;
  char *tem;

  /* Exchange the shorter segment with the far end of the longer segment.
     That puts the shorter segment into the right place.
     It leaves the longer segment in the right place overall,
     but it consists of two parts that need to be swapped next.  */

#if defined _LIBC && defined USE_NONOPTION_FLAGS
  /* First make sure the handling of the '__getopt_nonoption_flags'
     string can work normally.  Our top argument must be in the range
     of the string.  */
  if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
    {
      /* We must extend the array.  The user plays games with us and
         presents new arguments.  */
      char *new_str = malloc (top + 1);
      if (new_str == NULL)
        d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
      else
        {
          memset (__mempcpy (new_str, __getopt_nonoption_flags,
                             d->__nonoption_flags_max_len),
                  '\0', top + 1 - d->__nonoption_flags_max_len);
          d->__nonoption_flags_max_len = top + 1;
          __getopt_nonoption_flags = new_str;
        }
    }
#endif

  while (top > middle && middle > bottom)
    {
      if (top - middle > middle - bottom)
        {
          /* Bottom segment is the short one.  */
          int len = middle - bottom;
          register int i;

          /* Swap it with the top part of the top segment.  */
          for (i = 0; i < len; i++)
            {
              tem = argv[bottom + i];
              argv[bottom + i] = argv[top - (middle - bottom) + i];
              argv[top - (middle - bottom) + i] = tem;
              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
            }
          /* Exclude the moved bottom segment from further swapping.  */
          top -= len;
        }
      else
        {
          /* Top segment is the short one.  */
          int len = top - middle;
          register int i;

          /* Swap it with the bottom part of the bottom segment.  */
          for (i = 0; i < len; i++)
            {
              tem = argv[bottom + i];
              argv[bottom + i] = argv[middle + i];
              argv[middle + i] = tem;
              SWAP_FLAGS (bottom + i, middle + i);
            }
          /* Exclude the moved top segment from further swapping.  */
          bottom += len;
        }
    }

  /* Update records for the slots the non-options now occupy.  */

  d->__first_nonopt += (d->optind - d->__last_nonopt);
  d->__last_nonopt = d->optind;
}
Esempio n. 29
0
static void
msort_with_tmp (const struct msort_param *p, void *b, size_t n)
{
  char *b1, *b2;
  size_t n1, n2;

  if (n <= 1)
    return;

  n1 = n / 2;
  n2 = n - n1;
  b1 = b;
  b2 = (char *) b + (n1 * p->s);

  msort_with_tmp (p, b1, n1);
  msort_with_tmp (p, b2, n2);

  char *tmp = p->t;
  const size_t s = p->s;
  __compar_d_fn_t cmp = p->cmp;
  void *arg = p->arg;
  switch (p->var)
    {
    case 0:
      while (n1 > 0 && n2 > 0)
	{
	  if ((*cmp) (b1, b2, arg) <= 0)
	    {
	      *(uint32_t *) tmp = *(uint32_t *) b1;
	      b1 += sizeof (uint32_t);
	      --n1;
	    }
	  else
	    {
	      *(uint32_t *) tmp = *(uint32_t *) b2;
	      b2 += sizeof (uint32_t);
	      --n2;
	    }
	  tmp += sizeof (uint32_t);
	}
      break;
    case 1:
      while (n1 > 0 && n2 > 0)
	{
	  if ((*cmp) (b1, b2, arg) <= 0)
	    {
	      *(uint64_t *) tmp = *(uint64_t *) b1;
	      b1 += sizeof (uint64_t);
	      --n1;
	    }
	  else
	    {
	      *(uint64_t *) tmp = *(uint64_t *) b2;
	      b2 += sizeof (uint64_t);
	      --n2;
	    }
	  tmp += sizeof (uint64_t);
	}
      break;
    case 2:
      while (n1 > 0 && n2 > 0)
	{
	  unsigned long *tmpl = (unsigned long *) tmp;
	  unsigned long *bl;

	  tmp += s;
	  if ((*cmp) (b1, b2, arg) <= 0)
	    {
	      bl = (unsigned long *) b1;
	      b1 += s;
	      --n1;
	    }
	  else
	    {
	      bl = (unsigned long *) b2;
	      b2 += s;
	      --n2;
	    }
	  while (tmpl < (unsigned long *) tmp)
	    *tmpl++ = *bl++;
	}
      break;
    case 3:
      while (n1 > 0 && n2 > 0)
	{
	  if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0)
	    {
	      *(void **) tmp = *(void **) b1;
	      b1 += sizeof (void *);
	      --n1;
	    }
	  else
	    {
	      *(void **) tmp = *(void **) b2;
	      b2 += sizeof (void *);
	      --n2;
	    }
	  tmp += sizeof (void *);
	}
      break;
    default:
      while (n1 > 0 && n2 > 0)
	{
	  if ((*cmp) (b1, b2, arg) <= 0)
	    {
	      tmp = (char *) __mempcpy (tmp, b1, s);
	      b1 += s;
	      --n1;
	    }
	  else
	    {
	      tmp = (char *) __mempcpy (tmp, b2, s);
	      b2 += s;
	      --n2;
	    }
	}
      break;
    }

  if (n1 > 0)
    memcpy (tmp, b1, n1 * s);
  memcpy (b, p->t, (n - n2) * s);
}
Esempio n. 30
0
void
__vsyslog_chk(int pri, int flag, const char *fmt, va_list ap)
{
    struct tm now_tm;
    time_t now;
    int fd;
    FILE *f;
    char *buf = 0;
    size_t bufsize = 0;
    size_t msgoff;
#ifndef NO_SIGPIPE
    struct sigaction action, oldaction;
    int sigpipe;
#endif
    int saved_errno = errno;
    char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];

#define	INTERNALLOG	LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
    /* Check for invalid bits. */
    if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
        syslog(INTERNALLOG,
               "syslog: unknown facility/priority: %x", pri);
        pri &= LOG_PRIMASK|LOG_FACMASK;
    }

    /* Check priority against setlogmask values. */
    if ((LOG_MASK (LOG_PRI (pri)) & LogMask) == 0)
        return;

    /* Set default facility if none specified. */
    if ((pri & LOG_FACMASK) == 0)
        pri |= LogFacility;

    /* Build the message in a memory-buffer stream.  */
    f = __open_memstream (&buf, &bufsize);
    if (f == NULL)
    {
        /* We cannot get a stream.  There is not much we can do but
           emitting an error messages.  */
        char numbuf[3 * sizeof (pid_t)];
        char *nump;
        char *endp = __stpcpy (failbuf, "out of memory [");
        pid_t pid = __getpid ();

        nump = numbuf + sizeof (numbuf);
        /* The PID can never be zero.  */
        do
            *--nump = '0' + pid % 10;
        while ((pid /= 10) != 0);

        endp = __mempcpy (endp, nump, (numbuf + sizeof (numbuf)) - nump);
        *endp++ = ']';
        *endp = '\0';
        buf = failbuf;
        bufsize = endp - failbuf;
        msgoff = 0;
    }
    else
    {
        __fsetlocking (f, FSETLOCKING_BYCALLER);
        fprintf (f, "<%d>", pri);
        (void) time (&now);
        f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
                                          f->_IO_write_end
                                          - f->_IO_write_ptr,
                                          "%h %e %T ",
                                          __localtime_r (&now, &now_tm),
                                          _nl_C_locobj_ptr);
        msgoff = ftell (f);
        if (LogTag == NULL)
            LogTag = __progname;
        if (LogTag != NULL)
            __fputs_unlocked (LogTag, f);
        if (LogStat & LOG_PID)
            fprintf (f, "[%d]", (int) __getpid ());
        if (LogTag != NULL)
        {
            putc_unlocked (':', f);
            putc_unlocked (' ', f);
        }

        /* Restore errno for %m format.  */
        __set_errno (saved_errno);

        /* We have the header.  Print the user's format into the
               buffer.  */
        if (flag == -1)
            vfprintf (f, fmt, ap);
        else
            __vfprintf_chk (f, flag, fmt, ap);

        /* Close the memory stream; this will finalize the data
           into a malloc'd buffer in BUF.  */
        fclose (f);
    }

    /* Output to stderr if requested. */
    if (LogStat & LOG_PERROR) {
        struct iovec iov[2];
        struct iovec *v = iov;

        v->iov_base = buf + msgoff;
        v->iov_len = bufsize - msgoff;
        /* Append a newline if necessary.  */
        if (buf[bufsize - 1] != '\n')
        {
            ++v;
            v->iov_base = (char *) "\n";
            v->iov_len = 1;
        }

        __libc_cleanup_push (free, buf == failbuf ? NULL : buf);

        /* writev is a cancellation point.  */
        (void)__writev(STDERR_FILENO, iov, v - iov + 1);

        __libc_cleanup_pop (0);
    }

    /* Prepare for multiple users.  We have to take care: open and
       write are cancellation points.  */
    struct cleanup_arg clarg;
    clarg.buf = buf;
    clarg.oldaction = NULL;
    __libc_cleanup_push (cancel_handler, &clarg);
    __libc_lock_lock (syslog_lock);

#ifndef NO_SIGPIPE
    /* Prepare for a broken connection.  */
    memset (&action, 0, sizeof (action));
    action.sa_handler = sigpipe_handler;
    sigemptyset (&action.sa_mask);
    sigpipe = __sigaction (SIGPIPE, &action, &oldaction);
    if (sigpipe == 0)
        clarg.oldaction = &oldaction;
#endif

    /* Get connected, output the message to the local logger. */
    if (!connected)
        openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);

    /* If we have a SOCK_STREAM connection, also send ASCII NUL as
       a record terminator.  */
    if (LogType == SOCK_STREAM)
        ++bufsize;

    if (!connected || __send(LogFile, buf, bufsize, send_flags) < 0)
    {
        if (connected)
        {
            /* Try to reopen the syslog connection.  Maybe it went
               down.  */
            closelog_internal ();
            openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
        }

        if (!connected || __send(LogFile, buf, bufsize, send_flags) < 0)
        {
            closelog_internal ();	/* attempt re-open next time */
            /*
             * Output the message to the console; don't worry
             * about blocking, if console blocks everything will.
             * Make sure the error reported is the one from the
             * syslogd failure.
             */
            if (LogStat & LOG_CONS &&
                    (fd = __open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0)
            {
                __dprintf (fd, "%s\r\n", buf + msgoff);
                (void)__close(fd);
            }
        }
    }

#ifndef NO_SIGPIPE
    if (sigpipe == 0)
        __sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
#endif

    /* End of critical section.  */
    __libc_cleanup_pop (0);
    __libc_lock_unlock (syslog_lock);

    if (buf != failbuf)
        free (buf);
}