Exemple #1
0
/* Get information about the file NAME relative to FD in ST.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
      int result;

      if (__builtin_expect (vers == _STAT_VER, 1))
	{
	  struct stat16 buf16;
	  result =
	    INLINE_SYSCALL (fstatat, 4, fd, CHECK_STRING (file),
			    __ptrvalue (&buf16), flag);
	  if (result == 0)
	    stat16_to_stat (&buf16, st);
	}
      else if (__builtin_expect (vers == _STAT_VER_stat, 1))
	{
	  result =
	    INLINE_SYSCALL (fstatat, 4, fd, CHECK_STRING (file),
			    CHECK_1 ((struct stat16 *) st), flag);
	}
      else
	{
	  __set_errno (EINVAL);
	  return -1;
	}
	return result;
}
Exemple #2
0
/* Get information about the file FD in BUF.  */
int
__fxstat (int vers, int fd, struct stat *buf)
{
  if (vers == _STAT_VER_KERNEL || vers == _STAT_VER_LINUX)
    return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 (buf));

  __set_errno (EINVAL);
  return -1;
}
Exemple #3
0
/* Get information about the file FD in BUF.  */
int
__lxstat (int vers, const char *name, struct stat *buf)
{
  if (vers == _STAT_VER_KERNEL || vers == _STAT_VER_LINUX)
    return INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), CHECK_1 (buf));

  __set_errno (EINVAL);
  return -1;
}
Exemple #4
0
int
ustat (dev_t dev, struct ustat *ubuf)
{
  unsigned short int k_dev;

  /* We must convert the value to dev_t type used by the kernel.  */
  k_dev = ((major (dev) & 0xff) << 8) | (minor (dev) & 0xff);

  return INLINE_SYSCALL (ustat, 2, k_dev, CHECK_1 (ubuf));
}
Exemple #5
0
int
__lxstat64 (int vers, const char *file, struct stat64 *buf)
{
  if(vers != _STAT_VER)
    {
      __set_errno (EINVAL);
      return -1;
    }

  return INLINE_SYSCALL (lstat64, 2, file, CHECK_1 (buf));
}
int
___fxstat64 (int vers, int fd, struct stat64 *buf)
{
  int result;
  result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (buf));
#if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
  if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino)
    buf->st_ino = buf->__st_ino;
#endif
  return result;
}
/* Get information about the file descriptor FD in BUF.  */
int
__fxstat (int vers, int fd, struct stat *buf)
{
  if (vers != _STAT_VER)
    {
      __set_errno (EINVAL);
      return -1;
    }

  return __syscall_fstat (fd, CHECK_1 (buf));
}
Exemple #8
0
int
___xstat64 (int vers, const char *name, struct stat64 *buf)
{
  int result;
#if __ASSUME_STAT64_SYSCALL > 0
  result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));
# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
  if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino)
    buf->st_ino = buf->__st_ino;
# endif
  return result;
#else
  struct kernel_stat kbuf;
# if defined __NR_stat64
  if (! __have_no_stat64)
    {
      int saved_errno = errno;
      result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (buf));

      if (result != -1 || errno != ENOSYS)
	{
#  if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
	  if (!result && buf->__st_ino != (__ino_t) buf->st_ino)
	    buf->st_ino = buf->__st_ino;
#  endif
	  return result;
	}

      __set_errno (saved_errno);
      __have_no_stat64 = 1;
    }
# endif

  result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name), __ptrvalue (&kbuf));
  if (result == 0)
    result = __xstat64_conv (vers, &kbuf, buf);

  return result;
