[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libmicrohttpd] Spawning processes from access handler callback
From: |
Christian Grothoff |
Subject: |
Re: [libmicrohttpd] Spawning processes from access handler callback |
Date: |
Tue, 21 Apr 2015 13:49:10 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.6.0 |
Basically, calling popen() from multiple threads is not save according
to POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_01
(link from discussion at
http://cboard.cprogramming.com/linux-programming/136406-popen-thread-safe.html)
Locking may help, but this overall sounds like a bad idea for
performance as well. Why not have one thread (or main) globally do the
'ifconfig' fork and cache the result in a (lock-protected) global?
My 2 cents
Christian
On 04/20/2015 05:56 PM, address@hidden wrote:
>
>
> Hi Christian,
>
> My embedded linux webserver uses thread-per-connection mode. Using
> either the linux system() call or the popen() call, I am issuing a linux
> "ifconfig" command in my access handler callback, every second, on
> command from a webpage. I wait for the result and return the result
> string to the webpage in the response string.
>
> I find that after a variable number of minutes, I get a memory scribble
> which crashes my webserver application/daemon.
>
> Any linux command seems to show the same problem so it's not related to
> the "ifconfig", it crashes the same with "ps" or "ls" commands.
>
> Is there any reason why issuing system() or popen() calls in the
> callback might be unsafe?
>
> Here's the code I call in the callback
>
> int GetNetStats(MHD_Connection * connection, const char * szCommand)
> {
> FILE *fp;
> int status = 0;
> string strResponse = "<html><body>";
> const int max_buffer = 256;
> char buffer[max_buffer];
>
> /* Open the command for reading. */
> fp = popen(szCommand, "r");
> if (fp == NULL) {
> printf("Failed to run %s command\n", szCommand );
> status = -1;
> }
> else
> {
> /* Read the output a line at a time - output it. */
> while (!feof(fp))
> if (fgets(buffer, max_buffer, fp) != NULL) strResponse.append(buffer);
>
> pclose(fp);
> }
>
> strResponse += "</body></html>"; //terminate response string
> SendResponse(connection, strResponse);
>
> return status;
> }
>
> Best regards
>
> David Myers
>
>
0xE29FC3CC.asc
Description: application/pgp-keys