ulimit: return a specific error if option is not supported by the OS

This commit is contained in:
David Adam 2022-03-23 22:39:12 +08:00
parent 8c4c526698
commit a7eebff916
2 changed files with 67 additions and 29 deletions

View File

@ -34,7 +34,7 @@ Interactive improvements
- The default command-not-found handler now reports a special error if there is a non-executable file (:issue:`8804`)
- ``less`` and other interactive commands would occasionally be stopped when run in a pipeline with fish functions; this has been fixed (:issue:`8699`).
- Case-changing autosuggestions generated mid-token now correctly append only the suffix, instead of duplicating the token (:issue:`8820`).
- ``ulimit`` learned a number of new options for the resource limits available on Linux, FreeBSD and NetBSD (:issue:`8786`).
- ``ulimit`` learned a number of new options for the resource limits available on Linux, FreeBSD and NetBSD, and returns a specific warning if the limit specified is not available on the active operating system (:issue:`8823`).
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -76,6 +76,10 @@ static const struct resource_t resource_arr[] = {
#endif
{0, nullptr, 0, 0}};
/// This is likely to be the same as RLIMIT_INFINITY, but it shouldn't get used
/// in the same context (that is, compared to the result of a getrlimit call).
#define RLIMIT_UNKNOWN -1
/// Get the implicit multiplication factor for the specified resource limit.
static int get_multiplier(int what) {
for (int i = 0; resource_arr[i].desc; i++) {
@ -232,12 +236,14 @@ maybe_t<int> builtin_ulimit(parser_t &parser, io_streams_t &streams, const wchar
soft = true;
break;
}
#ifdef RLIMIT_SBSIZE
case 'b': {
#ifdef RLIMIT_SBSIZE
what = RLIMIT_SBSIZE;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
case 'c': {
what = RLIMIT_CORE;
break;
@ -246,50 +252,62 @@ maybe_t<int> builtin_ulimit(parser_t &parser, io_streams_t &streams, const wchar
what = RLIMIT_DATA;
break;
}
#ifdef RLIMIT_NICE
case 'e': {
#ifdef RLIMIT_NICE
what = RLIMIT_NICE;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
case 'f': {
what = RLIMIT_FSIZE;
break;
}
#ifdef RLIMIT_SIGPENDING
case 'i': {
#ifdef RLIMIT_SIGPENDING
what = RLIMIT_SIGPENDING;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_MEMLOCK
case 'l': {
#ifdef RLIMIT_MEMLOCK
what = RLIMIT_MEMLOCK;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_RSS
case 'm': {
#ifdef RLIMIT_RSS
what = RLIMIT_RSS;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
case 'n': {
what = RLIMIT_NOFILE;
break;
}
#ifdef RLIMIT_MSGQUEUE
case 'q': {
#ifdef RLIMIT_MSGQUEUE
what = RLIMIT_MSGQUEUE;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_RTPRIO
case 'r': {
#ifdef RLIMIT_RTPRIO
what = RLIMIT_RTPRIO;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
case 's': {
what = RLIMIT_STACK;
break;
@ -298,48 +316,62 @@ maybe_t<int> builtin_ulimit(parser_t &parser, io_streams_t &streams, const wchar
what = RLIMIT_CPU;
break;
}
#ifdef RLIMIT_NPROC
case 'u': {
#ifdef RLIMIT_NPROC
what = RLIMIT_NPROC;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_AS
case 'v': {
#ifdef RLIMIT_AS
what = RLIMIT_AS;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_SWAP
case 'w': {
#ifdef RLIMIT_SWAP
what = RLIMIT_SWAP;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_RTTIME
case 'y': {
#ifdef RLIMIT_RTTIME
what = RLIMIT_RTTIME;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_KQUEUES
case 'K': {
#ifdef RLIMIT_KQUEUES
what = RLIMIT_KQUEUES;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_NPTS
case 'P': {
#ifdef RLIMIT_NPTS
what = RLIMIT_NPTS;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
#ifdef RLIMIT_NTHR
case 'T': {
#ifdef RLIMIT_NTHR
what = RLIMIT_NTHR;
#else
what = RLIMIT_UNKNOWN;
#endif
break;
}
#endif
case 'h': {
builtin_print_help(parser, streams, cmd);
return STATUS_CMD_OK;
@ -363,6 +395,12 @@ maybe_t<int> builtin_ulimit(parser_t &parser, io_streams_t &streams, const wchar
return STATUS_CMD_OK;
}
if (what == RLIMIT_UNKNOWN) {
streams.err.append_format(_(L"%ls: Resource limit not available on this operating system\n"), cmd);
builtin_print_error_trailer(parser, streams.err, cmd);
return STATUS_INVALID_ARGS;
}
int arg_count = argc - w.woptind;
if (arg_count == 0) {
// Show current limit value.