#endif
}
int
__new_setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
{
#ifdef __ASSUME_NEW_GETRLIMIT_SYSCALL
  return INLINE_SYSCALL (setrlimit, 2, resource, CHECK_1 (rlimits));
#else
  struct rlimit rlimits_small;

# ifdef __NR_ugetrlimit
  if (__have_no_new_getrlimit == 0)
    {
      /* Check if the new ugetrlimit syscall exists.  We must do this
	 first because older kernels don't reject negative rlimit
	 values in setrlimit.  */
      int result = INLINE_SYSCALL (ugetrlimit, 2, resource, __ptrvalue (&rlimits_small));
      if (result != -1 || errno != ENOSYS)
	/* The syscall exists.  */
	__have_no_new_getrlimit = -1;
      else
	/* The syscall does not exist.  */
	__have_no_new_getrlimit = 1;
    }
  if (__have_no_new_getrlimit < 0)
    return INLINE_SYSCALL (setrlimit, 2, resource, CHECK_1 (rlimits));
# endif

  /* We might have to correct the limits values.  Since the old values
     were signed the new values might be too large.  */
  rlimits_small.rlim_cur = MIN ((unsigned long int) rlimits->rlim_cur,
				RLIM_INFINITY >> 1);
  rlimits_small.rlim_max = MIN ((unsigned long int) rlimits->rlim_max,
				RLIM_INFINITY >> 1);

  /* Use the adjusted values.  */
  return INLINE_SYSCALL (setrlimit, 2, resource, __ptrvalue (&rlimits_small));
#endif
}
Exemple #10
0
/* Get information about the file FD in BUF.  */
int
__fxstat (int vers, int fd, struct stat *buf)
{
    struct kernel_stat kbuf;
    int result;

    if (vers == _STAT_VER_KERNEL)
        return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 ((struct kernel_stat *) buf));

    result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf));
    if (result == 0)
        result = xstat_conv (vers, &kbuf, buf);

    return result;
}
Exemple #11
0
int
ustat (dev_t dev, struct ustat *ubuf)
{
  unsigned long long int k_dev;

  /* We must convert the value to dev_t type used by the kernel.  */
  k_dev =  dev & ((1ULL << 32) - 1);
  if (k_dev != dev)
    {
      __set_errno (EINVAL);
      return -1;
    }

  return INLINE_SYSCALL (ustat, 2, (unsigned int) k_dev, CHECK_1 (ubuf));
}
Exemple #12
0
/* Get information about the file FD in BUF.  */
int
__fxstat (int vers, int fd, struct stat *buf)
{
#if __ASSUME_STAT64_SYSCALL == 0
  struct kernel_stat kbuf;
#endif
  int result;

  if (vers == _STAT_VER_KERNEL)
    return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 ((struct kernel_stat *) buf));

#if __ASSUME_STAT64_SYSCALL > 0
  {
    struct stat64 buf64;

    result = INLINE_SYSCALL (fstat64, 2, fd, __ptrvalue (&buf64));
    if (result == 0)
      result = __xstat32_conv (vers, &buf64, buf);
    return result;
  }
#else

# if defined __NR_stat64
  /* To support 32 bit UIDs, we have to use stat64.  The normal stat call only returns
     16 bit UIDs.  */
  if (! __have_no_stat64)
    {
      struct stat64 buf64;

      result = INLINE_SYSCALL (fstat64, 2, fd, __ptrvalue (&buf64));

      if (result == 0)
	result = __xstat32_conv (vers, &buf64, buf);

      if (result != -1 || errno != ENOSYS)
	return result;

      __have_no_stat64 = 1;
    }
# endif

  result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf));
  if (result == 0)
    result = __xstat_conv (vers, &kbuf, buf);

  return result;
#endif  /* __ASSUME_STAT64_SYSCALL  */
}
Exemple #13
0
int
__xstat (int vers, const char *file, struct stat *buf)
{
  if (__builtin_expect (vers == _STAT_VER, 1))
    {
      struct stat16 buf16;
      int result = __syscall_stat (CHECK_STRING (file), __ptrvalue (&buf16));
      if (result == 0)
	stat16_to_stat (&buf16, buf);
      return result;
    }
  else if (__builtin_expect (vers == _STAT_VER_stat, 1))
    return __syscall_stat (CHECK_STRING (file),
			   CHECK_1 ((struct stat16 *) buf));
  else
    {
      __set_errno (EINVAL);
      return -1;
    }
}
Exemple #14
0
/* Get information about the file NAME in BUF.  */
int
__xstat (int vers, const char *name, struct stat *buf)
{
  if (vers == _STAT_VER_KERNEL)
    return INLINE_SYSCALL (stat, 2, CHECK_STRING (name),
			   CHECK_1 ((struct kernel_stat *) buf));

#ifdef STAT_IS_KERNEL_STAT
  errno = EINVAL;
  return -1;
#else
  struct kernel_stat kbuf;
  int result;

  result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name),
			   __ptrvalue (&kbuf));
  if (result == 0)
    result = __xstat_conv (vers, &kbuf, buf);

  return result;
