> "S. Kent Hamilton" <kenth@scssa.ops.scscom.com>:
SKH> This is a problem on SCO (and many other Intel Unix's) they don't have
SKH> socketpair. They don't have unix sockets. Most of the stuff is done
SKH> via named pipes, or SysV ipc.
*Smile* Time to take a look at Linux. A intel box with socketpairs ;-)
> Maybe a workaroud would be a socketpair() replacement which creates
> two inet domain sockets, bound to diffrent ports, connects them via
> accept/connect and uses this connection after a fork. But i am not
> sure, if this would be usable.
SKH> This is what I had in mind trying. I've never tried it before
SKH> but I can't see why it wouldn't work. If you have suggestions
SKH> for implimenting it please send 'em along, I'm a sysadmin not
SKH> a coder.... :-)
Well, maybe the sysadmins are the better coders ? The users are ever
playing and never hacking... ;-)
Anyway, please try the ``inet_socketpair()'' function below as a
replacement with AF_INET domain parameter. Maybe its the shot that
hits the spot.
It seems to work with SunOS 4.1.x and Linux 1.0.
Thanks, Erik
--- /* * socketpair-example3.c: April 1994 * (schoenfr) * * simple socketpair replacement for AF_INET domain. */#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <errno.h>
/* #define TEST_STANDALONE /* define for a test version */
/* * use * inet_socketpair (AF_INET, SOCK_STREAM, 0, xv) * as * socketpair (AF_UNIX, SOCK_STREAM, 0, xv) * replacement. */
static int inet_socketpair (d, type, protocol, sv) int d, type, protocol; int sv[2]; { struct sockaddr_in addr1, addr2, addr3; int addr3_len = sizeof (addr3); int fd, rc; static int port_no = 2345; /* XXX: ok ? */
if (d != AF_INET || type != SOCK_STREAM || protocol) { fprintf (stderr, "** bad param in inet_socketpair.\n"); return -1; }
if ((sv [0] = socket (AF_INET, SOCK_STREAM, 0)) < 0 || (sv [1] = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("** cannot create sockets; reason"); return -1; }
addr1.sin_port = htons (port_no); addr1.sin_family = AF_INET; addr1.sin_addr.s_addr = 0;
while ((rc = bind (sv[0], (struct sockaddr *) &addr1, sizeof (addr1))) < 0 && errno == EADDRINUSE) addr1.sin_port = htons (++port_no);
if (rc < 0) { perror ("** cannot bind; reason"); return -1; } if (listen (sv[0], 1) < 0) { perror ("** cannot listen; reason"); return -1; }
addr2.sin_port = htons (port_no); addr2.sin_family = AF_INET; addr2.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
if (connect (sv[1], (struct sockaddr *) &addr2, sizeof (addr2)) < 0) { perror ("** cannot connect; reason"); return -1; } if ((fd = accept (sv[0], (struct sockaddr *) &addr3, &addr3_len)) < 0) { perror ("** cannot accept; reason"); return -1; }
if (close (sv[0]) < 0) { perror ("** cannot close; reason"); return -1; }
sv[0] = fd;
/** printf ("* returning sv[0]=%d sv[1]=%d\n", sv[0], sv[1]); **/
/* okey dokey mom */ return 0; }
#ifdef TEST_STANDALONE
/* * simple test; compile with cc socketpair-example3.c * run as ./a.out * and expect a * ** got reply `hi nase\n''... * as reply (with the newline done). */
/* resolver tasks socketpair: */ static int xv [2];
static void run_child (cmd) char *cmd; { int child;
#if 1 if (inet_socketpair (AF_INET, SOCK_STREAM, 0, xv) < 0) #else if (socketpair (AF_UNIX, SOCK_STREAM, 0, xv) < 0) #endif { fprintf (stderr, "cannot create fake socketpair\n"); exit (1); } child = fork (); if (child < 0) { perror ("cannot for a child; reason"); exit (0); } if (child) { close (xv [0]); dup2 (xv [1], 0); dup2 (xv [1], 1); execl ("/bin/sh", "sh", "-c", cmd, (char *) 0); perror ("cannot execute child; reason"); exit (1); } else { close (xv [1]); } }
static void run_cmd (str) char *str; { char tmp [128]; int i, n; if (strlen (str) != write (xv [0], str, strlen (str))) { perror ("cannot write message to child; reason"); exit (1); } n = read (xv [0], tmp, 128); if (n < 0) { perror ("cannot read message from child; reason"); exit (1); } printf ("** got reply `"); for (i = 0; i < n; i++) putchar (tmp [i]); printf ("'...\n"); }
main () { /* hopefully the command does unbuffered io ;-) */ run_child ("/bin/cat"); run_cmd ("hi nase\n"); }
#endif /* TEST_STANDALONE */
/* end if socketpair-example3.c */