Bug 50774 - variables trashed in forked process
Summary: variables trashed in forked process
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: gcc
Version: 7.0
Hardware: i686
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: David Lawrence
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-08-03 00:09 UTC by Dan Mergens
Modified: 2007-04-18 16:35 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2001-08-03 00:09:45 UTC
Embargoed:


Attachments (Terms of Use)

Description Dan Mergens 2001-08-03 00:09:41 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686)

Description of problem:
When setting a variable in a forked process, its value is not set properly.

How reproducible:
Always

Steps to Reproduce:
Here's the source code to compile and run
----------------------------------------
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define REDIRECT_BUFFER_SIZE 1000000

/*----------------------------------------------------------------------
FUNCTION
        redirectIO - capture the standard output of a spawned process
SIDE EFFECTS
        Allocates memory for return character array which must be freed
        by calling process.
LIMITATIONS
        The buffer size is limited to REDIRECT_BUFFER_SIZE bytes for the
        standard output.
----------------------------------------------------------------------*/
char* redirectIO( const char* arglist, int* status=NULL );
 
char*
redirectIO( const char* arglist, int* status )
{
        int   fds[2];
        int   nread;
        pid_t pid;
        char* buf = (char*)malloc( sizeof(char)*REDIRECT_BUFFER_SIZE );
 
        pipe( fds );
 
        pid = fork();
        if( pid == 0 )  // child process
        {
                close( 1 );
                dup( fds[1] );
                close( fds[0] );
                if( status != NULL )
                        *status = system( arglist );
                else
                        system( arglist );
                exit( EXIT_SUCCESS );
        }
        else
        {
                nread = read( fds[0], buf, REDIRECT_BUFFER_SIZE );
                if( nread < REDIRECT_BUFFER_SIZE )
                {
                        buf = (char*)realloc( buf, sizeof(char)*(nread+1)
);
                        buf[nread] = 0;
                }
                else if( nread >= (REDIRECT_BUFFER_SIZE-1) )
                {
                        buf[REDIRECT_BUFFER_SIZE-1] = 0;
                }
        }
 
        return buf;
}
 
int main( int argc, char* const* argv )
{
        char*  return_string;
        int    status;
 
//      status = system( "wc -l testfile.txt" );
        return_string = redirectIO( "wc -l testfile.txt", &status );
        fprintf( stdout, "return string is %s\n", return_string );
        fprintf( stdout, "status is %d\n", status );
}
--------------------------------------------------
(You will also need the file testfile.txt which is only used for the line
count)

Actual Results:  return string is       2 testfile.txt
 
status is 134514545

Expected Results:  return string is       2 testfile.txt
 
status is 0

Additional info:

When the system call is performed in a function or in the main block the
status is set correctly to 0. This code works on IRIX properly. Apparently,
the variable either getting trashed or not set in the forked process.

Comment 1 Jakub Jelinek 2001-08-06 15:04:45 UTC
This is the expected behaviour. fork means the two processes don't share
address space, so writing into *status in the child really should not do
anything in the parent (it is possible that this was 0 on Irix before).
If you want the two processes to share memory, so that this would work,
please check out POSIX threads library or clone system call instead.


Note You need to log in before you can comment on or make changes to this bug.