1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
from cffi import FFI
from ctypes import util, CDLL
import sys
ffi = FFI()
# Note: we don't directly expose 'struct timeval' or 'struct rlimit'
rlimit_consts = '''
RLIMIT_CPU
RLIMIT_FSIZE
RLIMIT_DATA
RLIMIT_STACK
RLIMIT_CORE
RLIMIT_NOFILE
RLIMIT_OFILE
RLIMIT_VMEM
RLIMIT_AS
RLIMIT_RSS
RLIMIT_NPROC
RLIMIT_MEMLOCK
RLIMIT_SBSIZE
RLIM_INFINITY
RUSAGE_SELF
RUSAGE_CHILDREN
RUSAGE_BOTH
'''.split()
rlimit_consts = ['#ifdef %s\n\t{"%s", %s},\n#endif\n' % (s, s, s)
for s in rlimit_consts]
src = """
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
const struct my_rlimit_def {
const char *name;
long long value;
} my_rlimit_consts[] = {
$RLIMIT_CONSTS
{ NULL, 0 }
};
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
static double my_utime(struct rusage *input)
{
return doubletime(input->ru_utime);
}
static double my_stime(struct rusage *input)
{
return doubletime(input->ru_stime);
}
static int my_getrlimit(int resource, long long result[2])
{
struct rlimit rl;
if (getrlimit(resource, &rl) == -1)
return -1;
result[0] = rl.rlim_cur;
result[1] = rl.rlim_max;
return 0;
}
static int my_setrlimit(int resource, long long cur, long long max)
{
struct rlimit rl;
rl.rlim_cur = cur & RLIM_INFINITY;
rl.rlim_max = max & RLIM_INFINITY;
return setrlimit(resource, &rl);
}
""".replace('$RLIMIT_CONSTS', ''.join(rlimit_consts))
ffi.cdef("""
#define RLIM_NLIMITS ...
extern const struct my_rlimit_def {
const char *name;
long long value;
} my_rlimit_consts[];
struct rusage {
long ru_maxrss;
long ru_ixrss;
long ru_idrss;
long ru_isrss;
long ru_minflt;
long ru_majflt;
long ru_nswap;
long ru_inblock;
long ru_oublock;
long ru_msgsnd;
long ru_msgrcv;
long ru_nsignals;
long ru_nvcsw;
long ru_nivcsw;
...;
};
static double my_utime(struct rusage *);
static double my_stime(struct rusage *);
void getrusage(int who, struct rusage *result);
int my_getrlimit(int resource, long long result[2]);
int my_setrlimit(int resource, long long cur, long long max);
int wait3(int *status, int options, struct rusage *rusage);
int wait4(int pid, int *status, int options, struct rusage *rusage);
""")
libname = util.find_library('c')
glibc = CDLL(util.find_library('c'))
if hasattr(glibc, 'prlimit'):
src += """
static int _prlimit(int pid, int resource, int set, long long cur, long long max, long long result[2])
{
struct rlimit new_rl, old_rl;
new_rl.rlim_cur = cur & RLIM_INFINITY;
new_rl.rlim_max = max & RLIM_INFINITY;
if(prlimit(pid, resource, (set ? &new_rl : NULL), &old_rl) == -1)
return -1;
result[0] = old_rl.rlim_cur;
result[1] = old_rl.rlim_max;
return 0;
}
"""
ffi.cdef("""
int _prlimit(int pid, int resource, int set, long long cur, long long max, long long result[2]);
""")
ffi.set_source("_resource_cffi", src)
if __name__ == "__main__":
ffi.compile()
|