#endif
}
static int
do_sigtimedwait (const sigset_t *set, siginfo_t *info,
		 const struct timespec *timeout)
{
#ifdef SIGCANCEL
  sigset_t tmpset;
  if (set != NULL
      && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
# ifdef SIGSETXID
	  || __builtin_expect (__sigismember (set, SIGSETXID), 0)
# endif
	  ))
    {
      /* Create a temporary mask without the bit for SIGCANCEL set.  */
      // We are not copying more than we have to.
      memcpy (&tmpset, set, _NSIG / 8);
      __sigdelset (&tmpset, SIGCANCEL);
# ifdef SIGSETXID
      __sigdelset (&tmpset, SIGSETXID);
# endif
      set = &tmpset;
    }
#endif

    /* XXX The size argument hopefully will have to be changed to the
       real size of the user-level sigset_t.  */
  int result = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
			       CHECK_1 (info), timeout, _NSIG / 8);

  /* The kernel generates a SI_TKILL code in si_code in case tkill is
     used.  tkill is transparently used in raise().  Since having
     SI_TKILL as a code is useful in general we fold the results
     here.  */
  if (result != -1 && info != NULL && info->si_code == SI_TKILL)
    info->si_code = SI_USER;

  return result;
}
int
__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
{
#if __ASSUME_IPC64 > 0
  return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0,
			 CHECK_1 (buf));
#else
  switch (cmd) {
    case SHM_STAT:
    case IPC_STAT:
    case IPC_SET:
#if __WORDSIZE != 32
    case IPC_INFO:
#endif
      break;
    default:
      return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0,
			     CHECK_1 (buf));
  }

  {
    int save_errno = errno, result;
    union
      {
	struct __old_shmid_ds ds;
	struct __old_shminfo info;
      } old;

    /* Unfortunately there is no way how to find out for sure whether
       we should use old or new shmctl.  */
    result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd | __IPC_64, 0,
			     CHECK_1 (buf));
    if (result != -1 || errno != EINVAL)
      return result;

    __set_errno(save_errno);
    if (cmd == IPC_SET)
      {
	old.ds.shm_perm.uid = buf->shm_perm.uid;
	old.ds.shm_perm.gid = buf->shm_perm.gid;
	old.ds.shm_perm.mode = buf->shm_perm.mode;
	if (old.ds.shm_perm.uid != buf->shm_perm.uid ||
	    old.ds.shm_perm.gid != buf->shm_perm.gid)
	  {
	    __set_errno (EINVAL);
	    return -1;
	  }
      }
    result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl, shmid, cmd, 0,
			     __ptrvalue (&old.ds));
    if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT))
      {
	memset(buf, 0, sizeof(*buf));
	buf->shm_perm.__key = old.ds.shm_perm.__key;
	buf->shm_perm.uid = old.ds.shm_perm.uid;
	buf->shm_perm.gid = old.ds.shm_perm.gid;
	buf->shm_perm.cuid = old.ds.shm_perm.cuid;
	buf->shm_perm.cgid = old.ds.shm_perm.cgid;
	buf->shm_perm.mode = old.ds.shm_perm.mode;
	buf->shm_perm.__seq = old.ds.shm_perm.__seq;
	buf->shm_atime = old.ds.shm_atime;
	buf->shm_dtime = old.ds.shm_dtime;
	buf->shm_ctime = old.ds.shm_ctime;
	buf->shm_segsz = old.ds.shm_segsz;
	buf->shm_nattch = old.ds.shm_nattch;
	buf->shm_cpid = old.ds.shm_cpid;
	buf->shm_lpid = old.ds.shm_lpid;
      }
#if __WORDSIZE != 32
    else if (result != -1 && cmd == IPC_INFO)
      {
	struct shminfo *i = (struct shminfo *)buf;

	memset(i, 0, sizeof(*i));
	i->shmmax = old.info.shmmax;
	i->shmmin = old.info.shmmin;
	i->shmmni = old.info.shmmni;
	i->shmseg = old.info.shmseg;
	i->shmall = old.info.shmall;
      }
