This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

B20.1: Fork bug (Win95)


To reproduce the bug compile the appended source code:

bash$ gcc fork_test.c -o fork_test

Running fork_test with arguments "0 1" and "1 0" produces this output:

bash$ ./fork_test 0 1
parent - child_pid 1036: localhost's IP address = 127.0.0.1
child: Not owner
child - child_pid 0: localhost's IP address = 0.0.0.0
Child 1036: exited 1
bash$ ./fork_test 1 0
child - child_pid 0: localhost's IP address = 127.0.0.1
parent: Not owner
parent - child_pid 1038: localhost's IP address = 0.0.0.0
Child 1038: exited 1

This output shows that the first call of gethostbyname succeeds whereas
the second call produces the error "Not owner" (via perror - herror does
not produce an error message). It is not important if the parent or
the child is the first caller. (The first argument to fork_test
specifies a number of seconds for the parent to sleep, the second
argument a number of seconds for the child to sleep.)

The third argument allows the specification of another hostname. If the
host lookup fails the same error "Not owner" is reported via perror.

bash$ ./fork_test 0 1 bogus
parent: Not owner
parent - child_pid 1040: bogus's IP address = 0.0.0.0
child: Not owner
child - child_pid 0: bogus's IP address = 0.0.0.0
Child 1040: exited 1

The same executable run under WinNT4.0 resolves a valid
hostname both in the parent and the child process and reports "Not owner"
via perror in case of the "bogus" hostname.

The same program compiled under Linux (RedHat 5.1) behaves just like WinNT
except for reporting failure of gethostbyname via herror.

I searched the mailing list for similar bug reports and found the thread
"dll + fork", where a bug with dynamic loading was reported. I suspect
that the way cygwin1.dll implements gethostbyname is via delegation to a
windows DLL, so that this bug isn't anything new. However, it shows that
even calls to the published Cygwin API can fail in connection with fork
under Win95.

I found the bug running the perl regression tests tracking down a failure
of lib/io_sock.t (perl5.005_03 compiled statically).

Regards
Jörg Schray

# 1 "fork_test.c"
#ifndef FORK
#define FORK 1
#endif

#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <netdb.h>

int main (int argc, char *argv[], char **env) {

  char *child = "child";
  char *parent = "parent";
  char *process = NULL;

  pid_t child_pid = 0;

  char *argv3 = "localhost";
  unsigned char ip_address[4] = "\0\0\0\0";
  struct hostent * phe;

  int parent_sleep = 0;
  int child_sleep = 0;

  if (argc > 1) parent_sleep = atof(argv[1]);
  if (argc > 2) child_sleep = atof(argv[2]);
  if (argc > 3) argv3 = argv[3];

#if FORK
  child_pid = fork();
#endif

  process = (child_pid ? parent : child);

  if (FORK && child_pid && (parent_sleep > 0)) sleep(parent_sleep);
  if (FORK && !child_pid && (child_sleep > 0)) sleep(child_sleep);

  phe = gethostbyname(argv3);
  if (phe) memcpy(ip_address,phe->h_addr,4);
  if (!phe && h_errno) herror(process);
  if (!phe && errno) perror(process);

  printf("%s - child_pid %d: %s's IP address = %d.%d.%d.%d\n",
	 process, child_pid, argv3,
	 ip_address[0], ip_address[1], ip_address[2], ip_address[3]
	 );

  if (child_pid) {
    int status = 0;
    int wait_return = waitpid( child_pid, &status, 0);
    printf ("Child %d: exited %d\n",wait_return,WIFEXITED(status));
  }
  return 0;
}


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]