/***
*setmode.c - set file translation mode
*
*	Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*	defined _setmode() - set file translation mode of a file
*
*Revision History:
*	08-16-84  RN	initial version
*	10-29-87  JCR	Multi-thread support
*	12-11-87  JCR	Added "_LOAD_DS" to declaration
*	05-25-88  PHG	Merged DLL and normal versions
*	03-13-90  GJF	Made calling type _CALLTYPE1, added #include
*			<cruntime.h>, removed #include <register.h> and
*			fixed the copyright. Also, cleaned up the formatting
*			a bit.
*	04-04-90  GJF	Added #include <io.h>.
*	10-01-90  GJF	New-style function declarators.
*	12-04-90  GJF	Appended Win32 version onto the source with #ifdef-s.
*			Two versions should be merged together, the differences
*			are trivial.
*	12-06-90  SRW	Changed to use _osfile and _osfhnd instead of _osfinfo
*	01-17-91  GJF	ANSI naming.
*	02-13-92  GJF	Replaced _nfile by _nhandle for Win32.
*
*******************************************************************************/

#include <cruntime.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <errno.h>
#include <msdos.h>
#include <os2dll.h>
#include <stddef.h>
#include <internal.h>

/***
*int _setmode(fh, mode) - set file translation mode
*
*Purpose:
*	changes file mode to text/binary, depending on mode arg. this affects
*	whether read's and write's on the file translate between CRLF and LF
*	or is untranslated
*
*Entry:
*	int fh - file handle to change mode on
*	int mode - file translation mode (one of O_TEXT and O_BINARY)
*
*Exit:
*	returns old file translation mode
*	returns -1 and sets errno if fails
*
*Exceptions:
*
*******************************************************************************/

#ifdef MTHREAD	/* multi-thread code calls _lk_setmode() */

int _CALLTYPE1 _setmode (
	int fh,
	int mode
	)
{
	int retval;
#ifdef	_WIN32_
	if ( (unsigned)fh >= (unsigned)_nhandle ) {
#else
	if (fh < 0 || fh >= _nfile) {
#endif
		errno = EBADF;
		return(-1);
	}

	/* lock the file */
	_lock_fh(fh);

	/* set the text/binary mode */
	retval = _setmode_lk(fh, mode);

	/* unlock the file */
	_unlock_fh(fh);

	/* Return to user (_setmode_lk sets errno, if needed) */
	return(retval);

}

/***
*_setmode_lk() - Perform core setmode operation
*
*Purpose:
*	Core setmode code.  Assumes:
*	(1) Caller has validated fh to make sure it's in range.
*	(2) Caller has locked the file handle.
*
*	[See _setmode() description above.]
*
*Entry: [Same as _setmode()]
*
*Exit:	[Same as _setmode()]
*
*Exceptions:
*
*******************************************************************************/

int _CALLTYPE1 _setmode_lk (
	REG1 int fh,
	int mode
	)
{
	int oldmode;

#else	/* non multi-thread code */

int _CALLTYPE1 _setmode (
	REG1 int fh,
	int mode
	)
{
	int oldmode;

#ifdef	_WIN32_
	if ( (unsigned)fh >= (unsigned)_nhandle ) {
#else
	if (fh < 0 || fh >= _nfile) {
#endif
		errno = EBADF;
		return(-1);
	}

#endif	/* now join common code */

	if (!(_osfile[fh] & FOPEN)) {
		errno = EBADF;
		return(-1);
	}

	else {
		oldmode = _osfile[fh] & FTEXT;

		if (mode == _O_BINARY)
			_osfile[fh] &= ~FTEXT;
		else if (mode == _O_TEXT)
			_osfile[fh] |= FTEXT;
		else	{
			errno = EINVAL;
			return(-1);
		}
	}

	return(oldmode ? _O_TEXT : _O_BINARY);

}