#endif
    return result;
  }
#endif
}
Exemple #17
0
int
__old_shmctl (int shmid, int cmd, struct __old_shmid_ds *buf)
{
  return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
			 shmid, cmd, 0, CHECK_1 (buf));
}
Exemple #18
0
int
__new_getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits)
{
  return INLINE_SYSCALL (ugetrlimit, 2, resource, CHECK_1 (rlimits));
}
Exemple #19
0
int
__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
{
#if __ASSUME_32BITUIDS > 0
  return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
			 shmid, cmd | __IPC_64, 0, CHECK_1 (buf));
#else
  switch (cmd) {
    case SHM_STAT:
    case IPC_STAT:
    case IPC_SET:
# if __WORDSIZE != 32
    case IPC_INFO:
# endif
      break;
    default:
      return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
			     shmid, cmd, 0, CHECK_1 (buf));
  }

  {
    struct __old_shmid_ds old;
    int result;

# ifdef __NR_getuid32
    if (__libc_missing_32bit_uids <= 0)
      {
	if (__libc_missing_32bit_uids < 0)
	  {
	    int save_errno = errno;

	    /* Test presence of new IPC by testing for getuid32 syscall.  */
	    result = INLINE_SYSCALL (getuid32, 0);
	    if (result == -1 && errno == ENOSYS)
	      __libc_missing_32bit_uids = 1;
	    else
	      __libc_missing_32bit_uids = 0;
	    __set_errno(save_errno);
	  }
	if (__libc_missing_32bit_uids <= 0)
	  return INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
				 shmid, cmd | __IPC_64, 0, CHECK_1 (buf));
      }
# endif

    if (cmd == IPC_SET)
      {
	old.shm_perm.uid = buf->shm_perm.uid;
	old.shm_perm.gid = buf->shm_perm.gid;
	old.shm_perm.mode = buf->shm_perm.mode;
	if (old.shm_perm.uid != buf->shm_perm.uid ||
	    old.shm_perm.gid != buf->shm_perm.gid)
	  {
	    __set_errno (EINVAL);
	    return -1;
	  }
      }
    result = INLINE_SYSCALL (ipc, 5, IPCOP_shmctl,
			     shmid, cmd, 0, __ptrvalue (&old));
    if (result != -1 && (cmd == SHM_STAT || cmd == IPC_STAT))
      {
	memset(buf, 0, sizeof(*buf));
	buf->shm_perm.__key = old.shm_perm.__key;
	buf->shm_perm.uid = old.shm_perm.uid;
	buf->shm_perm.gid = old.shm_perm.gid;
	buf->shm_perm.cuid = old.shm_perm.cuid;
	buf->shm_perm.cgid = old.shm_perm.cgid;
	buf->shm_perm.mode = old.shm_perm.mode;
	buf->shm_perm.__seq = old.shm_perm.__seq;
	buf->shm_atime = old.shm_atime;
	buf->shm_dtime = old.shm_dtime;
	buf->shm_ctime = old.shm_ctime;
	buf->shm_segsz = old.shm_segsz;
	buf->shm_nattch = old.shm_nattch;
	buf->shm_cpid = old.shm_cpid;
	buf->shm_lpid = old.shm_lpid;
      }
# if __WORDSIZE != 32
    else if (result != -1 && cmd == IPC_INFO)
      {
	struct __old_shminfo *oldi = (struct __old_shminfo *)&old;
	struct shminfo *i = (struct shminfo *)buf;

	memset(i, 0, sizeof(*i));
	i->shmmax = oldi->shmmax;
	i->shmmin = oldi->shmmin;
	i->shmmni = oldi->shmmni;
	i->shmseg = oldi->shmseg;
	i->shmall = oldi->shmall;
      }
# endif
    return result;
  }
#endif
}
Exemple #20
0
int
__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
{
  /* This is a misnomer -- Alpha had 32-bit uids at the beginning
     of time.  However, msg_qnum and msg_qbytes changed size at
     the same time the size of uid changed elsewhere.  */
#if __ASSUME_32BITUIDS > 0
  return INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, CHECK_1 (buf));
