static int set_rctl(char *rctl, uint64_t value, rctl_priv_t priv) { rctlblk_t *oblk, *nblk; boolean_t priv_deny = B_FALSE; int priv_sig = 0; if (value == LX_RLIM64_INFINITY) value = get_rctl_max(rctl); /* * The brand library cannot use malloc(3C) so we allocate the space * with SAFE_ALLOCA(). Thus there's no need to free it when we're done. */ oblk = (rctlblk_t *)SAFE_ALLOCA(rctlblk_size()); nblk = (rctlblk_t *)SAFE_ALLOCA(rctlblk_size()); if (getrctl(rctl, NULL, oblk, RCTL_FIRST) == -1) return (-errno); do { if (rctlblk_get_privilege(oblk) == RCPRIV_PRIVILEGED && rctlblk_get_local_action(oblk, &priv_sig) & RCTL_LOCAL_DENY) priv_deny = B_TRUE; if (rctlblk_get_privilege(oblk) != priv) continue; /* we're already at this value, nothing to do */ if (rctlblk_get_value(oblk) == value) return (0); /* non-root cannot raise privileged limit */ if (priv == RCPRIV_PRIVILEGED && geteuid() != 0 && value > rctlblk_get_value(oblk)) return (-EPERM); bcopy(oblk, nblk, rctlblk_size()); rctlblk_set_value(nblk, value); if (setrctl(rctl, oblk, nblk, RCTL_REPLACE) == -1) return (-errno); return (0); } while (getrctl(rctl, oblk, oblk, RCTL_NEXT) != -1); /* not there, add it */ bzero(nblk, rctlblk_size()); rctlblk_set_value(nblk, value); rctlblk_set_privilege(nblk, priv); if (priv_deny) { rctlblk_set_local_action(nblk, RCTL_LOCAL_DENY, 0); } else { rctlblk_set_local_action(nblk, RCTL_LOCAL_SIGNAL, priv_sig); } if (setrctl(rctl, NULL, nblk, RCTL_INSERT) == -1) return (-errno); return (0); }
int main (void) { rctlblk_t *old_rblk; rctlblk_t *new_rblk; char *name = "process.max-file-descriptor"; int fd; if (((old_rblk = malloc (rctlblk_size ())) == NULL) || ((new_rblk = malloc (rctlblk_size ())) == NULL)) err_msg ("malloc failed"); if (getrctl (name, NULL, old_rblk, RCTL_FIRST) == -1) err_msg ("getrctl failed"); memcpy (new_rblk, old_rblk, rctlblk_size ()); printf ("Before...\n"); print_rctl (old_rblk); rctlblk_set_value (new_rblk, 10); rctlblk_set_local_action (new_rblk, RCTL_LOCAL_DENY | RCTL_LOCAL_SIGNAL, SIGTERM); if (setrctl (name, NULL, old_rblk, RCTL_DELETE) == -1) err_msg ("setrctl (RCTL_DELETE) failed"); if (setrctl (name, NULL, new_rblk, RCTL_INSERT) == -1) err_msg ("setrctl (RCTL_INSERT) failed"); if (getrctl (name, NULL, new_rblk, RCTL_FIRST) == -1) err_msg ("getrctl failed"); printf ("After...\n"); print_rctl (new_rblk); for (;;) { fd = open ("/tmp", O_RDONLY); printf ("Returned file descriptor = %d\n", fd); } }