This is a simplified case of something cygwin does:

1) Create a shared memory are using CreateFileMapping with SEC_RESERVE set.
2) Make the handle inheritable.
3) Call CreateProcess with inherit = TRUE
4) Map the region using MapViewOfFile.
5) Commit pages using VirtualAlloc.

See: MSDN's documentation on CreateFileMapping and VirtualAlloc.

When the test runs correctly, "%d: starting" is printed twice, with no other
output.

svn path=/trunk/; revision=6481
This commit is contained in:
Art Yerkes 2003-10-31 20:26:14 +00:00
parent 15da259ba7
commit 1a752ef4ba
2 changed files with 110 additions and 0 deletions

View file

@ -0,0 +1,21 @@
# $Id: makefile,v 1.1 2003/10/31 20:26:14 arty Exp $
PATH_TO_TOP = ../../..
TARGET_NORC = yes
TARGET_TYPE = program
TARGET_APPTYPE = console
TARGET_NAME = map_dup_inherit
TARGET_SDKLIBS = kernel32.a gdi32.a ntdll.a
TARGET_OBJECTS = $(TARGET_NAME).o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# EOF

View file

@ -0,0 +1,89 @@
#include <stdio.h>
#include <windows.h>
/* This tests the ability of the target win32 to create an anonymous file
* mapping, create a mapping view with MapViewOfFile, and then realize the
* pages with VirtualAlloc.
*/
int main( int argc, char **argv ) {
HANDLE file_view;
void *file_map;
int *x;
fprintf( stderr, "%d: Starting\n", GetCurrentProcessId() );
if( argc == 2 ) {
file_map = atoi(argv[1]);
} else {
file_map = CreateFileMapping( INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE | SEC_RESERVE,
0, 0x1000, NULL );
if( !SetHandleInformation( file_map,
HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT ) ) {
fprintf( stderr, "%d: Could not make handle inheritable.\n",
GetCurrentProcessId() );
return 100;
}
}
if( !file_map ) {
fprintf( stderr, "%d: Could not create anonymous file map.\n",
GetCurrentProcessId() );
return 1;
}
file_view = MapViewOfFile( file_map,
FILE_MAP_WRITE,
0,
0,
0x1000 );
if( !file_view ) {
fprintf( stderr, "%d: Could not map view of file.\n",
GetCurrentProcessId() );
return 2;
}
if( !VirtualAlloc( file_view, 0x1000, MEM_COMMIT, PAGE_READWRITE ) ) {
fprintf( stderr, "%d: VirtualAlloc failed to realize the page.\n",
GetCurrentProcessId() );
return 3;
}
x = (int *)file_view;
x[0] = 0x12345678;
if( x[0] != 0x12345678 ) {
fprintf( stderr, "%d: Can't write to the memory (%08x != 0x12345678)\n",
GetCurrentProcessId() );
return 4;
}
if( argc == 1 ) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
char cmdline[1000];
memset( &si, 0, sizeof( si ) );
memset( &pi, 0, sizeof( pi ) );
sprintf(cmdline,"%s %d", argv[0], (int)file_map);
if( !CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL,
&si, &pi ) ) {
fprintf( stderr, "%d: Could not create child process.\n",
GetCurrentProcessId() );
return 5;
}
if( WaitForSingleObject( pi.hThread, INFINITE ) != WAIT_OBJECT_0 ) {
fprintf( stderr, "%d: Failed to wait for child process to terminate.\n",
GetCurrentProcessId() );
return 6;
}
}
return 0;
}