sl@0: /*
sl@0: * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: * All rights reserved.
sl@0: * This component and the accompanying materials are made available
sl@0: * under the terms of "Eclipse Public License v1.0"
sl@0: * which accompanies this distribution, and is available
sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: *
sl@0: * Initial Contributors:
sl@0: * Nokia Corporation - initial contribution.
sl@0: *
sl@0: * Contributors:
sl@0: *
sl@0: * Description: connectors for re-entrant system calls
sl@0: */
sl@0: 
sl@0: 
sl@0: // connectors for re-entrant system calls
sl@0: 
sl@0: #include "sysif.h"
sl@0: #include "lposix.h"
sl@0: #include <unistd.h>
sl@0: #include <fcntl.h>		// for open()
sl@0: #include <sys/ioctl.h>
sl@0: #include <stdarg.h> 
sl@0: #include <sys/errno.h>
sl@0: #include <sys/stat.h>
sl@0: #include <utf.h>
sl@0: #include <string.h>
sl@0: #include <unistd.h>
sl@0: #include <sys/types.h>
sl@0: #include "sysreent.h"
sl@0: #include <sys/aeselect.h>
sl@0: #include "aeselectreent.h"
sl@0: #include "fdesc.h"
sl@0: #include "stdio_r.h"		// for popen3
sl@0: #include "stdlib_r.h"		// for system
sl@0: 
sl@0: #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
sl@0: #include "libc_wsd_defs.h"
sl@0: #endif
sl@0: #define	MAXPATHLEN	260	/* E32STD.H: KMaxFullName + 4 to avoid data loss */
sl@0: 
sl@0: extern "C" {
sl@0: 
sl@0: /*
sl@0: Opens the file which name is stored in the file string.
sl@0: */
sl@0: EXPORT_C int open (const char *file, int flags, ...)
sl@0: 	{
sl@0: 	va_list argList; 
sl@0: 	register int perms;
sl@0: 	
sl@0: 	if(!file) 
sl@0: 		{
sl@0:     	errno = EFAULT ;
sl@0:     	return -1 ;	//null file pointer
sl@0: 		}
sl@0: 	
sl@0: 	va_start (argList, flags);
sl@0: 	perms = va_arg(argList,int);
sl@0: 	va_end (argList);
sl@0: 
sl@0: 	//If mode is invalid
sl@0: 	if( perms  > (S_IRWXU | S_IRWXG | S_IRWXO ) )
sl@0: 		{
sl@0: 		//make it read-write for all
sl@0: 		perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
sl@0: 		}
sl@0: 	wchar_t _widename[MAXPATHLEN+1];
sl@0: 
sl@0: 	if ((size_t)-1 != mbstowcs(_widename, file, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _open_r (&errno, _widename, flags, perms);  
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		errno = EILSEQ;		
sl@0: 		return -1;	// Illegal Sequence of wide characeters
sl@0: 		}
sl@0: 
sl@0: 	}
sl@0: 
sl@0: /*
sl@0: A wide_character version of a open().
sl@0: */
sl@0: EXPORT_C int wopen (const wchar_t *file, int flags, ...)
sl@0: 	{
sl@0: 	va_list ap;
sl@0: 	int ret;
sl@0: 	register int perms;
sl@0: 	
sl@0: 	if(!file)
sl@0: 		{
sl@0:     	errno = EFAULT ;
sl@0:     	return -1 ;	
sl@0: 		}
sl@0: 		
sl@0: 	va_start (ap, flags);
sl@0: 	perms = va_arg(ap,int);
sl@0: 	va_end (ap);
sl@0: 	
sl@0: 	//If mode is invalid
sl@0: 	if( perms  > (S_IRWXU | S_IRWXG | S_IRWXO ) )
sl@0: 		{
sl@0: 		//make it read-write for all
sl@0: 		perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
sl@0: 		}
sl@0: 
sl@0: 	ret = _wopen_r (&errno, file, flags, perms);
sl@0: 	
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Reads a block of data of the length specified by cnt.
sl@0: */
sl@0: EXPORT_C int read (int fd, void *buf, size_t cnt)
sl@0: 	{
sl@0: 	if((int)cnt == 0)       
sl@0: 		{
sl@0: 			return 0 ;
sl@0: 		}	
sl@0: 	if((int)cnt < 0) 
sl@0: 		{
sl@0: 	  	errno = EINVAL ;
sl@0: 	  	return -1 ;
sl@0: 		}
sl@0: 	if(!buf)
sl@0: 	  	{
sl@0: 	  	errno = EFAULT ;
sl@0: 	  	return -1 ;
sl@0: 	  	}
sl@0: 	
sl@0: 	//If the fd corresponding to STDIN
sl@0: 	if(fd == STDIN_FILENO && (Backend()->GetDesc(STDIN_FILENO))->Attributes() == KConsoleFd) 
sl@0: 		{
sl@0: 		int len = 0;
sl@0: 		char ch = '\0';
sl@0: 		int ret = -1;
sl@0: 		do
sl@0: 			{
sl@0: 			ret = _read_r(&errno, STDIN_FILENO, &ch, 1);
sl@0: 
sl@0: 			//Copy requested count of data, ignore the rest
sl@0: 			if(ret > 0 && len < cnt )
sl@0: 				{
sl@0: 				((char*)buf)[len] = ch;
sl@0: 				len++;
sl@0: 				}
sl@0: 			else if(ret < 0)
sl@0: 				{
sl@0: 				break;
sl@0: 				}
sl@0: 			
sl@0: 			}while(ch != '\n');
sl@0: 		
sl@0: 		//Handle error case.
sl@0: 		if(ret == -1)
sl@0: 			{
sl@0: 			return ret;
sl@0: 			}
sl@0: 
sl@0: 		return len;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		return _read_r(&errno, fd, (char*)buf, cnt);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Writes a block of data of the length specified by cnt.
sl@0: */
sl@0: EXPORT_C int write (int fd, const void *buf, size_t cnt)
sl@0: 	{
sl@0: 		if((int)cnt == 0) 
sl@0: 		{
sl@0: 	   	return 0;
sl@0: 		}
sl@0: 	if((int)cnt < 0) 
sl@0: 		{
sl@0: 	   	errno = EINVAL;
sl@0: 	   	return -1;
sl@0: 		}
sl@0: 	if(!buf) 
sl@0: 	   	{
sl@0: 	   	errno = EFAULT ;
sl@0: 	   	return -1 ;
sl@0: 	   	}
sl@0: 	return _write_r(&errno, fd, (char*)buf, cnt);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Close a file.
sl@0: */
sl@0: EXPORT_C int close (int fd)
sl@0: 	{
sl@0: 	return  _close_r(&errno, fd);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /*
sl@0: Synchronizes a file's in-memory state with that on the physical medium.
sl@0: */
sl@0: EXPORT_C int fsync (int fd)
sl@0: 	{
sl@0: 	return _fsync_r(&errno, fd);
sl@0: 	}
sl@0: 
sl@0: /*
sl@0: Repositions the read/write file offset.
sl@0: */
sl@0: EXPORT_C off_t lseek (int fd, off_t pos, int whence)
sl@0: 	{
sl@0: 	return _lseek_r(&errno, fd, pos, whence);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Gets information about the named file and writes it to the area that buf points to.
sl@0: The system must be able to search all directories leading to the file; 
sl@0: however, read, write, or execute permission of the file is not required.
sl@0: */
sl@0: EXPORT_C int fstat (int fd, struct stat *st)
sl@0: 	{
sl@0: 	if(!st)
sl@0: 	   {
sl@0: 	    errno = EFAULT ;
sl@0: 	    return -1 ;	
sl@0: 	   }
sl@0: 	return _fstat_r(&errno, fd, st);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Gets the size of a file. 
sl@0: */
sl@0: EXPORT_C int stat (const char *name, struct stat *st)
sl@0: 	{
sl@0: 	if(!st)
sl@0: 	   {
sl@0: 	    errno = EFAULT ;
sl@0: 	    return -1 ;	
sl@0: 	   }
sl@0:     
sl@0:     wchar_t tmpbuf[MAXPATHLEN+1];	
sl@0: 	if ((size_t)-1 != mbstowcs(tmpbuf, name, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _stat_r(&errno, tmpbuf, st);
sl@0: 		}
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: EXPORT_C int utime (const char *name, const struct utimbuf *filetimes)
sl@0: 	{
sl@0: 	if(!name) 
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 
sl@0: 	wchar_t tmpbuf[MAXPATHLEN+1];	
sl@0: 	if ((size_t)-1 != mbstowcs(tmpbuf, name, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _utime_r (&errno, tmpbuf, filetimes);
sl@0: 		}
sl@0: 	
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /*
sl@0: A wide_character version of a stat().
sl@0: */
sl@0: EXPORT_C int wstat (const wchar_t *name, struct stat *st)
sl@0: 	{
sl@0: 			if( !name || !st )
sl@0: 			{
sl@0: 					errno = EFAULT;
sl@0: 					return -1;
sl@0: 			}
sl@0: 	return _wstat_r (&errno, name, st);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: duplicates an open file descriptor.
sl@0: */
sl@0: EXPORT_C int dup (int aFid)
sl@0: 	{
sl@0: 	return _dup_r(&errno, aFid);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: function duplicates an open file descriptor.
sl@0: */
sl@0: EXPORT_C int dup2 (int aFid1, int aFid2)
sl@0: 	{
sl@0: 	return _dup2_r(&errno, aFid1, aFid2);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: sorms a variety of device-specific control functions on device special files.
sl@0: */
sl@0: EXPORT_C int ioctl (int aFid, unsigned long aCmd, ...)
sl@0: 	{
sl@0: 	void* aParam ;
sl@0: 	va_list  Vlist ;
sl@0: 	int ret;
sl@0: 	va_start(Vlist , aCmd ) ;
sl@0: 	aParam = va_arg(Vlist , void *)  ;
sl@0: 	if(!aParam) 
sl@0: 		{
sl@0: 		errno = EFAULT ; 
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 
sl@0: 	ret = _ioctl_r(&errno, aFid, aCmd, aParam);
sl@0: 	
sl@0: 	va_end(Vlist) ;
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /*
sl@0: Gets the path name of the current working directory.
sl@0: If a buffer is specified, the path name is placed in that buffer,
sl@0: and the address of the buffer is returned.
sl@0: */
sl@0: 
sl@0: /*
sl@0: A wide_character version of a getcwd().
sl@0: */
sl@0: EXPORT_C wchar_t* wgetcwd (wchar_t *_buf, size_t _size)
sl@0: 	{
sl@0: 	return _wgetcwd_r(&errno, _buf, _size);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Changes the current working directory to be pathname. 
sl@0: The current directory is the beginning point for file 
sl@0: searches when path names are not absolute. 
sl@0: If the chdir() function fails, the current working directory remains unchanged.
sl@0: */
sl@0: EXPORT_C int chdir (const char *_path)
sl@0: 	{
sl@0: 	if(!_path) 
sl@0: 		{
sl@0: 		errno = EFAULT;
sl@0: 		return -1;
sl@0: 	  	}
sl@0: 
sl@0: 	//we need to use a wide buffer and convert
sl@0: 	wchar_t tmpbuf[MAXPATHLEN+1];		//use the max path length possible
sl@0: 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _chdir_r(&errno, tmpbuf);
sl@0: 		}
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /* A wide-character version of chdir().
sl@0: */
sl@0: EXPORT_C int wchdir (const wchar_t *_path)
sl@0: 	{
sl@0: 
sl@0: 	if(!_path) 
sl@0: 		{
sl@0: 		errno = EFAULT;
sl@0: 		return -1;
sl@0: 	  	}
sl@0: 
sl@0: 	return _wchdir_r(&errno, _path);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Removes an empty directory whose name is given by pathname.
sl@0: The directory must not have any entries other than dot (.) and dot-dot (..).
sl@0: */
sl@0: EXPORT_C int rmdir (const char *_path)
sl@0: 	{
sl@0: 	if(!_path)
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 
sl@0: 	if(!strcmp((_path + strlen(_path) -1 ) , ".") ) 
sl@0: 		{
sl@0: 		errno = EINVAL ;
sl@0: 		return -1 ;  
sl@0: 		}
sl@0: 
sl@0: 	wchar_t tmpbuf[MAXPATHLEN+1];		//use the max path length possible
sl@0: 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _rmdir_r(&errno, tmpbuf);
sl@0: 		}
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /* A wide-character version of rmdir().
sl@0: */
sl@0: EXPORT_C int wrmdir (const wchar_t *_path)
sl@0: 	{
sl@0: 			if( !_path )
sl@0: 			{
sl@0: 				 errno = EFAULT;
sl@0: 				 return -1;
sl@0: 			}
sl@0: 	return _wrmdir_r(&errno, _path);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Creates a new directory with the specified path name. 
sl@0: The file permissions of the new directory are initialized from the specified mode. 
sl@0: */
sl@0: EXPORT_C int mkdir (const char *_path, mode_t _mode)
sl@0: 	{
sl@0: 	if(!_path)
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 
sl@0: 	//we need to use a wide buffer and convert
sl@0: 	wchar_t tmpbuf[MAXPATHLEN+1];		//use the max path length possible
sl@0: 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _mkdir_r(&errno, tmpbuf, _mode);
sl@0: 		}
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /* A wide-character version of mkdir().
sl@0: */
sl@0: EXPORT_C int wmkdir (const wchar_t *_path, mode_t _mode)
sl@0: 	{
sl@0: 
sl@0: 	if(!_path)
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 	
sl@0: 	return _wmkdir_r(&errno, _path, _mode);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Sets the access permissions for the file 
sl@0: whose name is given by pathname to the bit pattern contained in mode. 
sl@0: For this call to succeed, the effective user ID of the process must match 
sl@0: the owner of the file, or the process must have appropriate privileges. 
sl@0: The owner of the file pathname always has privileges to change permission modes 
sl@0: and file attributes.
sl@0: */
sl@0: EXPORT_C int chmod (const char *_path, mode_t _mode)
sl@0: 	{
sl@0: 	if(!_path)
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 
sl@0: 	wchar_t tmpbuf[MAXPATHLEN+1];	
sl@0: 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
sl@0: 		{
sl@0: 		return _chmod_r(&errno, tmpbuf, _mode);
sl@0: 		}
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: /*
sl@0: Sets the access permissions for the file specifed by file descriptor
sl@0: whose name is given by pathname to the bit pattern contained in mode. 
sl@0: For this call to succeed, the effective user ID of the process must match 
sl@0: the owner of the file, or the process must have appropriate privileges. 
sl@0: The owner of the file pathname always has privileges to change permission modes 
sl@0: and file attributes.
sl@0: */
sl@0: EXPORT_C int fchmod (int fd , mode_t _mode)
sl@0: 	{
sl@0: 	
sl@0: 		return _fchmod_r(&errno, fd, _mode);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /* A wide-character version of chmod().
sl@0: */
sl@0: EXPORT_C int wchmod (const wchar_t *_path, mode_t _mode)
sl@0: 	{
sl@0: 	
sl@0: 	if(!_path)
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 	
sl@0: 	return _wchmod_r(&errno, _path, _mode);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /* A wide-character version of unlink().
sl@0: */
sl@0: EXPORT_C int wunlink (const wchar_t *_path)
sl@0: 	{
sl@0: 			if( !_path )
sl@0: 			{
sl@0: 					errno = EFAULT;
sl@0: 					return -1;
sl@0: 			}
sl@0: 	return _wunlink_r(&errno, _path);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Renames a file.
sl@0: */
sl@0: EXPORT_C int rename (const char *oldpath, const char *newpath)
sl@0: 	{
sl@0: 	if((!oldpath) ||(!newpath))
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 
sl@0: 	wchar_t _old[MAXPATHLEN+1];		
sl@0: 	wchar_t _new[MAXPATHLEN+1];		
sl@0: 	if ((size_t)-1 != mbstowcs(_old, oldpath, MAXPATHLEN))
sl@0: 		{
sl@0: 		if ((size_t)-1 != mbstowcs(_new, newpath, MAXPATHLEN))
sl@0: 			{
sl@0: 			return _rename_r(&errno, _old, _new);
sl@0: 			}
sl@0: 		}
sl@0: 	errno = EILSEQ;		
sl@0: 	return -1;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /* A wide-character version of rename().
sl@0: */
sl@0: EXPORT_C int wrename (const wchar_t *oldpath, const wchar_t *newpath)
sl@0: 	{
sl@0: 	
sl@0: 	if((!oldpath) ||(!newpath))
sl@0: 		{
sl@0: 		errno = EFAULT ;
sl@0: 		return -1 ;
sl@0: 		}
sl@0: 	
sl@0: 	return _wrename_r(&errno, oldpath, newpath);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Takes a specified path name, pathname and resolves all symbolic links,
sl@0: extra slashes (/), and references to /./ and /../. 
sl@0: The resulting absolute path name is placed in the memory location 
sl@0: pointed to by the resolved_path argument.
sl@0: */
sl@0: 
sl@0: /* A wide-character version of realpath().
sl@0: */
sl@0: EXPORT_C wchar_t* wrealpath (const wchar_t* path, wchar_t* resolved)
sl@0: 	{
sl@0: 	return _wrealpath_r(&errno, path, resolved);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Gives access to the client's stdin
sl@0: */
sl@0: EXPORT_C FILE* popen (const char* command, const char* mode)
sl@0: 	{
sl@0: 	// Check for the validity of command.
sl@0: 	// On Linux, the shell would return cannot find command to execute
sl@0: 	if (command == NULL)
sl@0: 		{
sl@0: 		errno = ENOENT;
sl@0: 		return NULL;
sl@0: 		}
sl@0: 		
sl@0: 	if(strlen(command) > KMaxPath)
sl@0: 		{
sl@0: 		errno = ENAMETOOLONG;
sl@0: 		return NULL;
sl@0: 		}
sl@0: 	// Check for the validity of Mode.
sl@0: 	if( (!mode) || mode[0] != 'r' && mode[0] != 'w' )
sl@0: 		{
sl@0: 		// Invalid mode
sl@0: 		errno = EINVAL;
sl@0: 		return NULL;
sl@0: 		}
sl@0: 		
sl@0: 	wchar_t wcmd[KMaxPath+1];
sl@0: 		
sl@0: 	// Widen command
sl@0: 	if ((size_t)-1 != mbstowcs(wcmd, command, KMaxPath))
sl@0: 		{
sl@0: 		int fd = _wpopen_r(&errno, wcmd, mode);
sl@0: 		if (fd > 0)
sl@0: 			{
sl@0: 			// return value is a valid fd
sl@0: 			return fdopen(fd, mode);
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		errno = EILSEQ;
sl@0: 		}
sl@0: 
sl@0: 	return NULL;
sl@0: 	}
sl@0: 	
sl@0: 	
sl@0: EXPORT_C FILE* wpopen (const wchar_t* command, const wchar_t* wmode)
sl@0: 	{
sl@0: 	char mode[2];
sl@0: 	size_t sz;
sl@0: 
sl@0: 	mode[0] = '\0';
sl@0: 	sz = wcstombs(mode, wmode, 2);
sl@0: 	//Check for the validity of Mode.
sl@0: 	if (sz <= 0 || (mode[0] != 'r' && mode[0] != 'w'))
sl@0: 		{
sl@0: 		//If its neither "r" nor "w", its undefined behavior
sl@0: 		errno = EINVAL;
sl@0: 		return NULL;
sl@0: 		}
sl@0: 
sl@0: 	if(command)
sl@0: 		{
sl@0: 		if(wcslen(command) > KMaxPath)
sl@0: 			{
sl@0: 			errno = ENAMETOOLONG;
sl@0: 			return NULL;
sl@0: 			}
sl@0: 			
sl@0: 		int fd = _wpopen_r(&errno, command, mode );
sl@0: 		//If return Value is valid fd
sl@0: 		if (fd > 0)
sl@0: 			{
sl@0: 			return fdopen(fd, mode);
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		errno = ENOENT;
sl@0: 		}
sl@0: 	return NULL;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: EXPORT_C int pclose(FILE* stream)
sl@0: 	{
sl@0: 	TInt fd;
sl@0: 	if (!stream || ((fd = fileno(stream)) == -1))
sl@0: 		{
sl@0: 		errno = EINVAL;
sl@0: 		return -1;
sl@0: 		}
sl@0: 		
sl@0: 	TInt err = _pclose_r(&errno, fd);
sl@0: 	
sl@0: 	if (err != 0)
sl@0: 		{
sl@0: 		if (errno == ECHILD)
sl@0: 			{
sl@0: 			fclose(stream);
sl@0: 			// reset errno just in case it has been modified by fclose
sl@0: 			errno = ECHILD;
sl@0: 			}
sl@0: 		
sl@0: 		return -1;
sl@0: 		}
sl@0: 		
sl@0: 	return fclose(stream);
sl@0: 	}
sl@0: 	
sl@0: /* A wide-character version of popen3().
sl@0: */
sl@0: EXPORT_C int wpopen3 (const wchar_t* file, const wchar_t* cmd, wchar_t** env, int fids[3])
sl@0: 	{
sl@0: 	if (file == NULL)
sl@0: 		{
sl@0: 		errno = ENOENT;
sl@0: 		return -1;
sl@0: 		}
sl@0: 		
sl@0: 	if(wcslen(file) > KMaxPath)
sl@0: 		{
sl@0: 		errno = ENAMETOOLONG;
sl@0: 		return -1;	
sl@0: 		}
sl@0: 		
sl@0: 	return _wpopen3_r(&errno, file, cmd, env, fids);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: EXPORT_C int popen3 (const char* file, const char* cmd, char** env, int fids[3])
sl@0: 	{
sl@0: 	if (file == NULL)
sl@0: 		{
sl@0: 		errno = ENOENT;
sl@0: 		return -1;
sl@0: 		}
sl@0: 		
sl@0: 	if(strlen(file) > KMaxPath)
sl@0: 		{
sl@0: 		errno = ENAMETOOLONG;
sl@0: 		return -1;	
sl@0: 		}
sl@0: 		
sl@0: 	wchar_t wfile[KMaxPath+1];
sl@0: 	wchar_t wcmd[KMaxPath+1];
sl@0: 	
sl@0: 	wchar_t** wenv = NULL;
sl@0: 	
sl@0: 	TInt ret = mbstowcs(wfile, file, KMaxPath);
sl@0: 	TInt cmdlen = mbstowcs(wcmd, cmd, KMaxPath);
sl@0: 	
sl@0: 	if (ret != (size_t)-1 && cmdlen != (size_t)-1)
sl@0: 		{
sl@0: 		//OK, we've widened the first 2 args
sl@0: 		//now for the environment
sl@0: 
sl@0: 		//env will be an array of char pointers with a NULL as the last one
sl@0: 		if (env)
sl@0: 			{
sl@0: 			TInt count = 0;
sl@0: 			
sl@0: 			for (; env[count]; ++count) { }
sl@0: 
sl@0: 			//coverity[alloc_fn]
sl@0: 			//coverity[assign]
sl@0: 			
sl@0: 			wenv = (wchar_t **)malloc((count+1) * sizeof(wchar_t*));
sl@0: 			if (!wenv)
sl@0: 				{
sl@0: 				errno = ENOMEM;
sl@0: 				return -1;
sl@0: 				}
sl@0: 			
sl@0: 			for (int i = 0; i < count; ++i)
sl@0: 				{
sl@0: 				int len = strlen(env[i]) + 1;
sl@0: 				wenv[i] = (wchar_t *)malloc(len * sizeof(wchar_t));
sl@0: 				if (wenv[i] == NULL)
sl@0: 					{
sl@0: 					//coverity[leave_without_push]
sl@0: 
sl@0: 					errno = ENOMEM;
sl@0: 					goto bailout;
sl@0: 					}
sl@0: 				if (mbstowcs(wenv[i], env[i], len) == (size_t)-1)
sl@0: 					{
sl@0: 					//coverity[leave_without_push]
sl@0: 					errno = EILSEQ;
sl@0: 					wenv[i+1] = NULL;
sl@0: 					goto bailout;
sl@0: 					}
sl@0: 				}
sl@0: 				
sl@0: 			wenv[count] = 0;
sl@0: 			}
sl@0: 
sl@0: 		if (cmdlen)
sl@0: 			{
sl@0: 			//coverity[leave_without_push]
sl@0: 			ret =  wpopen3(wfile, wcmd, wenv, fids);
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			//coverity[leave_without_push]
sl@0: 			ret = wpopen3(wfile, NULL, wenv, fids);
sl@0: 			}
sl@0: 			
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		errno = EILSEQ;
sl@0: 		return -1;
sl@0: 		}
sl@0: 
sl@0: bailout:
sl@0: 	if (wenv)
sl@0: 		{
sl@0: 		for (int i = 0; wenv[i]; ++i)
sl@0: 			{
sl@0: 			free(wenv[i]);
sl@0: 			}
sl@0: 		free(wenv);
sl@0: 		}
sl@0: 
sl@0: 	return ret;
sl@0: 	}
sl@0: 
sl@0: /*
sl@0: Lets the calling process obtain status information about one of its child processes.
sl@0: If status information is available for two or more child processes,
sl@0: the order in which their status is reported is unspecified.
sl@0: */
sl@0: EXPORT_C int waitpid (int pid, int* status, int options)
sl@0: 	{
sl@0: 	return _waitpid_r(&errno, pid, status, options);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /*
sl@0: Calls reentrant version of waitpid().
sl@0: */
sl@0: EXPORT_C int wait (int* status)
sl@0: 	{
sl@0: 	return _wait_r(&errno, status);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: /*
sl@0: Execute command.
sl@0: */
sl@0: 
sl@0: /* A wide-character version of a system().
sl@0: */
sl@0: EXPORT_C int wsystem (const wchar_t* cmd)
sl@0: 	{
sl@0: 	if (cmd==0)
sl@0: 		{
sl@0: 		return 1;	// special case, says that we do support system().	
sl@0: 		}
sl@0: 
sl@0: 	if(wcslen(cmd) > KMaxPath)
sl@0: 		{
sl@0: 		errno = ENAMETOOLONG;
sl@0: 		return -1;	
sl@0: 		}
sl@0: 		
sl@0: 	return _wsystem_r(&errno, cmd);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // Select() : Implementation of Select for I/O multiplexing
sl@0: // This API is used for waiting on multiple descriptors to become ready
sl@0: // Maximum timeout to wait can also be specified
sl@0: // Returns: System wide error code
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: EXPORT_C int select(int maxfd, fd_set *readfds, fd_set *writefds,
sl@0: 					fd_set *exceptfds, struct timeval *tvptr)
sl@0: 	{	
sl@0: 	return _select_r(&errno, maxfd, readfds, writefds, exceptfds, tvptr);
sl@0: 	}
sl@0: } // extern "C"
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // aselect() : Implementation of Select for asynchronous I/O multiplexing
sl@0: // This API is used for waiting on multiple descriptors to become ready
sl@0: // Maximum timeout to wait can also be specified
sl@0: // Returns: System wide error code
sl@0: // This api does not provide C Linkage
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: EXPORT_C int aselect(int maxfd, fd_set *readfds, fd_set *writefds,
sl@0: 					fd_set *exceptfds, struct timeval *tvptr,
sl@0: 					TRequestStatus* requeststatus)
sl@0: 	{	
sl@0: 	return _aselect_r(&errno, maxfd, readfds, writefds, exceptfds, tvptr, requeststatus);
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // cancelaselect() : Implementation of Select for asynchronous I/O multiplexing
sl@0: // This API is used for cancelling the aselect issued on requeststatus
sl@0: // Returns: System wide error code
sl@0: // This api does not provide C Linkage
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: EXPORT_C int cancelaselect(TRequestStatus* requeststatus)
sl@0: 	{	
sl@0: 	return _cancelaselect_r(&errno, requeststatus);
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // eselect() : Implementation of Select for I/O multiplexing
sl@0: // This API is used for waiting on multiple descriptors to become ready,
sl@0: // or for any of the TRequestStatus object in the TRequestStatus array passed
sl@0: // to be signalled
sl@0: // Maximum timeout to wait can also be specified
sl@0: // Returns: System wide error code
sl@0: // This api does not provide C Linkage
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: EXPORT_C int eselect(int maxfd, fd_set *readfds, fd_set *writefds,
sl@0: 					fd_set *exceptfds, struct timeval *tvptr, int numreqs,
sl@0: 					TRequestStatus* waitarray)
sl@0: 	{	
sl@0: 	return _eselect_r(&errno, maxfd, readfds, writefds, exceptfds, tvptr, numreqs, waitarray);
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: // fcntl() : Implementation of fcntl for supporting Non-Blocking I/O 
sl@0: // This API is used for setting a file descriptor as non-blocking
sl@0: // Returns: System wide error code
sl@0: // -----------------------------------------------------------------------------
sl@0: //
sl@0: EXPORT_C int fcntl (int aFid, int aCmd, ...)
sl@0: 	{
sl@0: 	va_list ap;
sl@0: 	va_start(ap, aCmd);
sl@0: 
sl@0: 	int ret;
sl@0: 	ret = _fcntl_r(&errno, aFid,aCmd, va_arg(ap, long)); 
sl@0: 	
sl@0:  	va_end(ap);
sl@0: 	return ret ;
sl@0: 	}
sl@0: 
sl@0: // -----------------------------------------------------------------------------
sl@0: //int setecho(int fd, unsigned int echoval)
sl@0: //
sl@0: //Sets the echo flag for this fd.
sl@0: // -----------------------------------------------------------------------------
sl@0: 
sl@0: extern "C" {
sl@0: EXPORT_C int setecho(int fd, uint8_t echoval)
sl@0: 	{
sl@0: 	return _setecho_r(&errno, fd, echoval);
sl@0: 	}
sl@0: } //extern "C"
sl@0: 
sl@0: 
sl@0: