/* * call-seq: * Process::UID.switch => fixnum * Process::UID.switch {|| block} => object * * Switch the effective and real user IDs of the current process. If * a <em>block</em> is given, the user IDs will be switched back * after the block is executed. Returns the new effective user ID if * called without a block, and the return value of the block if one * is given. * */ static VALUE p_uid_switch(obj) VALUE obj; { int uid, euid; check_uid_switch(); uid = getuid(); euid = geteuid(); if (uid != euid) { proc_seteuid(obj, INT2FIX(uid)); if (rb_block_given_p()) { under_uid_switch = 1; return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, SAVED_USER_ID); } else { return INT2FIX(euid); } } else if (euid != SAVED_USER_ID) { proc_seteuid(obj, INT2FIX(SAVED_USER_ID)); if (rb_block_given_p()) { under_uid_switch = 1; return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, euid); } else { return INT2FIX(uid); } } else { errno = EPERM; rb_sys_fail(0); } #else static VALUE p_uid_sw_ensure(obj) VALUE obj; { under_uid_switch = 0; return p_uid_exchange(obj); }