#else
  switch (cmd) {
    case MSG_STAT:
    case IPC_STAT:
    case IPC_SET:
      break;
    default:
      return INLINE_SYSCALL (msgctl, 3, msqid, cmd, CHECK_1 (buf));
  }

  {
    int save_errno = errno, result;
    struct __old_msqid_ds old;

    /* Unfortunately there is no way how to find out for sure whether
       we should use old or new msgctl.  */
    result = INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, CHECK_1 (buf));
    if (result != -1 || errno != EINVAL)
      return result;

    __set_errno(save_errno);
    if (cmd == IPC_SET)
      {
	old.msg_perm.uid = buf->msg_perm.uid;
	old.msg_perm.gid = buf->msg_perm.gid;
	old.msg_perm.mode = buf->msg_perm.mode;
	old.msg_qbytes = buf->msg_qbytes;
	if (old.msg_perm.uid != buf->msg_perm.uid ||
	    old.msg_perm.gid != buf->msg_perm.gid ||
	    old.msg_qbytes != buf->msg_qbytes)
	  {
	    __set_errno (EINVAL);
	    return -1;
	  }
      }
    result = INLINE_SYSCALL (msgctl, 3, msqid, cmd, __ptrvalue (&old));
    if (result != -1 && cmd != IPC_SET)
      {
	memset(buf, 0, sizeof(*buf));
	buf->msg_perm.__key = old.msg_perm.__key;
	buf->msg_perm.uid = old.msg_perm.uid;
	buf->msg_perm.gid = old.msg_perm.gid;
	buf->msg_perm.cuid = old.msg_perm.cuid;
	buf->msg_perm.cgid = old.msg_perm.cgid;
	buf->msg_perm.mode = old.msg_perm.mode;
	buf->msg_perm.__seq = old.msg_perm.__seq;
	buf->msg_stime = old.msg_stime;
	buf->msg_rtime = old.msg_rtime;
	buf->msg_ctime = old.msg_ctime;
	buf->__msg_cbytes = old.__msg_cbytes;
	buf->msg_qnum = old.msg_qnum;
	buf->msg_qbytes = old.msg_qbytes;
	buf->msg_lspid = old.msg_lspid;
	buf->msg_lrpid = old.msg_lrpid;
      }
    return result;
  }
#endif
}
Exemple #21
0
long int
ptrace (enum __ptrace_request request, ...)
{
  long int res, ret;
  va_list ap;
  pid_t pid;
  void *addr, *data;

  va_start (ap, request);
  pid = va_arg (ap, pid_t);
  addr = va_arg (ap, void *);
  data = va_arg (ap, void *);
  va_end (ap);

  if (request > 0 && request < 4)
    data = &ret;

#if __BOUNDED_POINTERS__
  switch (request)
    {
    case PTRACE_PEEKTEXT:
    case PTRACE_PEEKDATA:
    case PTRACE_PEEKUSER:
    case PTRACE_POKETEXT:
    case PTRACE_POKEDATA:
    case PTRACE_POKEUSER:
      (void) CHECK_1 ((int *) addr);
      (void) CHECK_1 ((int *) data);
      break;

    case PTRACE_GETREGS:
    case PTRACE_SETREGS:
#ifdef __i386__
      (void) CHECK_1 ((struct user_regs_struct *) data);
#else
      /* We don't know the size of data, so the best we can do is ensure
	 that `data' is valid for at least one word.  */
      (void) CHECK_1 ((int *) data);
#endif
      break;

    case PTRACE_GETFPREGS:
    case PTRACE_SETFPREGS:
#ifdef __i386__
      (void) CHECK_1 ((struct user_fpregs_struct *) data);
#else
      /* We don't know the size of data, so the best we can do is ensure
	 that `data' is valid for at least one word.  */
      (void) CHECK_1 ((int *) data);
#endif
      break;

    case PTRACE_GETFPXREGS:
    case PTRACE_SETFPXREGS:
#ifdef __i386__
      (void) CHECK_1 ((struct user_fpxregs_struct *) data);
#else
      /* We don't know the size of data, so the best we can do is ensure
	 that `data' is valid for at least one word.  */
      (void) CHECK_1 ((int *) data);
#endif
      break;

    case PTRACE_GETSIGINFO:
    case PTRACE_SETSIGINFO:
      (void) CHECK_1 ((siginfo_t *) data);
      break;

    case PTRACE_GETEVENTMSG:
      (void) CHECK_1 ((unsigned long *) data);
      break;

    case PTRACE_SETOPTIONS:
      (void) CHECK_1 ((long *) data);
      break;

    case PTRACE_TRACEME:
    case PTRACE_CONT:
    case PTRACE_KILL:
    case PTRACE_SINGLESTEP:
    case PTRACE_ATTACH:
    case PTRACE_DETACH:
    case PTRACE_SYSCALL:
      /* Neither `data' nor `addr' needs any checks.  */
      break;
    };
#endif

  res = INLINE_SYSCALL (ptrace, 4, request, pid,
			__ptrvalue (addr), __ptrvalue (data));
  if (res >= 0 && request > 0 && request < 4)
    {
      __set_errno (0);
      return ret;
    }

  return res;
}
Exemple #22
0
int
attribute_compat_text_section
__old_msgctl (int msqid, int cmd, struct __old_msqid_ds *buf)
{
  return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl, msqid, cmd, 0, CHECK_1 (buf));
}
Exemple #23
0
int
__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
{
#if __ASSUME_IPC64 > 0
  return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
			 msqid, cmd | __IPC_64, 0, CHECK_1 (buf));
