diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b2508572c..7dc610eaa 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/builtins/ulimit.cpp b/src/builtins/ulimit.cpp index 0c7f1af85..fc96a81bc 100644 --- a/src/builtins/ulimit.cpp +++ b/src/builtins/ulimit.cpp @@ -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 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 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 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 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.