Re: scotty/tkined on SCO Unix

Erik Schoenfelder (schoenfr@sol)
Fri, 8 Apr 94 19:54:26 +0200

Hi!

> "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 */