3 ulimit512.c - provide ulimit -f with 512-byte units on the command line
4 Copyright (C) 2018,2020 Kyle J. McKay. All rights reserved.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 "ulimit512 version 1.0.0\n" \
24 "Copyright (C) 2018,2020,2021 Kyle J. McKay <mackyle at gmail dot com>\n" \
25 "License GPLv2+: GNU GPL version 2 or later.\n" \
26 "<http://gnu.org/licenses/gpl2.html>\n" \
27 "This is free software: you are free to change and redistribute it.\n" \
28 "There is NO WARRANTY, to the extent permitted by law.\n"
31 "Usage: ulimit512 [option...] [<command> [<arg>...]]\n" \
32 " --help/-h show this help\n" \
33 " --version/-V show version/license info\n" \
34 " -f <blks> set UL_SETFSIZE to <blks> (dec/oct/hex # of 512-byte units)\n" \
35 " -i ignore UL_SETFSIZE error if UL_GETFSIZE is <= <blks> value\n" \
36 " -- terminate options, next arg is command even if it starts with -\n" \
37 " <command> if omitted do nothing other than attempt to set ulimit fsize\n" \
38 " <arg>... zero or more optional args to pass to <command>\n" \
39 "First sets ulimit UL_SETFSIZE value if any -f option given then uses execvp to\n" \
40 "run the <command> with any given <arg> values. A failure of UL_SETFSIZE or\n" \
41 "execvp will always result in an error. Note that the value given for -f ALWAYS\n" \
42 "specifies the limit in number of 512-byte units as required by POSIX and that\n" \
43 "the maximum value is the largest positive value that fits in a `long` type.\n" \
44 "Any -f values starting with `0x` are taken to be hexadecimal, starting with `0`\n" \
45 "means octal otherwise the value is decimal. It may NOT be negative.\n" \
46 "Note that using a <blks> value of 0 means zero bytes and is in no way special.\n"
60 #include <sys/types.h>
62 #include <sys/resource.h>
68 static long ulimit_get(void)
71 int rc
= getrlimit(RLIMIT_FSIZE
, &rl
);
75 fs
= rl
.rlim_max
>> 9;
76 if (rl
.rlim_max
== RLIM_INFINITY
|| fs
> LONG_MAX
)
81 static long ulimit_set(long fs
)
90 fsbytes
= (rlim_t
)fs
<< 9;
91 if ((fsbytes
>> 9) != fs
) {
95 rl
.rlim_max
= fsbytes
;
96 rl
.rlim_cur
= fsbytes
;
97 rc
= setrlimit(RLIMIT_FSIZE
, &rl
);
101 #define ulimit_get() ulimit(UL_GETFSIZE)
102 #define ulimit_set(fs) ulimit(UL_SETFSIZE, (fs))
105 int main(int argc
, char *argv
[])
112 while (arg
< argc
&& *argv
[arg
] == '-') {
113 if (!strcmp(argv
[arg
], "--help") || !strcmp(argv
[arg
], "-h")) {
117 if (!strcmp(argv
[arg
], "--version") || !strcmp(argv
[arg
], "-V")) {
118 printf("%s", VERSION
);
121 if (!strcmp(argv
[arg
], "-i")) {
126 if (!strcmp(argv
[arg
], "-f")) {
129 if (++arg
>= argc
|| !*argv
[arg
]) {
130 fprintf(stderr
, "ulimit512: missing -f value\n");
133 fsize
= strtol(argv
[arg
], &end
, 0);
135 fprintf(stderr
, "ulimit512: invalid number: %s\n",
140 fprintf(stderr
, "ulimit512: invalid limit %ld "
147 if (!strcmp(argv
[arg
], "--")) {
151 fprintf(stderr
, "ulimit512: invalid option: %s (see ulimit512 -h)\n",
159 result
= ulimit_set(fsize
);
160 if (result
== -1 && errno
!= 0) {
164 result
= ulimit_get();
165 if (result
< 0 || result
> fsize
)
169 fprintf(stderr
, "ulimit512: error: "
170 "set FSIZE limit %ld 512-byte units "
171 "failed: %s\n", fsize
,
179 int i
, cnt
= argc
- arg
;
180 char **cmd
= (char **)malloc((cnt
+ 1) * sizeof(char *));
183 fprintf(stderr
, "ulimit512: out of memory\n");
186 for (i
= 0; i
< cnt
; ++i
) {
187 cmd
[i
] = argv
[arg
+ i
];
190 if (execvp(cmd
[0], cmd
) == -1) {
191 fprintf(stderr
, "ulimit512: error: execvp failed: %s\n",
195 /* It's an error if execvp returns even if it's not -1 */
199 /* No error if nothing to do or just UL_SETFSIZE and that succeeded */