Merge commit '9c1bc6bbc82e3e4f005e9fcacfca94b2dd82ca31' into HEAD

This commit is contained in:
Bill Yi 2015-02-19 14:33:24 -08:00
commit 0cc8da0947
17 changed files with 155 additions and 103 deletions

View file

@ -154,9 +154,10 @@ static void check_fs(char *blk_device, char *fs_type, char *target)
} else if (!strcmp(fs_type, "f2fs")) {
char *f2fs_fsck_argv[] = {
F2FS_FSCK_BIN,
"-f",
blk_device
};
INFO("Running %s on %s\n", F2FS_FSCK_BIN, blk_device);
INFO("Running %s -f %s\n", F2FS_FSCK_BIN, blk_device);
ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv,
&status, true, LOG_KLOG | LOG_FILE,
@ -487,7 +488,9 @@ int fs_mgr_mount_all(struct fstab *fstab)
/* Deal with encryptability. */
if (!mret) {
/* If this is encryptable, need to trigger encryption */
if (fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
if ( (fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)
|| (device_is_force_encrypted()
&& fs_mgr_is_encryptable(&fstab->recs[attempted_idx]))) {
if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,

View file

@ -428,11 +428,6 @@ int fs_mgr_is_encryptable(struct fstab_rec *fstab)
return fstab->fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT);
}
int fs_mgr_is_force_encrypted(struct fstab_rec *fstab)
{
return fstab->fs_mgr_flags & MF_FORCECRYPT;
}
int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab)
{
return fstab->fs_mgr_flags & MF_NOEMULATEDSD;

View file

@ -86,11 +86,11 @@ static RSAPublicKey *load_key(char *path)
static int verify_table(char *signature, char *table, int table_length)
{
RSAPublicKey *key;
uint8_t hash_buf[SHA_DIGEST_SIZE];
uint8_t hash_buf[SHA256_DIGEST_SIZE];
int retval = -1;
// Hash the table
SHA_hash((uint8_t*)table, table_length, hash_buf);
SHA256_hash((uint8_t*)table, table_length, hash_buf);
// Now get the public key from the keyfile
key = load_key(VERITY_TABLE_RSA_KEY);
@ -104,7 +104,7 @@ static int verify_table(char *signature, char *table, int table_length)
(uint8_t*) signature,
RSANUMBYTES,
(uint8_t*) hash_buf,
SHA_DIGEST_SIZE)) {
SHA256_DIGEST_SIZE)) {
ERROR("Couldn't verify table.");
goto out;
}

View file

@ -83,7 +83,6 @@ int fs_mgr_is_voldmanaged(struct fstab_rec *fstab);
int fs_mgr_is_nonremovable(struct fstab_rec *fstab);
int fs_mgr_is_verified(struct fstab_rec *fstab);
int fs_mgr_is_encryptable(struct fstab_rec *fstab);
int fs_mgr_is_force_encrypted(struct fstab_rec *fstab);
int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab);
int fs_mgr_swapon_all(struct fstab *fstab);
#ifdef __cplusplus

View file

