system() function string length limit Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!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

How does the math work when buying airline miles?

How can I prevent/balance waiting and turtling as a response to cooldown mechanics

In musical terms, what properties are varied by the human voice to produce different words / syllables?

How to write capital alpha?

Drawing spherical mirrors

Amount of permutations on an NxNxN Rubik's Cube

Did Mueller's report provide an evidentiary basis for the claim of Russian govt election interference via social media?

Google .dev domain strangely redirects to https

What to do with repeated rejections for phd position

Misunderstanding of Sylow theory

Is it possible to force a specific program to remain in memory after closing it?

One-one communication

Is it possible for SQL statements to execute concurrently within a single session in SQL Server?

How does Belgium enforce obligatory attendance in elections?

What makes a man succeed?

How to dry out epoxy resin faster than usual?

What is the difference between globalisation and imperialism?

Draw 4 of the same figure in the same tikzpicture

Random body shuffle every night—can we still function?

Why are vacuum tubes still used in amateur radios?

Most bit efficient text communication method?

Is CEO the "profession" with the most psychopaths?

What would you call this weird metallic apparatus that allows you to lift people?

Flash light on something



system() function string length limit



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!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;








10















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);









share|improve this question



















  • 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 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

















10















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);









share|improve this question



















  • 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 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













10












10








10








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);









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 13 at 23:16









Charles Duffy

182k28206261




182k28206261










asked Apr 13 at 15:08









Cacahuete FritoCacahuete Frito

667621




667621







  • 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 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












  • 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 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







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












3 Answers
3






active

oldest

votes


















9














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 call
sysconf(_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.)






share|improve this answer




















  • 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 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






  • 1





    @PSkocik 1 thousandth more or less, but still have a point.

    – Cacahuete Frito
    Apr 14 at 8:23


















4














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.






share|improve this answer
































    3















    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 :)






    share|improve this answer

























      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
      );



      );













      draft saved

      draft discarded


















      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









      9














      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 call
      sysconf(_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.)






      share|improve this answer




















      • 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 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






      • 1





        @PSkocik 1 thousandth more or less, but still have a point.

        – Cacahuete Frito
        Apr 14 at 8:23















      9














      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 call
      sysconf(_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.)






      share|improve this answer




















      • 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 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






      • 1





        @PSkocik 1 thousandth more or less, but still have a point.

        – Cacahuete Frito
        Apr 14 at 8:23













      9












      9








      9







      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 call
      sysconf(_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.)






      share|improve this answer















      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 call
      sysconf(_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.)







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Apr 14 at 12:40

























      answered Apr 13 at 15:23









      PSkocikPSkocik

      35.8k65580




      35.8k65580







      • 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 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






      • 1





        @PSkocik 1 thousandth more or less, but still have a point.

        – Cacahuete Frito
        Apr 14 at 8:23












      • 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 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






      • 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













      4














      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.






      share|improve this answer





























        4














        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.






        share|improve this answer



























          4












          4








          4







          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.






          share|improve this answer















          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 13 at 15:54

























          answered Apr 13 at 15:15









          chqrliechqrlie

          64k851108




          64k851108





















              3















              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 :)






              share|improve this answer





























                3















                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 :)






                share|improve this answer



























                  3












                  3








                  3








                  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 :)






                  share|improve this 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 :)







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Apr 13 at 15:45

























                  answered Apr 13 at 15:38









                  Rob KieltyRob Kielty

                  6,43153047




                  6,43153047



























                      draft saved

                      draft discarded
















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      How to write a 12-bar blues melodyI-IV-V blues progressionHow to play the bridges in a standard blues progressionHow does Gdim7 fit in C# minor?question on a certain chord progressionMusicology of Melody12 bar blues, spread rhythm: alternative to 6th chord to avoid finger stretchChord progressions/ Root key/ MelodiesHow to put chords (POP-EDM) under a given lead vocal melody (starting from a good knowledge in music theory)Are there “rules” for improvising with the minor pentatonic scale over 12-bar shuffle?Confusion about blues scale and chords

                      What if the end-user didn't have the required library?What is setup.py?What is a clean, pythonic way to have multiple constructors in Python?What does Ruby have that Python doesn't, and vice versa?What is the reason for having '//' in Python?How do I create a namespace package in Python?How to package shared objects that python modules depend on?setuptools vs. distutils: why is distutils still a thing?Navigation in Windows 10 vs code not going to virtualenv library when the same library is installed at user levelPython create package for local usePackaging a project that uses multiple python versionsWhy is permission denied on pip install except for when “--user” is included at end of command?

                      Esgonzo ibérico Índice Descrición Distribución Hábitat Ameazas Notas Véxase tamén "Acerca dos nomes dos anfibios e réptiles galegos""Chalcides bedriagai"Chalcides bedriagai en Carrascal, L. M. Salvador, A. (Eds). Enciclopedia virtual de los vertebrados españoles. Museo Nacional de Ciencias Naturales, Madrid. España.Fotos