#else
  switch (cmd) {
    case MSG_STAT:
    case IPC_STAT:
    case IPC_SET:
      break;
    default:
      return INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
			     msqid, cmd, 0, CHECK_1 (buf));
  }

  {
    int result;
    struct __old_msqid_ds old;

    /* Unfortunately there is no way how to find out for sure whether
       we should use old or new msgctl.  */
    result = INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
			     msqid, cmd | __IPC_64, 0, CHECK_1 (buf));
    if (result != -1 || errno != EINVAL)
      return result;

    if (cmd == IPC_SET)
      {
	old.msg_perm.uid = buf->msg_perm.uid;
	old.msg_perm.gid = buf->msg_perm.gid;
	old.msg_perm.mode = buf->msg_perm.mode;
	old.msg_qbytes = buf->msg_qbytes;
	if (old.msg_perm.uid != buf->msg_perm.uid ||
	    old.msg_perm.gid != buf->msg_perm.gid ||
	    old.msg_qbytes != buf->msg_qbytes)
	  {
	    __set_errno (EINVAL);
	    return -1;
	  }
      }
    result = INLINE_SYSCALL (ipc, 5, IPCOP_msgctl,
			     msqid, cmd, 0, __ptrvalue (&old));
    if (result != -1 && cmd != IPC_SET)
      {
	memset(buf, 0, sizeof(*buf));
	buf->msg_perm.__key = old.msg_perm.__key;
	buf->msg_perm.uid = old.msg_perm.uid;
	buf->msg_perm.gid = old.msg_perm.gid;
	buf->msg_perm.cuid = old.msg_perm.cuid;
	buf->msg_perm.cgid = old.msg_perm.cgid;
	buf->msg_perm.mode = old.msg_perm.mode;
	buf->msg_perm.__seq = old.msg_perm.__seq;
	buf->msg_stime = old.msg_stime;
	buf->msg_rtime = old.msg_rtime;
	buf->msg_ctime = old.msg_ctime;
	buf->__msg_cbytes = old.__msg_cbytes;
	buf->msg_qnum = old.msg_qnum;
	buf->msg_qbytes = old.msg_qbytes;
	buf->msg_lspid = old.msg_lspid;
	buf->msg_lrpid = old.msg_lrpid;
      }
    return result;
  }
