Mail Archives: cygwin/2002/06/03/17:06:06
Enclosed is a sample program that demonstrates a bug with
mmap, fork, and sockets. This sample is very similar to
on submitted by me on june 2, but this one eliminiates sysV ipc.
here is the sample run:
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> gcc -oforktest2 forktest2.c
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> ./forktest2
in pid = 2276
entering NetWorkSocket
Port=5210, Socket=3, sinport=23060
exiting NetWorkSocket
entering accept
[@TERMSERV]/cygdrive/c/apps/apwin1/src/forktest>
-> after accept
in pid = 6880
1963 [main] forktest2 7220 fixup_mmaps_after_fork: base address fails to matc
h requested address 0x650000
c:\apps\apwin1\src\forktest\forktest2.exe: *** recreate_mmaps_after_fork_failed
Note: you have to telnet to port 5210 to allow the program to continue.
----------------------------------------------------------------------
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
# include <unistd.h>
# include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
static int RegProcNet_sd;
static struct sockaddr_in Sin;
static const int on = 1;
int SwitchToPrivate_sd(void)
{
int NewNet_sd;
unsigned long SizeOfsockaddr_in = sizeof (struct sockaddr_in);
printf("entering accept\n");
NewNet_sd = accept(RegProcNet_sd, (struct sockaddr *)&Sin,
(size_t *)&SizeOfsockaddr_in);
printf("after accept\n");
if (NewNet_sd < 0)
{
int SaveErrNo = errno;
printf("Exiting due to error in accept %d\n", SaveErrNo);
exit(1);
}
return(NewNet_sd);
}
#define PORT_NUM 5210
void NetWorkSocket(void)
{
int SizeOfsockaddr_in = sizeof (struct sockaddr_in);
bzero((char *) &Sin, sizeof(Sin));
Sin.sin_family = AF_INET;
Sin.sin_addr.s_addr = htonl(INADDR_ANY) ;
Sin.sin_port = htons((unsigned short)PORT_NUM);
printf("entering NetWorkSocket\n");
RegProcNet_sd = socket(AF_INET, SOCK_STREAM, 0);
if (RegProcNet_sd < 0)
{
int SaveErrNo = errno;
printf("Exiting due to error in socket %d\n", SaveErrNo);
exit(1);
}
(void) setsockopt(RegProcNet_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (bind(RegProcNet_sd, (struct sockaddr *)&Sin, SizeOfsockaddr_in) < 0)
{
int SaveErrNo = errno;
printf("Exiting due to error in bind %d\n", SaveErrNo);
exit(1);
}
if (listen(RegProcNet_sd, 1) < 0)
{
int SaveErrNo = errno;
printf("Exiting due to error in listen %d\n", SaveErrNo);
exit(1);
}
{
printf("Port=%d, Socket=%d, sinport=%d\n",
PORT_NUM, RegProcNet_sd, Sin.sin_port);
}
printf("exiting NetWorkSocket\n");
return;
}
int main(int argc, char *argv[])
{
char *shmptr3;
int SaveErrno;
int sd;
if (fork())
{
printf("in pid = %d\n", getpid());
exit(0);
}
shmptr3 = mmap(0, 1024*1024, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_SHARED, -1, 0);
if (shmptr3 == (char *)-1)
{
SaveErrno = errno;
printf("mmap failed errno = %d\n", SaveErrno);
exit(1);
}
NetWorkSocket();
sd = SwitchToPrivate_sd();
fork();
printf("in pid = %d\n", getpid());
exit(0);
}
----------------------------------------------------------------------
--
Michael Potter
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -