Subject: None
To: None <netbsd-bugs@NetBSD.ORG>
From: None <robin@red-branch.MIT.EDU>
List: netbsd-bugs
Date: 03/19/1995 14:23:56
My system is NetBSD-1.0/i386 binary w/o patches. I've discovered what appears
to be a bug with regard to SOL_SOCKET options, after a call to fork(2)
has been made. The following typescript illustrates the problem, that
after a call to fork(), an fd inherited from the parent process does not
retain its SOL_SOCKET SO_TYPE. I've tried the code on Soaris System V, which
managed to find the type of the socket only in the forked image and not in the
parent ! However it worked as it should do on DYNIX.
----->----->---->
Script started on Sun Mar 19 18:23:13 1995
bash$ cat mother.c
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define IPC_PIPE(sv) (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, (sv)))
#define WARN(x) (Log("WARNING: [%s:%d] %s: %s", __FILE__, __LINE__, (x), strerror(errno)))
static void
Log(const char *fmt,...)
{
va_list ap;
char buf[2048];
va_start(ap, fmt);
/* This is NOT safe, but vsnprintf(3) is not ``ANSI C'' ! */
vsprintf(buf, fmt, ap);
va_end(ap);
fprintf(stderr, "[mother] %s\n", buf);
fflush(stderr);
}
static void
List(void)
{
register int i;
int type;
int size;
for (i = 0; i < OPEN_MAX; ++i)
if (getsockopt(i, SOL_SOCKET, SO_TYPE, &type, &size) != -1)
Log("FD: #%d, TYPE: %d, SIZE: %d", i, type, size);
}
static const int
Fork_and_exec(char *const path)
{
const pid_t child_pid = fork();
if (child_pid < 0) {
WARN("fork(2)");
return -1;
}
List();
if (child_pid == 0) {
char *const argv[] = {path, NULL};
char *const envp[] = {NULL};
if (execve(path, argv, envp) < 0) {
WARN("execve(2)");
exit(EXIT_FAILURE);
}
}
Log("CHILD FORKED: %d", child_pid);
return child_pid;
}
void
main(int argc, char *argv[])
{
int sockets[2];
if (argc != 2) {
Log("Usage: %s <path>", argv[0]);
exit(EXIT_FAILURE);
}
if (IPC_PIPE(&sockets[0]) < 0) {
WARN("socketpair(2)");
exit(EXIT_FAILURE);
}
List();
if (Fork_and_exec(argv[1]) < 0) {
exit(EXIT_FAILURE);
}
sleep(3);
exit(EXIT_SUCCESS);
}
bash$ cay t tablelist.c
#include <stdio.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
static void
List(void)
{
register int i;
int type;
int size;
for (i = 0; i < OPEN_MAX; ++i) {
printf("%d ", i);
if (getsockopt(i, SOL_SOCKET, SO_TYPE, &type, &size) != -1)
printf("[TABLELIST] FD: #%d, TYPE: %d, SIZE: %d\n", i, type, size);
}
printf("\n");
}
void
main(void)
{
printf("[TABLELIST] Searching ...\n");
List();
exit(EXIT_SUCCESS);
}
bash$ b mother tablelist
[mother] FD: #3, TYPE: 1, SIZE: 1
[mother] FD: #4, TYPE: 1, SIZE: 1
[TABLELIST] Searching ...
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
[mother] CHILD FORKED: 223
bash$ exit
Script done on Sun Mar 19 18:23:31 1995
<----<-----<----
Any ideas ?
Cheers :)
--
Robin J F Carey