#endif
}
Exemple #24
0
/* Get information about the file NAME in BUF.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
  int result;
  INTERNAL_SYSCALL_DECL (err);
#ifdef STAT_IS_KERNEL_STAT
# define kst (*st)
#else
  struct kernel_stat kst;
#endif

#ifdef __NR_newfstatat
# ifndef __ASSUME_ATFCTS
  if (__have_atfcts >= 0)
# endif
    {
      result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
# ifndef __ASSUME_ATFCTS
      if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
	  && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
	__have_atfcts = -1;
      else
# endif
	if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	  {
#ifdef STAT_IS_KERNEL_STAT
	    return 0;
#else
	    return __xstat_conv (vers, &kst, st);
#endif
	  }
	else
	  {
	    __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
	    return -1;
	  }
    }
#endif

  if (flag & ~AT_SYMLINK_NOFOLLOW)
    {
      __set_errno (EINVAL);
      return -1;
    }

  char *buf = NULL;

  if (fd != AT_FDCWD && file[0] != '/')
    {
      size_t filelen = strlen (file);
      if (__builtin_expect (filelen == 0, 0))
	{
	  __set_errno (ENOENT);
	  return -1;
	}

      static const char procfd[] = "/proc/self/fd/%d/%s";
      /* Buffer for the path name we are going to use.  It consists of
	 - the string /proc/self/fd/
	 - the file descriptor number
	 - the file name provided.
	 The final NUL is included in the sizeof.   A bit of overhead
	 due to the format elements compensates for possible negative
	 numbers.  */
      size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
      buf = alloca (buflen);

      __snprintf (buf, buflen, procfd, fd, file);
      file = buf;
    }

  if (vers == _STAT_VER_KERNEL)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
				   CHECK_1 ((struct kernel_stat *) st));
      else
	result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
				   CHECK_1 ((struct kernel_stat *) st));

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	return result;
    }
#ifdef STAT_IS_KERNEL_STAT
  else
    {
      __set_errno (EINVAL);
      return -1;
    }
#else
  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));
  else
    result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));

  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat_conv (vers, &kst, st);
#endif

  __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);

  return -1;
}
Exemple #25
0
/* Get information about the file NAME relative to FD in ST.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
  if (vers != _STAT_VER_KERNEL && vers != _STAT_VER_LINUX)
    {
      __set_errno (EINVAL);
      return -1;
    }

  int res;

#ifdef __NR_newfstatat
# ifndef __ASSUME_ATFCTS
  if (__have_atfcts >= 0)
# endif
    {
      res = INLINE_SYSCALL (newfstatat, 4, fd, file, st, flag);
# ifndef __ASSUME_ATFCTS
      if (res == -1 && errno == ENOSYS)
	__have_atfcts = -1;
      else
# endif
	return res;
    }
#endif

#ifndef __ASSUME_ATFCTS
  if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
    {
      __set_errno (EINVAL);
      return -1;
    }

  char *buf = NULL;

  if (fd != AT_FDCWD && file[0] != '/')
    {
      size_t filelen = strlen (file);
      if (__builtin_expect (filelen == 0, 0))
	{
	  __set_errno (ENOENT);
	  return -1;
	}

      static const char procfd[] = "/proc/self/fd/%d/%s";
      /* Buffer for the path name we are going to use.  It consists of
	 - the string /proc/self/fd/
	 - the file descriptor number
	 - the file name provided.
	 The final NUL is included in the sizeof.   A bit of overhead
	 due to the format elements compensates for possible negative
	 numbers.  */
      size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
      buf = alloca (buflen);

      __snprintf (buf, buflen, procfd, fd, file);
      file = buf;
    }

  INTERNAL_SYSCALL_DECL (err);

  if (flag & AT_SYMLINK_NOFOLLOW)
    res = INTERNAL_SYSCALL (lstat, err, 2, file, CHECK_1 (st));
  else
    res = INTERNAL_SYSCALL (stat, err, 2, file, CHECK_1 (st));

  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
    {
      __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (res, err), fd, buf);
      res = -1;
    }

  return res;
#endif
}
/* Get information about the file NAME relative to FD in ST.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
  int result;
  INTERNAL_SYSCALL_DECL (err);
  struct stat64 st64;

#ifdef __NR_fstatat64
# ifndef __ASSUME_ATFCTS
  if (__have_atfcts >= 0)
# endif
    {
      result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
# ifndef __ASSUME_ATFCTS
      if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
	  && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
	__have_atfcts = -1;
      else
# endif
	if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	  return __xstat32_conv (vers, &st64, st);
	else
	  {
	    __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
	    return -1;
	  }
    }
#endif

#ifndef __ASSUME_ATFCTS
  if (__builtin_expect (flag & ~AT_SYMLINK_NOFOLLOW, 0))
    {
      __set_errno (EINVAL);
      return -1;
    }

  char *buf = NULL;

  if (fd != AT_FDCWD && file[0] != '/')
    {
      size_t filelen = strlen (file);
      static const char procfd[] = "/proc/self/fd/%d/%s";
      /* Buffer for the path name we are going to use.  It consists of
	 - the string /proc/self/fd/
	 - the file descriptor number
	 - the file name provided.
	 The final NUL is included in the sizeof.   A bit of overhead
	 due to the format elements compensates for possible negative
	 numbers.  */
      size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
      buf = alloca (buflen);

      __snprintf (buf, buflen, procfd, fd, file);
      file = buf;
    }

