/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <sys/inttypes.h>
#include <sys/sysmacros.h>
#include <sys/tuneable.h>
#include <sys/resource.h>
/*
* Perhaps ulimit could be moved into a user library, as calls to
* getrlimit and setrlimit, were it not for binary compatibility
* restrictions.
*/
long
{
long retval;
switch (cmd) {
case UL_GFILLIM: /* Return current file size limit. */
{
mutex_enter(&p->p_lock);
p->p_rctls, p);
mutex_exit(&p->p_lock);
if (get_udatamodel() == DATAMODEL_ILP32) {
/*
* File size is returned in blocks for ulimit.
* This function is deprecated and therefore LFS API
* didn't define the behaviour of ulimit.
* Here we return maximum value of file size possible
* so that applications that do not check errors
* continue to work.
*/
if (filesize > MAXOFF32_T)
} else
break;
}
case UL_SFILLIM: /* Set new file size limit. */
{
int error = 0;
else
mutex_enter(&p->p_lock);
CRED())) {
mutex_exit(&p->p_lock);
}
mutex_exit(&p->p_lock);
break;
}
case UL_GMEMLIM: /* Return maximum possible break value. */
{
/*
* Find the segment with a virtual address
* greater than the end of the current break.
*/
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
/*
* Since we can't return less than the current break,
* initialize the return value to the current break
*/
break;
}
}
mutex_enter(&p->p_lock);
p->p_rctls, p);
p->p_rctls, p);
mutex_exit(&p->p_lock);
/*
* First, calculate the maximum break value based on
* the user's RLIMIT_DATA, but also taking into account
* that this value cannot be greater than as->a_userlimit.
* We also take care to make sure that we don't overflow
* in the calculation.
*/
/*
* Since we are casting the RLIMIT_DATA value to a
* ulong (a 32-bit value in the 32-bit kernel) we have
* to pass this assertion.
*/
/* don't return less than current */
else
/*
* The max break cannot extend into the next segment
*/
/*
* Handle the case where there is an limit on RLIMIT_VMEM
*/
if (vmem_ctl < UINT64_MAX) {
/* calculate brkend based on the end of page */
PAGESIZE);
/*
* Large Files: The following assertion has to pass
* through to ensure the correctness of the cast.
*/
else
size = 0;
/*
* Take care to not overflow the calculation
*/
}
/* truncate to same boundary as sbrk */
switch (get_udatamodel()) {
default:
case DATAMODEL_ILP32:
break;
case DATAMODEL_LP64:
break;
}
break;
}
case UL_GDESLIM: /* Return approximate number of open files */
{
break;
}
default:
}
return (retval);
}
#ifdef _SYSCALL32_IMPL
int
{
}
#endif /* _SYSCALL32_IMPL */
#if defined(_ILP32) || defined(_SYSCALL32_IMPL)
/*
* Large Files: getrlimit returns RLIM_SAVED_CUR or RLIM_SAVED_MAX when
* rlim_cur or rlim_max is not representable in 32-bit rlim_t. These
* values are just tokens which will be used in setrlimit to set the
* correct limits. The current limits are saved in the saved_rlimit members
* in user structures when the token is returned. setrlimit restores
* the limit values to these saved values when the token is passed.
* Consider the following common scenario of the apps:
*
* limit = getrlimit();
* savedlimit = limit;
* limit = limit1;
* setrlimit(limit)
* // execute all processes in the new rlimit state.
* setrlimit(savedlimit) // restore the old values.
*
* Most apps don't check error returns from getrlimit or setrlimit
* and this is why we return tokens when the correct value
* cannot be represented in rlim_t. For more discussion refer to
* the LFS API document.
*
* In the 64-bit kernel, all existing resource limits are treated in this
* manner. In the 32-bit kernel, CPU time is treated equivalently to the
* file size limit above; the VM-related limits are not. The macro,
* RLIM_SAVED(x), returns true if the resource limit should be handled in
* this way on the current kernel.
*/
int
{
int savecur = 0;
int savemax = 0;
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
else {
savemax = 1;
/*CONSTCOND*/
}
savecur = 1;
/*CONSTCOND*/
savecur = 1;
/*CONSTCOND*/
} else
/*
* save the current limits in user structure.
*/
/*CONSTCOND*/
if (RLIM_SAVED(resource)) {
mutex_enter(&p->p_lock);
if (savemax)
if (savecur)
mutex_exit(&p->p_lock);
}
} else {
}
return (0);
}
/*
* See comments above getrlimit32(). When the tokens are passed in the
* rlimit structure the values are considered equal to the values
* stored in saved_rlimit members of user structure.
* When the user passes RLIM_INFINITY to set the resource limit to
* unlimited internally understand this value as RLIM64_INFINITY and
* let rlimit() do the job.
*/
int
{
int error;
/*
* Disallow resource limit tunnelling
*/
/*CONSTCOND*/
if (RLIM_SAVED(resource)) {
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
} else {
}
case RLIM32_INFINITY:
break;
case RLIM32_SAVED_CUR:
break;
case RLIM32_SAVED_MAX:
break;
default:
break;
}
case RLIM32_INFINITY:
break;
case RLIM32_SAVED_MAX:
break;
case RLIM32_SAVED_CUR:
break;
default:
break;
}
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
}
mutex_exit(&p->p_lock);
return (0);
}
#endif /* _ILP32 && _SYSCALL32_IMPL */
int
{
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
return (0);
}
int
{
int error;
mutex_enter(&p->p_lock);
mutex_exit(&p->p_lock);
}
mutex_exit(&p->p_lock);
return (0);
}