/*
 *
 * Copyright 1998-1999, University of Notre Dame.
 * Authors: Jeffrey M. Squyres, Kinis L. Meyer with M. D. McNally 
 *          and Andrew Lumsdaine
 *
 * This file is part of the Notre Dame LAM implementation of MPI.
 *
 * You should have received a copy of the License Agreement for the
 * Notre Dame LAM implementation of MPI along with the software; see
 * the file LICENSE.  If not, contact Office of Research, University
 * of Notre Dame, Notre Dame, IN 46556.
 *
 * Permission to modify the code and to distribute modified code is
 * granted, provided the text of this NOTICE is retained, a notice that
 * the code was modified is included with the above COPYRIGHT NOTICE and
 * with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
 * file is distributed with the modified code.
 *
 * LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
 * By way of example, but not limitation, Licensor MAKES NO
 * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
 * PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
 * OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
 * OR OTHER RIGHTS.  
 *
 * Additional copyrights may follow.
 *
 *	Ohio Trollius
 *	Copyright 1996 The Ohio State University
 *	NJN
 *
 *	$Id: lioattach.c,v 6.5 1999/07/28 00:31:47 jsquyres Exp $
 *
 *	Function:	- attach stream to io daemon
 *	Accepts:	- stream
 *			- remote IO node
 *			- remote LAM file descriptor
 *			- buffering mode (one of _IOFBF, _IOLBF or _IONBF)
 *	Returns:	- 0 or LAMERROR
 */

#include <lam_config.h>
#include <sfh.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "terror.h"
#include "typical.h"
#include "t_types.h"

/*
 * external functions
 */
extern char		*iosockname();
extern int		mwrite();
extern int		sfh_sock_open_clt_unix_stm();


int
liosattach(stream, node, tfd, buffering)

FILE			*stream;
int4			node;
int4			tfd;
int			buffering;

{
	int		iofd;			/* socket to IO daemon */
	char		*iosock;		/* IO daemon server sock name */
	int4		data[3];		/* forwarding info */
/*
 * Create a socket connected to IO daemon.
 */
	iosock = iosockname();
	if (iosock == 0) return(LAMERROR);

	iofd = sfh_sock_open_clt_unix_stm(iosock);
	free(iosock);
	if (iofd < 0) return(LAMERROR);
/*
 * Pass forwarding information to IO daemon.
 */
	data[0] = node;
	data[1] = tfd;
	data[2] = 0;

	if (mwrite(iofd, (char *) data, sizeof(data)) != sizeof(data)) {
		close(iofd);
		return(LAMERROR);
	}
/*
 * Redirect the stream to the socket to IO daemon and set the 
 * line buffering discipline.
 */
	if (freopen("/dev/null", "a", stream) == NULL) {
		close(iofd);
		return(LAMERROR);
	}

	if (setvbuf(stream, NULL, buffering, BUFSIZ)) {
		return(LAMERROR);
	}

	if (dup2(iofd, fileno(stream)) < 0) {
		close(iofd);
		return(LAMERROR);
	}

	return(0);
}

#if (LAM_HAVE_BSD44_FD_PASSING || LAM_HAVE_BSD43_FD_PASSING || LAM_HAVE_SYSV_FD_PASSING)

int
liofdattach(int fd, int4 node, int4 tfd)
{
	int		iofd;			/* socket to IO daemon */
	char		*iosock;		/* IO daemon server sock name */
	int4		data[3];		/* forwarding info */
/*
 * Create a socket connected to IO daemon.
 */
	iosock = iosockname();
	if (iosock == 0) return(LAMERROR);

	iofd = sfh_sock_open_clt_unix_stm(iosock);
	free(iosock);
	if (iofd < 0) return(LAMERROR);
/*
 * Pass forwarding information to IO daemon.
 */
	data[0] = node;
	data[1] = tfd;
	data[2] = 1;

	if (mwrite(iofd, (char *) data, sizeof(data)) != sizeof(data)) {
		close(iofd);
		return(LAMERROR);
	}

	if (sfh_send_fd(iofd, fd)) {
		close(iofd);
		return(LAMERROR);
	}

	close(iofd);
	return(0);
}

#else

int
liofdattach(int fd, int4 node, int4 tfd)
{
    errno = ENOPFDSUPPORT;
    return(LAMERROR);
}

#endif