# if __ASSUME_STAT64_SYSCALL == 0
  struct kernel_stat kst;
# endif
  if (vers == _STAT_VER_KERNEL)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
				   CHECK_1 ((struct kernel_stat *) st));
      else
	result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
				   CHECK_1 ((struct kernel_stat *) st));
      goto out;
    }

# if __ASSUME_STAT64_SYSCALL > 0

  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
			       __ptrvalue (&st64));
  else
    result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
			       __ptrvalue (&st64));
  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat32_conv (vers, &st64, st);
# else
#  if defined __NR_stat64
  /* To support 32 bit UIDs, we have to use stat64.  The normal stat
     call only returns 16 bit UIDs.  */
  if (! __have_no_stat64)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
				   __ptrvalue (&st64));
      else
	result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
				   __ptrvalue (&st64));

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	result = __xstat32_conv (vers, &st64, st);

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1)
	  || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
	goto out;

      __have_no_stat64 = 1;
    }
#  endif
  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));
  else
    result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));
  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat_conv (vers, &kst, st);
# endif  /* __ASSUME_STAT64_SYSCALL  */

 out:
  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
    {
      __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
      result = -1;
    }

  return result;
#endif
}
Exemple #27
0
int
__msgctl (int msqid, int cmd, struct msqid_ds *buf)
{
  return INLINE_SYSCALL (msgctl, 3, msqid, cmd | __IPC_64, CHECK_1 (buf));
}
int
__fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
{
  if (__builtin_expect (vers != _STAT_VER_LINUX, 0))
    {
      __set_errno (EINVAL);
      return -1;
    }

  int result;
  INTERNAL_SYSCALL_DECL (err);

#ifdef __NR_fstatat64
# ifndef __ASSUME_ATFCTS
  if (__have_atfcts >= 0)
# endif
    {
      result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
# ifndef __ASSUME_ATFCTS
      if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
	  && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
	__have_atfcts = -1;
      else
# endif
	if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	  return 0;
	else
	  {
	    __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
	    return -1;
	  }
    }
#endif

#ifndef __ASSUME_ATFCTS
  if (flag & ~AT_SYMLINK_NOFOLLOW)
    {
      __set_errno (EINVAL);
      return -1;
    }

  char *buf = NULL;

  if (fd != AT_FDCWD && file[0] != '/')
    {
      size_t filelen = strlen (file);
      static const char procfd[] = "/proc/self/fd/%d/%s";
      /* Buffer for the path name we are going to use.  It consists of
	 - the string /proc/self/fd/
	 - the file descriptor number
	 - the file name provided.
	 The final NUL is included in the sizeof.   A bit of overhead
	 due to the format elements compensates for possible negative
	 numbers.  */
      size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
      buf = alloca (buflen);

      __snprintf (buf, buflen, procfd, fd, file);
      file = buf;
    }

# if __ASSUME_STAT64_SYSCALL > 0
  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
			       CHECK_1 (st));
  else
    result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
			       CHECK_1 (st));
  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    {
#  if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
      if (st->__st_ino != (__ino_t) st->st_ino)
	st->st_ino = st->__st_ino;
#  endif
      return result;
    }
# else
  struct kernel_stat kst;
#  ifdef __NR_stat64
  if (! __have_no_stat64)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
				   CHECK_1 (st));
      else
	result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
				   CHECK_1 (st));

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	{
#   if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0
	  if (st->__st_ino != (__ino_t) st->st_ino)
	    st->st_ino = st->__st_ino;
#   endif
	  return result;
	}
      if (INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
	goto fail;

      __have_no_stat64 = 1;
    }
#  endif

  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));
  else
    result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));

  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat64_conv (vers, &kst, st);

 fail:
# endif
  __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);

  return -1;
#endif
}