system() function string length limitHow can I get a file's size in C?How do function pointers in C work?How does free know how much to free?Improve INSERT-per-second performance of SQLite?What does “#define _GNU_SOURCE” imply?Maximum length of command line argument that can be passed to SQL*Plus?Why are elementwise additions much faster in separate loops than in a combined loop?POSIX limits the number of character acceptable as user input to 4096, how to increase it?Does Posix supply format string macros for printf/scanf?Define length-prefixed const wide string in C
Circumcircle bisects the segment connecting the vertices of two regular even-sided polygons
Glitch in ac sinewave interfering with phase cut dimming
Break equation in parts
How can I find where certain bash function is defined?
Is there an explanation for Austria's Freedom Party virtually retaining its vote share despite recent scandal?
Crossing US border with music files I'm legally allowed to possess
I think I may have violated academic integrity last year - what should I do?
French translation of “only ever”
If a person had control of every single cell of their body, would they be able to transform into another creature?
Is there any use case for the bottom type as a function parameter type?
What is the 中 in ダウンロード中?
Reducing Spill Overs
Have I been doing real analysis incorrectly?
How long does it take to crack RSA 1024 with a PC?
How to verify sticky delta property on a stochastic volatility model
How were these pictures of spacecraft wind tunnel testing taken?
For which distribution same pdf is generated for given random variable
Is healing by fire possible?
Is it possible to change original filename of an exe?
Which noble houses were destroyed during the Game of Thrones?
Can I use the Shadow Step feature to effectively teleport into a Darkness spell I cast upon myself?
Best strategy for UK visa for a school trip (travelling alone or accomanpied child)?
Compact Mechanical Energy Source
At what point in European history could a government build a printing press given a basic description?
system() function string length limit
How can I get a file's size in C?How do function pointers in C work?How does free know how much to free?Improve INSERT-per-second performance of SQLite?What does “#define _GNU_SOURCE” imply?Maximum length of command line argument that can be passed to SQL*Plus?Why are elementwise additions much faster in separate loops than in a combined loop?POSIX limits the number of character acceptable as user input to 4096, how to increase it?Does Posix supply format string macros for printf/scanf?Define length-prefixed const wide string in C
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
How long can be a string passed to system()
?
I know the POSIX minimum is 4096, but I would like to know the actual size I can use. Is there any macro defined in any header for that, similar to FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
c linux posix
add a comment |
How long can be a string passed to system()
?
I know the POSIX minimum is 4096, but I would like to know the actual size I can use. Is there any macro defined in any header for that, similar to FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
c linux posix
4
Start worrying if your string is more than 100 KiB. Until then, you should be OK.
– Jonathan Leffler
Apr 13 at 15:11
If this is a problem for your programming, you are better off writing the command arguments into a file and updating the command to read that. Many programs, like the compiler and linker on Windows, can already read arguments from a file. Some Unix programs likexargs
can read a stream of arguments and run one copy of the command template for eachn
arguments.
– Zan Lynx
Apr 13 at 23:13
BTW, thesystem()
function is a very different thing from a "system call" in the syscall (userspace/kernelspace boundary) sense of the word.
– Charles Duffy
Apr 13 at 23:17
add a comment |
How long can be a string passed to system()
?
I know the POSIX minimum is 4096, but I would like to know the actual size I can use. Is there any macro defined in any header for that, similar to FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
c linux posix
How long can be a string passed to system()
?
I know the POSIX minimum is 4096, but I would like to know the actual size I can use. Is there any macro defined in any header for that, similar to FILENAME_MAX
?
char cmd[SOME_MACRO];
...
system(cmd);
c linux posix
c linux posix
edited Apr 13 at 23:16
Charles Duffy
185k28214267
185k28214267
asked Apr 13 at 15:08
Cacahuete FritoCacahuete Frito
1,1671622
1,1671622
4
Start worrying if your string is more than 100 KiB. Until then, you should be OK.
– Jonathan Leffler
Apr 13 at 15:11
If this is a problem for your programming, you are better off writing the command arguments into a file and updating the command to read that. Many programs, like the compiler and linker on Windows, can already read arguments from a file. Some Unix programs likexargs
can read a stream of arguments and run one copy of the command template for eachn
arguments.
– Zan Lynx
Apr 13 at 23:13
BTW, thesystem()
function is a very different thing from a "system call" in the syscall (userspace/kernelspace boundary) sense of the word.
– Charles Duffy
Apr 13 at 23:17
add a comment |
4
Start worrying if your string is more than 100 KiB. Until then, you should be OK.
– Jonathan Leffler
Apr 13 at 15:11
If this is a problem for your programming, you are better off writing the command arguments into a file and updating the command to read that. Many programs, like the compiler and linker on Windows, can already read arguments from a file. Some Unix programs likexargs
can read a stream of arguments and run one copy of the command template for eachn
arguments.
– Zan Lynx
Apr 13 at 23:13
BTW, thesystem()
function is a very different thing from a "system call" in the syscall (userspace/kernelspace boundary) sense of the word.
– Charles Duffy
Apr 13 at 23:17
4
4
Start worrying if your string is more than 100 KiB. Until then, you should be OK.
– Jonathan Leffler
Apr 13 at 15:11
Start worrying if your string is more than 100 KiB. Until then, you should be OK.
– Jonathan Leffler
Apr 13 at 15:11
If this is a problem for your programming, you are better off writing the command arguments into a file and updating the command to read that. Many programs, like the compiler and linker on Windows, can already read arguments from a file. Some Unix programs like
xargs
can read a stream of arguments and run one copy of the command template for each n
arguments.– Zan Lynx
Apr 13 at 23:13
If this is a problem for your programming, you are better off writing the command arguments into a file and updating the command to read that. Many programs, like the compiler and linker on Windows, can already read arguments from a file. Some Unix programs like
xargs
can read a stream of arguments and run one copy of the command template for each n
arguments.– Zan Lynx
Apr 13 at 23:13
BTW, the
system()
function is a very different thing from a "system call" in the syscall (userspace/kernelspace boundary) sense of the word.– Charles Duffy
Apr 13 at 23:17
BTW, the
system()
function is a very different thing from a "system call" in the syscall (userspace/kernelspace boundary) sense of the word.– Charles Duffy
Apr 13 at 23:17
add a comment |
3 Answers
3
active
oldest
votes
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), so
the maximum length (not counting the ''
terminator) is ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
is defined in limits.h as
"Maximum length of argument to the exec functions including
environment data."
If limits.h
, doesn't define ARG_MAX
, you should be able to callsysconf(_SC_ARG_MAX)
to obtain a runtime limit.
The linux manpage for execve (called by system) provides more information:
On Linux prior to kernel 2.6.23, the memory used to store the
environment and argument strings was limited to 32 pages (defined by
the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page
size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit
derived from the soft RLIMIT_STACK resource limit (see getrlimit(2))
that is in force at the time of the execve() call. (Architectures with
no memory management unit are excepted: they maintain the limit that
was in effect before kernel 2.6.23.) This change allows programs to
have a much larger argument and/or environment list. For these
architectures, the total size is limited to 1/4 of the allowed stack
size. (Imposing the 1/4-limit ensures that the new program always has
some stack space.) Since Linux 2.6.25, the kernel places a floor of 32
pages on this size limit, so that, even when RLIMIT_STACK is set very
low, applications are guaranteed to have at least as much argument and
environment space as was provided by Linux 2.6.23 and earlier. (This
guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally,
the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN),
and the maximum number of strings is 0x7FFFFFFF.
To measure the size of your environment, you can run:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(As Zan Lynx has pointed out in the comments, this can be sped up (cca 20 times as per my measurements—from 1600ns to 80ns for the 100-string 6KB environment I had when measuring)
if you assume the char*
pointers in environ
point to a contiguous buffer, which they do after a program starts, but calls to setenv
, putenv
, or unsetenv
typically break this:
extern char **environ;
char **e; for(e=environ; *e; e++)
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
In any case, the speed up at the cost of robustness shouldn't matter much if you're expecting to fork+exec (/system) soon, given that fork+exec typically costs at least around 1-2ms on Linux on a modern machine.)
1
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
1
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involvingstrlen
calls.
– Zan Lynx
Apr 13 at 23:15
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
1
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
|
show 2 more comments
The limit is highly system dependent. It may even depend on the command shell that will be used. You should test the return value of system()
to see if the system call was successful: -1
means failure and errno
should give you more information. The behavior should be defined for any proper C string.
POSIX documents that system(command)
is equivalent to:
execl(<shell path>, "sh", "-c", command, (char *)0);
And also documents ARG_MAX
defined in <limits.h>
as the limit for the combined lengths of the arguments to exec
and the environment variables.
Note however that command
may contain wildcards and/or other shell words whose expansion may exceed some other limit. Always check the return value for failure.
add a comment |
man 3 system
gives us
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command
using execl(3) as follows:execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
so system() is a wrapper for
execl()
From the same page we also see that this call conforms to some standards.
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99.
Looking up POSIX.1-2008 produces the following online reference
https://pubs.opengroup.org/onlinepubs/9699919799/
Where we can search for info on the execl
function which system takes us to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Which offers up the following
The number of bytes available for the new process' combined argument and environment lists is ARG_MAX. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
And finally ...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument
list and environment list is greater than the system-imposed limit of
ARG_MAX bytes.
So the final check to carry out here is the actual exec implementation rather than relying on the standard just in case the implementation deviated from the standard.
So, man 3 execl
reports that the errors returned are the same as documented for execve(2)
and man 2 execvw
reports the following:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
Not as precise as the POSIX standard? Best check the code or see the (now) accepted answer :)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55666911%2fsystem-function-string-length-limit%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), so
the maximum length (not counting the ''
terminator) is ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
is defined in limits.h as
"Maximum length of argument to the exec functions including
environment data."
If limits.h
, doesn't define ARG_MAX
, you should be able to callsysconf(_SC_ARG_MAX)
to obtain a runtime limit.
The linux manpage for execve (called by system) provides more information:
On Linux prior to kernel 2.6.23, the memory used to store the
environment and argument strings was limited to 32 pages (defined by
the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page
size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit
derived from the soft RLIMIT_STACK resource limit (see getrlimit(2))
that is in force at the time of the execve() call. (Architectures with
no memory management unit are excepted: they maintain the limit that
was in effect before kernel 2.6.23.) This change allows programs to
have a much larger argument and/or environment list. For these
architectures, the total size is limited to 1/4 of the allowed stack
size. (Imposing the 1/4-limit ensures that the new program always has
some stack space.) Since Linux 2.6.25, the kernel places a floor of 32
pages on this size limit, so that, even when RLIMIT_STACK is set very
low, applications are guaranteed to have at least as much argument and
environment space as was provided by Linux 2.6.23 and earlier. (This
guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally,
the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN),
and the maximum number of strings is 0x7FFFFFFF.
To measure the size of your environment, you can run:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(As Zan Lynx has pointed out in the comments, this can be sped up (cca 20 times as per my measurements—from 1600ns to 80ns for the 100-string 6KB environment I had when measuring)
if you assume the char*
pointers in environ
point to a contiguous buffer, which they do after a program starts, but calls to setenv
, putenv
, or unsetenv
typically break this:
extern char **environ;
char **e; for(e=environ; *e; e++)
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
In any case, the speed up at the cost of robustness shouldn't matter much if you're expecting to fork+exec (/system) soon, given that fork+exec typically costs at least around 1-2ms on Linux on a modern machine.)
1
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
1
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involvingstrlen
calls.
– Zan Lynx
Apr 13 at 23:15
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
1
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
|
show 2 more comments
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), so
the maximum length (not counting the ''
terminator) is ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
is defined in limits.h as
"Maximum length of argument to the exec functions including
environment data."
If limits.h
, doesn't define ARG_MAX
, you should be able to callsysconf(_SC_ARG_MAX)
to obtain a runtime limit.
The linux manpage for execve (called by system) provides more information:
On Linux prior to kernel 2.6.23, the memory used to store the
environment and argument strings was limited to 32 pages (defined by
the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page
size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit
derived from the soft RLIMIT_STACK resource limit (see getrlimit(2))
that is in force at the time of the execve() call. (Architectures with
no memory management unit are excepted: they maintain the limit that
was in effect before kernel 2.6.23.) This change allows programs to
have a much larger argument and/or environment list. For these
architectures, the total size is limited to 1/4 of the allowed stack
size. (Imposing the 1/4-limit ensures that the new program always has
some stack space.) Since Linux 2.6.25, the kernel places a floor of 32
pages on this size limit, so that, even when RLIMIT_STACK is set very
low, applications are guaranteed to have at least as much argument and
environment space as was provided by Linux 2.6.23 and earlier. (This
guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally,
the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN),
and the maximum number of strings is 0x7FFFFFFF.
To measure the size of your environment, you can run:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(As Zan Lynx has pointed out in the comments, this can be sped up (cca 20 times as per my measurements—from 1600ns to 80ns for the 100-string 6KB environment I had when measuring)
if you assume the char*
pointers in environ
point to a contiguous buffer, which they do after a program starts, but calls to setenv
, putenv
, or unsetenv
typically break this:
extern char **environ;
char **e; for(e=environ; *e; e++)
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
In any case, the speed up at the cost of robustness shouldn't matter much if you're expecting to fork+exec (/system) soon, given that fork+exec typically costs at least around 1-2ms on Linux on a modern machine.)
1
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
1
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involvingstrlen
calls.
– Zan Lynx
Apr 13 at 23:15
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
1
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
|
show 2 more comments
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), so
the maximum length (not counting the ''
terminator) is ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
is defined in limits.h as
"Maximum length of argument to the exec functions including
environment data."
If limits.h
, doesn't define ARG_MAX
, you should be able to callsysconf(_SC_ARG_MAX)
to obtain a runtime limit.
The linux manpage for execve (called by system) provides more information:
On Linux prior to kernel 2.6.23, the memory used to store the
environment and argument strings was limited to 32 pages (defined by
the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page
size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit
derived from the soft RLIMIT_STACK resource limit (see getrlimit(2))
that is in force at the time of the execve() call. (Architectures with
no memory management unit are excepted: they maintain the limit that
was in effect before kernel 2.6.23.) This change allows programs to
have a much larger argument and/or environment list. For these
architectures, the total size is limited to 1/4 of the allowed stack
size. (Imposing the 1/4-limit ensures that the new program always has
some stack space.) Since Linux 2.6.25, the kernel places a floor of 32
pages on this size limit, so that, even when RLIMIT_STACK is set very
low, applications are guaranteed to have at least as much argument and
environment space as was provided by Linux 2.6.23 and earlier. (This
guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally,
the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN),
and the maximum number of strings is 0x7FFFFFFF.
To measure the size of your environment, you can run:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(As Zan Lynx has pointed out in the comments, this can be sped up (cca 20 times as per my measurements—from 1600ns to 80ns for the 100-string 6KB environment I had when measuring)
if you assume the char*
pointers in environ
point to a contiguous buffer, which they do after a program starts, but calls to setenv
, putenv
, or unsetenv
typically break this:
extern char **environ;
char **e; for(e=environ; *e; e++)
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
In any case, the speed up at the cost of robustness shouldn't matter much if you're expecting to fork+exec (/system) soon, given that fork+exec typically costs at least around 1-2ms on Linux on a modern machine.)
system
exec's a shell with arguments "sh","-c", YourAgumentToSystem, (char*)0
(guaranteed by POSIX), so
the maximum length (not counting the ''
terminator) is ARG_MAX -1 -3 -3 - size_of_your_environment
.
ARG_MAX
is defined in limits.h as
"Maximum length of argument to the exec functions including
environment data."
If limits.h
, doesn't define ARG_MAX
, you should be able to callsysconf(_SC_ARG_MAX)
to obtain a runtime limit.
The linux manpage for execve (called by system) provides more information:
On Linux prior to kernel 2.6.23, the memory used to store the
environment and argument strings was limited to 32 pages (defined by
the kernel constant MAX_ARG_PAGES). On architectures with a 4-kB page
size, this yields a maximum size of 128 kB.
On kernel 2.6.23 and later, most architectures support a size limit
derived from the soft RLIMIT_STACK resource limit (see getrlimit(2))
that is in force at the time of the execve() call. (Architectures with
no memory management unit are excepted: they maintain the limit that
was in effect before kernel 2.6.23.) This change allows programs to
have a much larger argument and/or environment list. For these
architectures, the total size is limited to 1/4 of the allowed stack
size. (Imposing the 1/4-limit ensures that the new program always has
some stack space.) Since Linux 2.6.25, the kernel places a floor of 32
pages on this size limit, so that, even when RLIMIT_STACK is set very
low, applications are guaranteed to have at least as much argument and
environment space as was provided by Linux 2.6.23 and earlier. (This
guarantee was not provided in Linux 2.6.23 and 2.6.24.) Additionally,
the limit per string is 32 pages (the kernel constant MAX_ARG_STRLEN),
and the maximum number of strings is 0x7FFFFFFF.
To measure the size of your environment, you can run:
extern char **environ;
size_t envsz = 0; for(char **e=environ; *e; e++) envsz += strlen(*e)+1;
(As Zan Lynx has pointed out in the comments, this can be sped up (cca 20 times as per my measurements—from 1600ns to 80ns for the 100-string 6KB environment I had when measuring)
if you assume the char*
pointers in environ
point to a contiguous buffer, which they do after a program starts, but calls to setenv
, putenv
, or unsetenv
typically break this:
extern char **environ;
char **e; for(e=environ; *e; e++)
size_t envsz = ($_sz)(e[-1]+strlen(e[-1])+1 - *environ);
In any case, the speed up at the cost of robustness shouldn't matter much if you're expecting to fork+exec (/system) soon, given that fork+exec typically costs at least around 1-2ms on Linux on a modern machine.)
edited Apr 14 at 12:40
answered Apr 13 at 15:23
PSkocikPSkocik
36.5k65580
36.5k65580
1
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
1
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involvingstrlen
calls.
– Zan Lynx
Apr 13 at 23:15
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
1
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
|
show 2 more comments
1
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
1
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involvingstrlen
calls.
– Zan Lynx
Apr 13 at 23:15
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
1
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
1
1
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
Note that this value may be large for allocation with automatic storage.
– chqrlie
Apr 13 at 16:02
1
1
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
Its also not guarenteed that exceeding it will fail -- its (just) undefined behavior, so it may work one time you call it and fail the next.
– Chris Dodd
Apr 13 at 17:31
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involving
strlen
calls.– Zan Lynx
Apr 13 at 23:15
I don't think that's the most efficient way to calculate environment size. I believe you can run the pointers up until the NULL and subtract from environ, without involving
strlen
calls.– Zan Lynx
Apr 13 at 23:15
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
@ZanLynx I think that'll only work with a fresh environment. The environment-manipulating functions don't appear to keep the backend contiguous.
– PSkocik
Apr 14 at 0:50
1
1
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
@PSkocik 1 thousandth more or less, but still have a point.
– Cacahuete Frito
Apr 14 at 8:23
|
show 2 more comments
The limit is highly system dependent. It may even depend on the command shell that will be used. You should test the return value of system()
to see if the system call was successful: -1
means failure and errno
should give you more information. The behavior should be defined for any proper C string.
POSIX documents that system(command)
is equivalent to:
execl(<shell path>, "sh", "-c", command, (char *)0);
And also documents ARG_MAX
defined in <limits.h>
as the limit for the combined lengths of the arguments to exec
and the environment variables.
Note however that command
may contain wildcards and/or other shell words whose expansion may exceed some other limit. Always check the return value for failure.
add a comment |
The limit is highly system dependent. It may even depend on the command shell that will be used. You should test the return value of system()
to see if the system call was successful: -1
means failure and errno
should give you more information. The behavior should be defined for any proper C string.
POSIX documents that system(command)
is equivalent to:
execl(<shell path>, "sh", "-c", command, (char *)0);
And also documents ARG_MAX
defined in <limits.h>
as the limit for the combined lengths of the arguments to exec
and the environment variables.
Note however that command
may contain wildcards and/or other shell words whose expansion may exceed some other limit. Always check the return value for failure.
add a comment |
The limit is highly system dependent. It may even depend on the command shell that will be used. You should test the return value of system()
to see if the system call was successful: -1
means failure and errno
should give you more information. The behavior should be defined for any proper C string.
POSIX documents that system(command)
is equivalent to:
execl(<shell path>, "sh", "-c", command, (char *)0);
And also documents ARG_MAX
defined in <limits.h>
as the limit for the combined lengths of the arguments to exec
and the environment variables.
Note however that command
may contain wildcards and/or other shell words whose expansion may exceed some other limit. Always check the return value for failure.
The limit is highly system dependent. It may even depend on the command shell that will be used. You should test the return value of system()
to see if the system call was successful: -1
means failure and errno
should give you more information. The behavior should be defined for any proper C string.
POSIX documents that system(command)
is equivalent to:
execl(<shell path>, "sh", "-c", command, (char *)0);
And also documents ARG_MAX
defined in <limits.h>
as the limit for the combined lengths of the arguments to exec
and the environment variables.
Note however that command
may contain wildcards and/or other shell words whose expansion may exceed some other limit. Always check the return value for failure.
edited Apr 13 at 15:54
answered Apr 13 at 15:15
chqrliechqrlie
66.2k854112
66.2k854112
add a comment |
add a comment |
man 3 system
gives us
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command
using execl(3) as follows:execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
so system() is a wrapper for
execl()
From the same page we also see that this call conforms to some standards.
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99.
Looking up POSIX.1-2008 produces the following online reference
https://pubs.opengroup.org/onlinepubs/9699919799/
Where we can search for info on the execl
function which system takes us to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Which offers up the following
The number of bytes available for the new process' combined argument and environment lists is ARG_MAX. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
And finally ...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument
list and environment list is greater than the system-imposed limit of
ARG_MAX bytes.
So the final check to carry out here is the actual exec implementation rather than relying on the standard just in case the implementation deviated from the standard.
So, man 3 execl
reports that the errors returned are the same as documented for execve(2)
and man 2 execvw
reports the following:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
Not as precise as the POSIX standard? Best check the code or see the (now) accepted answer :)
add a comment |
man 3 system
gives us
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command
using execl(3) as follows:execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
so system() is a wrapper for
execl()
From the same page we also see that this call conforms to some standards.
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99.
Looking up POSIX.1-2008 produces the following online reference
https://pubs.opengroup.org/onlinepubs/9699919799/
Where we can search for info on the execl
function which system takes us to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Which offers up the following
The number of bytes available for the new process' combined argument and environment lists is ARG_MAX. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
And finally ...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument
list and environment list is greater than the system-imposed limit of
ARG_MAX bytes.
So the final check to carry out here is the actual exec implementation rather than relying on the standard just in case the implementation deviated from the standard.
So, man 3 execl
reports that the errors returned are the same as documented for execve(2)
and man 2 execvw
reports the following:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
Not as precise as the POSIX standard? Best check the code or see the (now) accepted answer :)
add a comment |
man 3 system
gives us
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command
using execl(3) as follows:execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
so system() is a wrapper for
execl()
From the same page we also see that this call conforms to some standards.
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99.
Looking up POSIX.1-2008 produces the following online reference
https://pubs.opengroup.org/onlinepubs/9699919799/
Where we can search for info on the execl
function which system takes us to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Which offers up the following
The number of bytes available for the new process' combined argument and environment lists is ARG_MAX. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
And finally ...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument
list and environment list is greater than the system-imposed limit of
ARG_MAX bytes.
So the final check to carry out here is the actual exec implementation rather than relying on the standard just in case the implementation deviated from the standard.
So, man 3 execl
reports that the errors returned are the same as documented for execve(2)
and man 2 execvw
reports the following:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
Not as precise as the POSIX standard? Best check the code or see the (now) accepted answer :)
man 3 system
gives us
DESCRIPTION
The system() library function uses fork(2) to create a child process that executes the shell command specified in command
using execl(3) as follows:execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
so system() is a wrapper for
execl()
From the same page we also see that this call conforms to some standards.
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99.
Looking up POSIX.1-2008 produces the following online reference
https://pubs.opengroup.org/onlinepubs/9699919799/
Where we can search for info on the execl
function which system takes us to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
Which offers up the following
The number of bytes available for the new process' combined argument and environment lists is ARG_MAX. It is implementation-defined whether null terminators, pointers, and/or any alignment bytes are included in this total.
And finally ...
ERRORS
The exec functions shall fail if:
[E2BIG] The number of bytes used by the new process image's argument
list and environment list is greater than the system-imposed limit of
ARG_MAX bytes.
So the final check to carry out here is the actual exec implementation rather than relying on the standard just in case the implementation deviated from the standard.
So, man 3 execl
reports that the errors returned are the same as documented for execve(2)
and man 2 execvw
reports the following:
ERRORS
E2BIG The total number of bytes in the environment (envp) and argument list (argv) is too large.
Not as precise as the POSIX standard? Best check the code or see the (now) accepted answer :)
edited Apr 13 at 15:45
answered Apr 13 at 15:38
Rob KieltyRob Kielty
6,46653047
6,46653047
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55666911%2fsystem-function-string-length-limit%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
Start worrying if your string is more than 100 KiB. Until then, you should be OK.
– Jonathan Leffler
Apr 13 at 15:11
If this is a problem for your programming, you are better off writing the command arguments into a file and updating the command to read that. Many programs, like the compiler and linker on Windows, can already read arguments from a file. Some Unix programs like
xargs
can read a stream of arguments and run one copy of the command template for eachn
arguments.– Zan Lynx
Apr 13 at 23:13
BTW, the
system()
function is a very different thing from a "system call" in the syscall (userspace/kernelspace boundary) sense of the word.– Charles Duffy
Apr 13 at 23:17