Implement prlimit64 decoding, rewrite [gs]etrlimit decoding

* configure.ac: Remove AC_RLIM_T_IS_LONG_LONG call.
Define SIZEOF_RLIM_T.
* m4/long_long.m4 (AC_RLIM_T_IS_LONG_LONG): Remove.
* linux/dummy.h (sys_prlimit64): Remove.
* linux/syscall.h (sys_prlimit64): New prototype.
* resource.c (resources): Reindent, add RLIMIT_RTTIME.
(sprintrlim, print_rlimit32, sys_getrlimit, sys_setrlimit): Remove.
[HAVE_LONG_LONG_RLIM_T]: Remove dead code.
[_LFS64_LARGEFILE || HAVE_LONG_LONG_RLIM_T]: Likewise.
(sprint_rlim64, print_rlimit64, decode_rlimit64, sprint_rlim32,
print_rlimit32, decode_rlimit, sys_getrlimit, sys_setrlimit,
sys_prlimit64): New functions.
This commit is contained in:
Дмитрий Левин 2012-03-16 23:05:21 +04:00
parent 9c3861d317
commit b468f2320a
5 changed files with 119 additions and 149 deletions

View File

@ -150,7 +150,6 @@ AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id],,,
AC_CHECK_TYPES([long long])
AC_LITTLE_ENDIAN_LONG_LONG
AC_OFF_T_IS_LONG_LONG
AC_RLIM_T_IS_LONG_LONG
AC_CHECK_TYPES([struct opthdr],,, [#include <sys/socket.h>])
AC_CHECK_TYPES([struct t_opthdr],,, [#include <sys/tiuser.h>])
@ -252,6 +251,7 @@ AC_CACHE_CHECK([for BLKGETSIZE64], [ac_cv_have_blkgetsize64],
fi)
AC_CHECK_SIZEOF([long])
AC_CHECK_SIZEOF([rlim_t],,[#include <sys/resource.h>])
AC_PATH_PROG([PERL], [perl])

View File

@ -40,7 +40,6 @@
#define sys_name_to_handle_at printargs
#define sys_open_by_handle_at printargs
#define sys_perf_event_open printargs
#define sys_prlimit64 printargs
#define sys_request_key printargs
#define sys_sync_file_range printargs
#define sys_sysfs printargs

View File

@ -172,10 +172,11 @@ int sys_ppoll();
int sys_prctl();
int sys_pread();
int sys_preadv();
int sys_pselect6();
int sys_ptrace();
int sys_prlimit64();
int sys_process_vm_readv();
int sys_process_vm_writev();
int sys_pselect6();
int sys_ptrace();
int sys_putpmsg();
int sys_pwrite();
int sys_pwritev();

View File

@ -13,23 +13,6 @@ then
fi
])
dnl ### A macro to determine if rlim_t is a long long
AC_DEFUN([AC_RLIM_T_IS_LONG_LONG],
[AC_MSG_CHECKING(for long long rlim_t)
AC_CACHE_VAL(ac_cv_have_long_long_rlim_t,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
char a[(sizeof (rlim_t) == sizeof (long long) &&
sizeof (rlim_t) > sizeof (long)) - 1];
]])],[ac_cv_have_long_long_rlim_t=yes],[ac_cv_have_long_long_rlim_t=no])])
AC_MSG_RESULT($ac_cv_have_long_long_rlim_t)
if test "$ac_cv_have_long_long_rlim_t" = yes
then
AC_DEFINE([HAVE_LONG_LONG_RLIM_T], 1, [Define if rlim_t is a long long.])
fi
])
dnl ### A macro to determine endianness of long long
AC_DEFUN([AC_LITTLE_ENDIAN_LONG_LONG],
[AC_MSG_CHECKING(for little endian long long)

View File

@ -33,37 +33,24 @@
#include <sys/times.h>
#include <linux/kernel.h>
#if HAVE_LONG_LONG_RLIM_T
/*
* Hacks for systems that have a long long rlim_t
*/
# define rlimit64 rlimit /* Ugly hack */
# define rlim64_t rlim_t /* Ugly hack */
# ifndef RLIM64_INFINITY
# define RLIM64_INFINITY RLIM_INFINITY /* You guessed it */
# endif
# define sys_getrlimit64 sys_getrlimit
# define sys_setrlimit64 sys_setrlimit
#endif
static const struct xlat resources[] = {
#ifdef RLIMIT_AS
{ RLIMIT_AS, "RLIMIT_AS" },
{ RLIMIT_AS, "RLIMIT_AS" },
#endif
#ifdef RLIMIT_CORE
{ RLIMIT_CORE, "RLIMIT_CORE" },
{ RLIMIT_CORE, "RLIMIT_CORE" },
#endif
#ifdef RLIMIT_CPU
{ RLIMIT_CPU, "RLIMIT_CPU" },
{ RLIMIT_CPU, "RLIMIT_CPU" },
#endif
#ifdef RLIMIT_DATA
{ RLIMIT_DATA, "RLIMIT_DATA" },
{ RLIMIT_DATA, "RLIMIT_DATA" },
#endif
#ifdef RLIMIT_FSIZE
{ RLIMIT_FSIZE, "RLIMIT_FSIZE" },
{ RLIMIT_FSIZE, "RLIMIT_FSIZE" },
#endif
#ifdef RLIMIT_LOCKS
{ RLIMIT_LOCKS, "RLIMIT_LOCKS" },
{ RLIMIT_LOCKS, "RLIMIT_LOCKS" },
#endif
#ifdef RLIMIT_MEMLOCK
{ RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK" },
@ -72,92 +59,150 @@ static const struct xlat resources[] = {
{ RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE" },
#endif
#ifdef RLIMIT_NICE
{ RLIMIT_NICE, "RLIMIT_NICE" },
{ RLIMIT_NICE, "RLIMIT_NICE" },
#endif
#ifdef RLIMIT_NOFILE
{ RLIMIT_NOFILE, "RLIMIT_NOFILE" },
{ RLIMIT_NOFILE, "RLIMIT_NOFILE" },
#endif
#ifdef RLIMIT_NPROC
{ RLIMIT_NPROC, "RLIMIT_NPROC" },
{ RLIMIT_NPROC, "RLIMIT_NPROC" },
#endif
#ifdef RLIMIT_RSS
{ RLIMIT_RSS, "RLIMIT_RSS" },
{ RLIMIT_RSS, "RLIMIT_RSS" },
#endif
#ifdef RLIMIT_RTPRIO
{ RLIMIT_RTPRIO, "RLIMIT_RTPRIO" },
{ RLIMIT_RTPRIO, "RLIMIT_RTPRIO" },
#endif
#ifdef RLIMIT_RTTIME
{ RLIMIT_RTTIME, "RLIMIT_RTTIME" },
#endif
#ifdef RLIMIT_SIGPENDING
{ RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING" },
#endif
#ifdef RLIMIT_STACK
{ RLIMIT_STACK, "RLIMIT_STACK" },
{ RLIMIT_STACK, "RLIMIT_STACK" },
#endif
#ifdef RLIMIT_VMEM
{ RLIMIT_VMEM, "RLIMIT_VMEM" },
{ RLIMIT_VMEM, "RLIMIT_VMEM" },
#endif
{ 0, NULL },
{ 0, NULL }
};
#if !HAVE_LONG_LONG_RLIM_T
#if !(SIZEOF_RLIM_T == 4 || SIZEOF_RLIM_T == 8)
# error "Unsupported SIZEOF_RLIM_T value"
#endif
static const char *
sprintrlim(long lim)
sprint_rlim64(uint64_t lim)
{
static char buf[sizeof(long)*3 + sizeof("%ld*1024")];
static char buf[sizeof(uint64_t)*3 + sizeof("*1024")];
if (lim == RLIM_INFINITY)
return "RLIM_INFINITY";
if (lim == UINT64_MAX)
return "RLIM64_INFINITY";
if (lim > 1024 && lim%1024 == 0)
sprintf(buf, "%ld*1024", lim/1024);
if (lim > 1024 && lim % 1024 == 0)
sprintf(buf, "%" PRIu64 "*1024", lim / 1024);
else
sprintf(buf, "%ld", lim);
sprintf(buf, "%" PRIu64, lim);
return buf;
}
# if defined(POWERPC64) || defined(X86_64)
static void
print_rlimit32(struct tcb *tcp)
print_rlimit64(struct tcb *tcp, unsigned long addr)
{
struct rlimit32 {
unsigned int rlim_cur;
unsigned int rlim_max;
struct rlimit_64 {
uint64_t rlim_cur;
uint64_t rlim_max;
} rlim;
if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
tprints("{...}");
if (umove(tcp, addr, &rlim) < 0)
tprintf("%#lx", addr);
else {
tprintf("{rlim_cur=%s,",
sprintrlim(rlim.rlim_cur == -1 ? RLIM_INFINITY
: rlim.rlim_cur));
tprintf(" rlim_max=%s}",
sprintrlim(rlim.rlim_max == -1 ? RLIM_INFINITY
: rlim.rlim_max));
tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur));
tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max));
}
}
static void
decode_rlimit64(struct tcb *tcp, unsigned long addr)
{
if (!addr)
tprints("NULL");
else if (!verbose(tcp) ||
(exiting(tcp) && syserror(tcp)))
tprintf("%#lx", addr);
else
print_rlimit64(tcp, addr);
}
#if SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1
static const char *
sprint_rlim32(uint32_t lim)
{
static char buf[sizeof(uint32_t)*3 + sizeof("*1024")];
if (lim == UINT32_MAX)
return "RLIM_INFINITY";
if (lim > 1024 && lim % 1024 == 0)
sprintf(buf, "%" PRIu32 "*1024", lim / 1024);
else
sprintf(buf, "%" PRIu32, lim);
return buf;
}
static void
print_rlimit32(struct tcb *tcp, unsigned long addr)
{
struct rlimit_32 {
uint32_t rlim_cur;
uint32_t rlim_max;
} rlim;
if (umove(tcp, addr, &rlim) < 0)
tprintf("%#lx", addr);
else {
tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur));
tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max));
}
}
static void
decode_rlimit(struct tcb *tcp, unsigned long addr)
{
if (!addr)
tprints("NULL");
else if (!verbose(tcp) ||
(exiting(tcp) && syserror(tcp)))
tprintf("%#lx", addr);
else {
# if SIZEOF_RLIM_T == 4
print_rlimit32(tcp, addr);
# else
if (personality_wordsize[current_personality] == 4)
print_rlimit32(tcp, addr);
else
print_rlimit64(tcp, addr);
# endif
}
}
#else /* SIZEOF_RLIM_T == 8 && SUPPORTED_PERSONALITIES == 1 */
# define decode_rlimit decode_rlimit64
#endif /* SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1 */
int
sys_getrlimit(struct tcb *tcp)
{
struct rlimit rlim;
if (entering(tcp)) {
printxval(resources, tcp->u_arg[0], "RLIMIT_???");
tprints(", ");
}
else {
if (syserror(tcp) || !verbose(tcp))
tprintf("%#lx", tcp->u_arg[1]);
# if defined(POWERPC64) || defined(X86_64)
else if (current_personality == 1)
print_rlimit32(tcp);
# endif
else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
tprints("{...}");
else {
tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
}
decode_rlimit(tcp, tcp->u_arg[1]);
}
return 0;
}
@ -165,86 +210,28 @@ sys_getrlimit(struct tcb *tcp)
int
sys_setrlimit(struct tcb *tcp)
{
struct rlimit rlim;
if (entering(tcp)) {
printxval(resources, tcp->u_arg[0], "RLIMIT_???");
tprints(", ");
if (!verbose(tcp))
tprintf("%#lx", tcp->u_arg[1]);
# if defined(POWERPC64) || defined(X86_64)
else if (current_personality == 1)
print_rlimit32(tcp);
# endif
else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
tprints("{...}");
else {
tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
}
}
return 0;
}
#endif /* !HAVE_LONG_LONG_RLIM_T */
#if _LFS64_LARGEFILE || HAVE_LONG_LONG_RLIM_T
static const char *
sprintrlim64(rlim64_t lim)
{
static char buf[sizeof(long long)*3 + sizeof("%lld*1024")];
if (lim == RLIM64_INFINITY)
return "RLIM64_INFINITY";
if (lim > 1024 && lim%1024 == 0)
sprintf(buf, "%lld*1024", (long long) lim/1024);
else
sprintf(buf, "%lld", (long long) lim);
return buf;
}
int
sys_getrlimit64(struct tcb *tcp)
{
struct rlimit64 rlim;
if (entering(tcp)) {
printxval(resources, tcp->u_arg[0], "RLIMIT_???");
tprints(", ");
}
else {
if (syserror(tcp) || !verbose(tcp))
tprintf("%#lx", tcp->u_arg[1]);
else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
tprints("{...}");
else {
tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
}
decode_rlimit(tcp, tcp->u_arg[1]);
}
return 0;
}
int
sys_setrlimit64(struct tcb *tcp)
sys_prlimit64(struct tcb *tcp)
{
struct rlimit64 rlim;
if (entering(tcp)) {
printxval(resources, tcp->u_arg[0], "RLIMIT_???");
tprintf("%ld, ", tcp->u_arg[0]);
printxval(resources, tcp->u_arg[1], "RLIMIT_???");
tprints(", ");
if (!verbose(tcp))
tprintf("%#lx", tcp->u_arg[1]);
else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
tprints("{...}");
else {
tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
}
decode_rlimit64(tcp, tcp->u_arg[2]);
tprints(", ");
} else {
decode_rlimit64(tcp, tcp->u_arg[3]);
}
return 0;
}
#endif /* _LFS64_LARGEFILES || HAVE_LONG_LONG_RLIM_T */
static const struct xlat usagewho[] = {
{ RUSAGE_SELF, "RUSAGE_SELF" },