@ -265,10 +265,10 @@ bool BatteryMonitor::update(void) {
"battery none");
}
KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
props.chargerAcOnline ? "a" : "",
props.chargerUsbOnline ? "u" : "",
props.chargerWirelessOnline ? "w" : "");
KLOG_WARNING(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
props.chargerAcOnline ? "a" : "",
props.chargerUsbOnline ? "u" : "",
props.chargerWirelessOnline ? "w" : "");
}
healthd_mode_ops->battery_update(&props);
@ -511,7 +511,7 @@ void BatteryMonitor::init(struct healthd_config *hc) {
if (!mChargerNames.size())
KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
if (!mBatteryDevicePresent) {
KLOG_INFO(LOG_TAG, "No battery devices found\n");
KLOG_WARNING(LOG_TAG, "No battery devices found\n");
hc->periodic_chores_interval_fast = -1;
hc->periodic_chores_interval_slow = -1;
} else {

View file

@ -53,6 +53,7 @@ static struct healthd_config healthd_config = {
.batteryCurrentAvgPath = String8(String8::kEmptyString),
.batteryChargeCounterPath = String8(String8::kEmptyString),
.energyCounter = NULL,
.screen_on = NULL,
};
static int eventct;
@ -313,8 +314,8 @@ static int healthd_init() {
return -1;
}
healthd_mode_ops->init(&healthd_config);
healthd_board_init(&healthd_config);
healthd_mode_ops->init(&healthd_config);
wakealarm_init();
uevent_init();
gBatteryMonitor = new BatteryMonitor();

View file

@ -67,6 +67,7 @@ struct healthd_config {
android::String8 batteryChargeCounterPath;
int (*energyCounter)(int64_t *);
bool (*screen_on)(android::BatteryProperties *props);
};
// Global helper functions

View file

@ -68,14 +68,13 @@ char *locale;
#define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
#define BATTERY_FULL_THRESH 95
#define SCREEN_ON_BATTERY_THRESH 0
#define LAST_KMSG_PATH "/proc/last_kmsg"
#define LAST_KMSG_PSTORE_PATH "/sys/fs/pstore/console-ramoops"
#define LAST_KMSG_MAX_SZ (32 * 1024)
#define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0)
#define LOGI(x...) do { KLOG_INFO("charger", x); } while (0)
#define LOGW(x...) do { KLOG_WARNING("charger", x); } while (0)
#define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0)
struct key_state {
@ -109,7 +108,6 @@ struct animation {
struct charger {
bool have_battery_state;
bool charger_connected;
int capacity;
int64_t next_screen_transition;
int64_t next_key_check;
int64_t next_pwr_check;
@ -170,7 +168,8 @@ static struct animation battery_animation = {
};
static struct charger charger_state;
static struct healthd_config *healthd_config;
static struct android::BatteryProperties *batt_prop;
static int char_width;
static int char_height;
static bool minui_inited;
@ -198,15 +197,15 @@ static void dump_last_kmsg(void)
unsigned sz = 0;
int len;
LOGI("\n");
LOGI("*************** LAST KMSG ***************\n");
LOGI("\n");
LOGW("\n");
LOGW("*************** LAST KMSG ***************\n");
LOGW("\n");
buf = (char *)load_file(LAST_KMSG_PSTORE_PATH, &sz);
if (!buf || !sz) {
buf = (char *)load_file(LAST_KMSG_PATH, &sz);
if (!buf || !sz) {
LOGI("last_kmsg not found. Cold reset?\n");
LOGW("last_kmsg not found. Cold reset?\n");
goto out;
}
}
@ -225,7 +224,7 @@ static void dump_last_kmsg(void)
yoink = ptr[cnt];
ptr[cnt] = '\0';
klog_write(6, "<6>%s", ptr);
klog_write(6, "<4>%s", ptr);
ptr[cnt] = yoink;
len -= cnt;
@ -235,14 +234,9 @@ static void dump_last_kmsg(void)
free(buf);
out:
LOGI("\n");
LOGI("************* END LAST KMSG *************\n");
LOGI("\n");
}
static int get_battery_capacity()
{
return charger_state.capacity;
LOGW("\n");
LOGW("************* END LAST KMSG *************\n");
LOGW("\n");
}
#ifdef CHARGER_ENABLE_SUSPEND
@ -356,15 +350,16 @@ static void update_screen_state(struct charger *charger, int64_t now)
return;
if (!minui_inited) {
int batt_cap = get_battery_capacity();
if (batt_cap < SCREEN_ON_BATTERY_THRESH) {
LOGV("[%" PRId64 "] level %d, leave screen off\n", now, batt_cap);
batt_anim->run = false;
charger->next_screen_transition = -1;
if (charger->charger_connected)
request_suspend(true);
return;
if (healthd_config && healthd_config->screen_on) {
if (!healthd_config->screen_on(batt_prop)) {
LOGV("[%" PRId64 "] leave screen off\n", now);
batt_anim->run = false;
charger->next_screen_transition = -1;
if (charger->charger_connected)
request_suspend(true);
return;
}
}
gr_init();
@ -391,16 +386,14 @@ static void update_screen_state(struct charger *charger, int64_t now)
/* animation starting, set up the animation */
if (batt_anim->cur_frame == 0) {
int batt_cap;
LOGV("[%" PRId64 "] animation starting\n", now);
batt_cap = get_battery_capacity();
if (batt_cap >= 0 && batt_anim->num_frames != 0) {
if (batt_prop && batt_prop->batteryLevel >= 0 && batt_anim->num_frames != 0) {
int i;
/* find first frame given current capacity */
for (i = 1; i < batt_anim->num_frames; i++) {
if (batt_cap < batt_anim->frames[i].min_capacity)
if (batt_prop->batteryLevel < batt_anim->frames[i].min_capacity)
break;
}
batt_anim->cur_frame = i - 1;
@ -408,8 +401,8 @@ static void update_screen_state(struct charger *charger, int64_t now)
/* show the first frame for twice as long */
disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time * 2;
}
batt_anim->capacity = batt_cap;
if (batt_prop)
batt_anim->capacity = batt_prop->batteryLevel;
}
/* unblank the screen on first cycle */
@ -524,10 +517,10 @@ static void process_key(struct charger *charger, int code, int64_t now)
all devices. Check the property and continue booting or reboot
accordingly. */
if (property_get_bool("ro.enable_boot_charger_mode", false)) {
LOGI("[%" PRId64 "] booting from charger mode\n", now);
LOGW("[%" PRId64 "] booting from charger mode\n", now);
property_set("sys.boot_from_charger_mode", "1");
} else {
LOGI("[%" PRId64 "] rebooting\n", now);
LOGW("[%" PRId64 "] rebooting\n", now);
android_reboot(ANDROID_RB_RESTART, 0, 0);
}
} else {
@ -565,10 +558,10 @@ static void handle_power_supply_state(struct charger *charger, int64_t now)
request_suspend(false);
if (charger->next_pwr_check == -1) {
charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME;
LOGI("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n",
LOGW("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n",
now, (int64_t)UNPLUGGED_SHUTDOWN_TIME, charger->next_pwr_check);
} else if (now >= charger->next_pwr_check) {
LOGI("[%" PRId64 "] shutting down\n", now);
LOGW("[%" PRId64 "] shutting down\n", now);
android_reboot(ANDROID_RB_POWEROFF, 0, 0);
} else {
/* otherwise we already have a shutdown timer scheduled */
@ -576,7 +569,7 @@ static void handle_power_supply_state(struct charger *charger, int64_t now)
} else {
/* online supply present, reset shutdown timer if set */
if (charger->next_pwr_check != -1) {
LOGI("[%" PRId64 "] device plugged in: shutdown cancelled\n", now);
LOGW("[%" PRId64 "] device plugged in: shutdown cancelled\n", now);
kick_animation(charger->batt_anim);
}
charger->next_pwr_check = -1;
@ -605,7 +598,6 @@ void healthd_mode_charger_battery_update(
charger->charger_connected =
props->chargerAcOnline || props->chargerUsbOnline ||
props->chargerWirelessOnline;
charger->capacity = props->batteryLevel;
if (!charger->have_battery_state) {
charger->have_battery_state = true;
@ -613,6 +605,7 @@ void healthd_mode_charger_battery_update(
reset_animation(charger->batt_anim);
kick_animation(charger->batt_anim);
}
batt_prop = props;
}
int healthd_mode_charger_preparetowait(void)
@ -663,7 +656,7 @@ static void charger_event_handler(uint32_t /*epevents*/)
ev_dispatch();
}
void healthd_mode_charger_init(struct healthd_config* /*config*/)
void healthd_mode_charger_init(struct healthd_config* config)
{
int ret;
struct charger *charger = &charger_state;
@ -672,7 +665,7 @@ void healthd_mode_charger_init(struct healthd_config* /*config*/)
dump_last_kmsg();
LOGI("--------------- STARTING CHARGER MODE ---------------\n");
LOGW("--------------- STARTING CHARGER MODE ---------------\n");
ret = ev_init(input_callback, charger);
if (!ret) {
@ -711,4 +704,5 @@ void healthd_mode_charger_init(struct healthd_config* /*config*/)
charger->next_screen_transition = -1;
charger->next_key_check = -1;
charger->next_pwr_check = -1;
healthd_config = config;
}

View file

@ -252,7 +252,6 @@ static const struct fs_path_config android_files[] = {
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/librank" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procrank" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/tcpdump" },
{ 04770, AID_ROOT, AID_RADIO, 0, "system/bin/pppd-ril" },
/* the following files have enhanced capabilities and ARE included in user builds. */

View file

@ -57,10 +57,14 @@ typedef enum {
* and must be routed to speaker
*/
AUDIO_STREAM_DTMF = 8,
AUDIO_STREAM_TTS = 9,
AUDIO_STREAM_CNT,
AUDIO_STREAM_MAX = AUDIO_STREAM_CNT - 1,
AUDIO_STREAM_TTS = 9, /* Transmitted Through Speaker.
* Plays over speaker only, silent on other devices.
*/
AUDIO_STREAM_ACCESSIBILITY = 10, /* For accessibility talk back prompts */
AUDIO_STREAM_REROUTING = 11, /* For dynamic policy output mixes */
AUDIO_STREAM_PATCH = 12, /* For internal audio flinger tracks. Fixed volume */
AUDIO_STREAM_PUBLIC_CNT = AUDIO_STREAM_TTS + 1,
AUDIO_STREAM_CNT = AUDIO_STREAM_PATCH + 1,
} audio_stream_type_t;
/* Do not change these values without updating their counterparts
@ -96,6 +100,7 @@ typedef enum {
AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12,
AUDIO_USAGE_ASSISTANCE_SONIFICATION = 13,
AUDIO_USAGE_GAME = 14,
AUDIO_USAGE_VIRTUAL_SOURCE = 15,
AUDIO_USAGE_CNT,
AUDIO_USAGE_MAX = AUDIO_USAGE_CNT - 1,
@ -135,6 +140,7 @@ typedef enum {
/* play the mix captured by this audio source. */
AUDIO_SOURCE_CNT,
AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1,
AUDIO_SOURCE_FM_TUNER = 1998,
AUDIO_SOURCE_HOTWORD = 1999, /* A low-priority, preemptible audio source for
for background software hotword detection.
Same tuning as AUDIO_SOURCE_VOICE_RECOGNITION.

View file

@ -30,9 +30,11 @@ native_handle_t* native_handle_create(int numFds, int numInts)
native_handle_t* h = malloc(
sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));
h->version = sizeof(native_handle_t);
h->numFds = numFds;
h->numInts = numInts;
if (h) {
h->version = sizeof(native_handle_t);
h->numFds = numFds;
h->numInts = numInts;
}
return h;
}

View file

@ -45,8 +45,6 @@ static inline SchedPolicy _policy(SchedPolicy p)
#define POLICY_DEBUG 0
#define CAN_SET_SP_SYSTEM 0 // non-zero means to implement set_sched_policy(tid, SP_SYSTEM)
// This prctl is only available in Android kernels.
#define PR_SET_TIMERSLACK_PID 41
@ -60,9 +58,6 @@ static int __sys_supports_schedgroups = -1;
// File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error.
static int bg_cgroup_fd = -1;
static int fg_cgroup_fd = -1;
#if CAN_SET_SP_SYSTEM
static int system_cgroup_fd = -1;
#endif
/* Add tid to the scheduling group defined by the policy */
static int add_tid_to_cgroup(int tid, SchedPolicy policy)
@ -78,11 +73,6 @@ static int add_tid_to_cgroup(int tid, SchedPolicy policy)
case SP_AUDIO_SYS:
fd = fg_cgroup_fd;
break;
#if CAN_SET_SP_SYSTEM
case SP_SYSTEM:
fd = system_cgroup_fd;
break;
#endif
default:
fd = -1;
break;
@ -123,21 +113,13 @@ static void __initialize(void) {
if (!access("/dev/cpuctl/tasks", F_OK)) {
__sys_supports_schedgroups = 1;
#if CAN_SET_SP_SYSTEM
filename = "/dev/cpuctl/tasks";
system_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);
if (system_cgroup_fd < 0) {
SLOGV("open of %s failed: %s\n", filename, strerror(errno));
}
#endif
filename = "/dev/cpuctl/apps/tasks";
fg_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);
if (fg_cgroup_fd < 0) {
SLOGE("open of %s failed: %s\n", filename, strerror(errno));
}
filename = "/dev/cpuctl/apps/bg_non_interactive/tasks";
filename = "/dev/cpuctl/bg_non_interactive/tasks";
bg_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);
if (bg_cgroup_fd < 0) {
SLOGE("open of %s failed: %s\n", filename, strerror(errno));
@ -231,11 +213,9 @@ int get_sched_policy(int tid, SchedPolicy *policy)
if (getSchedulerGroup(tid, grpBuf, sizeof(grpBuf)) < 0)
return -1;
if (grpBuf[0] == '\0') {
*policy = SP_SYSTEM;
} else if (!strcmp(grpBuf, "apps/bg_non_interactive")) {
*policy = SP_BACKGROUND;
} else if (!strcmp(grpBuf, "apps")) {
*policy = SP_FOREGROUND;
} else if (!strcmp(grpBuf, "bg_non_interactive")) {
*policy = SP_BACKGROUND;
} else {
errno = ERANGE;
return -1;

View file

@ -36,6 +36,7 @@ TEST_F(NativeBridgeTest, CompleteFlow) {
// Unload
UnloadNativeBridge();
ASSERT_FALSE(NativeBridgeAvailable());
ASSERT_FALSE(NativeBridgeError());

View file

@ -118,25 +118,18 @@ on init
mount cgroup none /dev/cpuctl cpu
chown system system /dev/cpuctl
chown system system /dev/cpuctl/tasks
chmod 0660 /dev/cpuctl/tasks
chmod 0666 /dev/cpuctl/tasks
write /dev/cpuctl/cpu.shares 1024
write /dev/cpuctl/cpu.rt_runtime_us 950000
write /dev/cpuctl/cpu.rt_runtime_us 800000
write /dev/cpuctl/cpu.rt_period_us 1000000
mkdir /dev/cpuctl/apps
chown system system /dev/cpuctl/apps/tasks
chmod 0666 /dev/cpuctl/apps/tasks
write /dev/cpuctl/apps/cpu.shares 1024
write /dev/cpuctl/apps/cpu.rt_runtime_us 800000
write /dev/cpuctl/apps/cpu.rt_period_us 1000000
mkdir /dev/cpuctl/apps/bg_non_interactive
chown system system /dev/cpuctl/apps/bg_non_interactive/tasks
chmod 0666 /dev/cpuctl/apps/bg_non_interactive/tasks
mkdir /dev/cpuctl/bg_non_interactive
chown system system /dev/cpuctl/bg_non_interactive/tasks
chmod 0666 /dev/cpuctl/bg_non_interactive/tasks
# 5.0 %
write /dev/cpuctl/apps/bg_non_interactive/cpu.shares 52
write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us 700000
write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us 1000000
write /dev/cpuctl/bg_non_interactive/cpu.shares 52
write /dev/cpuctl/bg_non_interactive/cpu.rt_runtime_us 700000
write /dev/cpuctl/bg_non_interactive/cpu.rt_period_us 1000000
# qtaguid will limit access to specific data based on group memberships.
# net_bw_acct grants impersonation of socket owners.
@ -589,7 +582,7 @@ service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted
# encryption) or trigger_restart_min_framework (other encryption)
# One shot invocation to encrypt unencrypted volumes
service encrypt /system/bin/vdc --wait cryptfs maybeenabledefaultcrypto
service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default
disabled
oneshot
# vold will set vold.decrypt to trigger_restart_framework (default

View file

@ -89,6 +89,7 @@ subsystem adf
/dev/ppp 0660 radio vpn
# sysfs properties
/sys/devices/platform/trusty.* trusty_version 0440 root log
/sys/devices/virtual/input/input* enable 0660 root input
/sys/devices/virtual/input/input* poll_delay 0660 root input
/sys/devices/virtual/usb_composite/* enable 0664 root system

View file

@ -56,6 +56,7 @@ OUR_TOOLS := \
nandread \
newfs_msdos \
ps \
prlimit \
renice \
restorecon \
route \

76
toolbox/prlimit.c Normal file
View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2014, The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
static void
usage(const char *s)
{
fprintf(stderr, "usage: %s pid resource cur max\n", s);
exit(EXIT_FAILURE);
}
int prlimit_main(int argc, char *argv[])
{
pid_t pid;
struct rlimit64 rl;
int resource;
int rc;
if (argc != 5)
usage(*argv);
if (sscanf(argv[1], "%d", &pid) != 1)
usage(*argv);
if (sscanf(argv[2], "%d", &resource) != 1)
usage(*argv);
if (sscanf(argv[3], "%llu", &rl.rlim_cur) != 1)
usage(*argv);
if (sscanf(argv[4], "%llu", &rl.rlim_max) != 1)
usage(*argv);
printf("setting resource %d of pid %d to [%llu,%llu]\n", resource, pid,
rl.rlim_cur, rl.rlim_max);
rc = prlimit64(pid, resource, &rl, NULL);
if (rc < 0) {
perror("prlimit");
exit(EXIT_FAILURE);
}
return 0;
}