prlimit(), prlimit64()
Set and get the limit on a system resource
Synopsis:
#include <sys/resource.h>
int prlimit( pid_t pid,
int resource,
const struct rlimit * new_rlp,
struct rlimit * old_rlp );
int prlimit64( pid_t pid,
int resource,
const struct rlimit64 * new_rlp,
struct rlimit64 * old_rlp );
Arguments:
- pid
- The ID of the process to set or get the limit for. If pid is 0, the call applies to the calling process.
- resource
- The resource whose limit you want to get or set. For a list of the possible resources, their descriptions, and the actions taken when the current limit is exceeded, see below.
- new_rlp
- If this argument is not NULL, the rlimit structure that it points to is used to set new values for the soft and hard limits for resource.
- old_rlp
- If this argument is not NULL, a successful call to prlimit() places the previous soft and hard limits for resource in the rlimit structure that old_rlp points to.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The prlimit() and prlimit64() functions can be used to set and get limits on the consumption of a variety of system resources by a process and each process it creates. They combine and extend the functionality of setrlimit() and getrlimit(). The prlimit64() function is a large-file support version of prlimit().
Classificationin What's in a Function Description?
The possible resources, their descriptions, and the actions
taken when the current limit is exceeded are summarized below
(the _NP
in some names stands for non-POSIX
):
Resource | Classification | Description | Action |
---|---|---|---|
RLIMIT_AS | POSIX | The maximum size, in bytes, of a process's mapped address space. | If the limit is exceeded, mmap() fails with errno set to ENOMEM. In addition, the automatic stack growth fails with the effects outlined above. |
RLIMIT_CHANNELS_NP | QNX OS | The maximum number of channels a process can create; the default hard limit is 100 channels per process. | If the limit is exceeded, ChannelCreate() fails with errno set to EAGAIN. |
RLIMIT_CORE | POSIX | The maximum size, in bytes, of a core file that a process may create. A limit of 0 prevents the creation of a core file. | The writing of a core file terminates at this size. |
RLIMIT_CPU | POSIX | The maximum amount of CPU time, in seconds, that a process may use. This is a soft limit only. RLIMIT_CPU is an absolute value and is compared against the process's CPU clock, CLOCK_PROCESS_CPUTIME_ID. | If the limit is exceeded, only one SIGXCPU is sent to the process.
If the process is ignoring SIGXCPU, SIGKILL is sent to the
process.
If the current CPU time is greater than or equal to the RLIMIT_CPU set, then one SIGXCPU is sent to the process soon thereafter. |
RLIMIT_DATA | POSIX | The maximum size, in bytes, that a process's heap may be.
In QNX OS, RLIMIT_DATA covers all mappings
made by the process that are MAP_ANON | MAP_PRIVATE that aren't
MAP_STACK , which corresponds typically to heap allocations.
|
If the limit is exceeded, mmap() fails with errno set to ENOMEM. |
RLIMIT_FREEMEM | Unix | The limit on total memory usage, in tenths of a per cent of the total system memory. For example, a limit of 500 on a system with 1000 MB of memory would be 500 MB. | This limit is shared with all other processes;
a memory allocation by this process fails if it would cause the total system memory usage
of all processes to exceed this process's limit.
The intention is to allow the memory pool to be crudely partitioned. For example, important system processes could be given an RLIMIT_FREEMEM value of RLIM_INFINITY, and all others a value of 800. That would partition memory into an 80% chunk that's shared by everybody and a 20% chunk that's shared by important system processes. |
RLIMIT_FSIZE | POSIX | The maximum size of a file, in bytes, that may be created by a process. | If the limit is exceeded by a write or truncate operation, SIGXFSZ is sent to the thread. If the thread is blocking, or the process is catching or ignoring SIGXFSZ, continued attempts to increase the size of a file shall fail with errno set to EFBIG. |
RLIMIT_NOCONN_NP | QNX OS | The maximum number of connections a process can create,
including file descriptors and side-channel connections.
Most processes are created with three fds (stdin, stdout,
and stderr)
and a connection to the system process.
RLIMIT_NOCONN_NP should be greater than or equal to RLIMIT_NOFILE; it's up to you to set these limits so that they don't conflict. |
ConnectAttach() gives an error of EMFILE |
RLIMIT_NOFILE | POSIX | One more than the maximum value that the system may assign to a newly created descriptor. This limit constrains the number of file descriptors that a process may create. | Functions that allocate a file descriptor give an error of EMFILE |
RLIMIT_NPROC | Unix | The maximum number of processes. | Attempts to create new processes fail. |
RLIMIT_NTHR | Unix | The maximum number of threads. | Attempts to create threads (e.g., by calling pthread_create()) fail. |
RLIMIT_OFILE | Unix | Same as RLIMIT_NOFILE. | |
RLIMIT_RSS | Unix | The maximum resident set size for a process; the same as RLIMIT_AS. | Same as RLIMIT_AS. |
RLIMIT_SHM_HANDLES_NP | QNX OS | The maximum number of concurrent shmem handles created by a process and not yet consumed; the default number of handles is 50. | If the limit is exceeded, shm_create_handle() fails with EAGAIN. |
RLIMIT_SIGEVENT_NP | QNX OS | The maximum number of sigevents that a process can have registered at a given time. | MsgRegisterEvent() gives an error of EAGAIN. |
RLIMIT_STACK | POSIX | The maximum size, in bytes, that a process's stack may be. The system will not automatically grow the stack beyond this limit. Within a process, prlimit() increases the limit on the size of your stack, but doesn't move current memory segments to allow for that growth. To guarantee that the process stack can grow to the limit, the limit must be altered prior to the execution of the process in which the new stack size is to be used. Note:
Within a multithreaded process, do not try to change RLIMIT_STACK from a thread
that's not the main thread. If you do try this, prlimit() fails with
EINVAL. |
The SIGSEGV signal is sent to the process. If the process is holding or ignoring SIGSEGV, or is catching SIGSEGV and hasn't made arrangements to use an alternate stack, the disposition of SIGSEGV is set to SIG_DFL before it's sent. |
RLIMIT_TIMERS_NP | QNX OS | The maximum number of timers that a process can create. | Attempts to create timers by calling timer_create() or TimerCreate() fail with an error of EAGAIN. Note that this limit doesn't apply to TimerTimeout() |
RLIMIT_VMEM | Unix | Same as RLIMIT_AS. | Same as RLIMIT_AS. |
Because limit information is stored in the per-process information, the shell builtin ulimit command (see the entry for ksh in the Utilities Reference) must directly execute this system call if it's to affect all future processes created by the shell.
The values of the current limit of the following resources affect these parameters:
Resource | Parameter |
---|---|
RLIMIT_NOFILE | OPEN_MAX |
- If the resource limit can be represented correctly in an object of type rlim_t, then its representation is returned.
- If the value of the resource limit is equal to that of the corresponding saved hard limit, the value returned is RLIM_SAVED_MAX.
- For all other resource limit values, the value returned is RLIM_SAVED_CUR.
- If the new limit requested is RLIM_INFINITY, the new limit is "no limit".
- If the requested new limit is RLIM_SAVED_MAX the limit is set to the corresponding saved hard limit.
- If the requested new limit is RLIM_SAVED_CUR, the limit is set to the corresponding saved soft limit.
- For all other resource limit values, the limit is set to the requested value.
The result of setting a limit to RLIM_SAVED_MAX or RLIM_SAVED_CUR is unspecified unless a previous call to prlimit() returned that value as the soft or hard limit for the corresponding resource limit.
A limit whose value is greater than RLIM_INFINITY is permitted.
Returns:
- 0
- Success.
- -1
- An error occurred (errno is set).
Errors:
- EFAULT
- Either new_rlp or old_rlp points to an illegal address.
- EINVAL
- An invalid resource or an invalid value for the resource was specified.
- EPERM
- The calling process does not have the required permissions to set resource limits on the process with PID pid. (See procmgr_ability().)
- ESRCH
- The process specified by pid does not exist.
Examples:
struct rlimit old;
struct rlimit new;
pid_t pid;
int ret;
pid = ...
// Get the old limit for RLIMIT_CPU
ret = prlimit(pid, RLIMIT_CPU, NULL, &old);
if (ret != 0) {
perror("prlimit");
return errno;
}
printf("old: cur=%lu, max=%lu \n", old.rlim_cur, old.rlim_max);
new.rlim_cur = ...
new.rlim_max = ...
printf("new: cur=%lu, max=%lu \n", new.rlim_cur, new.rlim_max);
// Get and set the limit for RLIMIT_CPU
ret = prlimit(pid, RLIMIT_CPU, &new, &old);
if (ret != 0) {
perror("prlimit");
return errno;
}
printf("old: cur=%lu, max=%lu \n", old.rlim_cur, old.rlim_max);
Classification:
prlimit() is Linux; prlimit64() is Large-file support.
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |