genericopenlibs/openenvcore/backend/src/syscall/handlefms.cpp
changeset 31 ce057bb09d0b
child 45 4b03adbd26ca
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/backend/src/syscall/handlefms.cpp	Fri Jun 04 16:20:51 2010 +0100
@@ -0,0 +1,674 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+// connectors for re-entrant networking system calls
+
+#include <sys/errno.h>
+#include "sysreent.h"
+#include "aeselectreent.h"
+#include <unistd.h>
+#include <fcntl.h>		// for open()
+#include <sys/ioctl.h>
+#include <stdarg.h> 
+#include <utf.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <spawn.h>
+#include <charconv.h>
+#include "sys/stat.h"
+#include <wchar.h>
+#include "systemspecialfilercg.h"
+#include "link.h"
+#include "errno.h"
+
+#include "sysif.h"
+#include "lposix.h"
+
+
+
+#define	MAXPATHLEN	256	/* E32STD.H: KMaxFullName */
+
+TInt __EPOC32_WDIR::UpdateNarrow()
+	{
+	return -1;		//this is not supported.
+	}
+	
+TInt __EPOC32_DIR::UpdateNarrow()
+	{
+	//update the narrow one
+	
+	TInt ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(iCurrentNarrowName, iCurrentName);
+	if (ret >= 0)
+		{
+		iCurrentNarrow.d_namlen=(short)iCurrentNarrowName.Length();
+		memcpy(iCurrentNarrow.d_name,iCurrentNarrowName.PtrZ(),iCurrentNarrowName.Length() + 1);
+		}
+	return ret;
+	}
+
+__EPOC32_WDIR::~__EPOC32_WDIR()
+	{
+	delete iPath;
+	delete iEntries;
+	}
+
+TInt __EPOC32_WDIR::Open(const wchar_t* _path,int* aErrno)
+	{
+	TParse name;
+	TInt err = Backend()->ResolvePath(name,_path,NULL);
+	if (!err)
+		err = Open(name.DriveAndPath());
+	if (err)
+		MapError(err,*aErrno);
+	return err;
+	}
+
+TInt __EPOC32_WDIR::Open(const TDesC& aPath)
+	{
+	delete iPath;
+	iPath=aPath.Alloc();		//allocate space for a hbufc and initialise it to the TDesC contents
+	return Open();
+	}
+
+TInt __EPOC32_WDIR::Open()
+	{
+	delete iEntries;
+	iEntries=0;
+	iIndex = 0;
+	iCount = 0 ;
+	if (iPath==0)
+		{
+		return ENOMEM;
+		}
+		
+	RFs& session = Backend()->FileSession();
+	TInt err=session.GetDir(*iPath,KEntryAttMaskSupported,ESortByName+EDescending,iEntries);
+		
+	if (!err) 
+		{
+		// iCount is actually a Last Index, not the number of entries!
+		iCount = iEntries->Count()-1;
+		iIndex = 0;
+		}
+	return err;
+	}
+
+extern "C" {
+
+/* A reentrant version of open() */
+EXPORT_C int _open_r (int *aErrno, const wchar_t *name, int mode, int perms)
+	{	
+	return Backend()->open(name, mode, perms, *aErrno);
+	}
+
+/*A reentrant version of wopen() */
+EXPORT_C int _wopen_r (int *aErrno, const wchar_t *name, int mode, int perms)
+	{
+	return Backend()->open(name, mode, perms, *aErrno);
+	}
+
+/* A reentrant version of read()*/
+EXPORT_C int _read_r (int *aErrno, int fd, char *buf, size_t nbyte)
+	{
+	return Backend()->read(fd, buf, nbyte, *aErrno);
+	}
+
+
+/* A reentrant version of write()*/
+EXPORT_C int _write_r (int *aErrno, int fd, const char *buf, size_t nbyte)
+	{
+	return Backend()->write(fd, buf, nbyte, *aErrno);
+	}
+
+
+/* A reentrant version of close()*/
+EXPORT_C int _close_r (int *aErrno, int fd)
+	{
+	return Backend()->close(fd, *aErrno);
+	}
+
+/* A reentrant version of fsync()*/
+EXPORT_C int _fsync_r (int *aErrno, int fd)
+	{
+	return Backend()->fsync(fd, *aErrno);
+	}
+
+/*A reentrant version of fseek()*/
+EXPORT_C off_t _lseek_r (int *aErrno, int fd, off_t pos, int whence)
+	{
+	return Backend()->lseek(fd, pos, whence, *aErrno);
+	}
+
+
+/* A reentrant version of fstat()*/
+EXPORT_C int _fstat_r (int *aErrno, int fd, struct stat *st) 
+	{
+	return Backend()->fstat(fd, st, *aErrno);
+	}
+
+/* A reentrant version of stat().
+*/
+EXPORT_C int _stat_r (int *aErrno, const wchar_t *name, struct stat *st) 
+	{
+	return Backend()->stat(name, st, *aErrno);
+	}
+	
+/* A reentrant version of lstat().
+*/
+EXPORT_C int _lstat_r (int *aErrno, const wchar_t *name, struct stat *st) 
+    {
+    return Backend()->lstat(name, st, *aErrno);
+    }
+
+EXPORT_C int _utime_r (int *aErrno, const wchar_t *name,const  struct utimbuf *filetimes) 
+	{
+	return Backend()->utime(name, filetimes, *aErrno);
+	}
+
+
+/* A reentrant version of wstat().
+*/
+EXPORT_C int _wstat_r (int *aErrno, const wchar_t *name, struct stat *st) 
+	{
+	return Backend()->stat(name, st, *aErrno);
+	}
+
+/* A reentrant version of dup().
+*/
+EXPORT_C int _dup_r (int *aErrno, int aFid)
+	{
+	return Backend()->dup(aFid, *aErrno);
+	}
+
+/* A reentrant version of dup2().
+*/
+EXPORT_C int _dup2_r (int *aErrno, int aFid1, int aFid2)
+	{
+	return Backend()->dup2(aFid1, aFid2, *aErrno);
+	}
+
+/* A reentrant version of ioctl().
+*/
+EXPORT_C int _ioctl_r (int *aErrno, int aFid, int aCmd, void* aParam)
+	{
+	return Backend()->ioctl(aFid, aCmd, aParam, *aErrno);
+	}
+
+/* A wide-character version of reentrant of getcwd().
+*/
+EXPORT_C wchar_t * _wgetcwd_r (int *aErrno, wchar_t *_buf, size_t _size)
+	{
+	if (_buf==0)
+		{
+		_buf=(wchar_t *)User::Alloc(_size*sizeof(wchar_t));
+		if (_buf==0)
+			{
+			*aErrno=ENOMEM;
+			return _buf;
+			}
+		}
+	return Backend()->getcwd(_buf, _size, *aErrno);
+	}
+
+/* A reentrant version of chdir().
+*/
+EXPORT_C int _chdir_r (int *aErrno, const wchar_t *_path)
+	{
+	return Backend()->chdir(_path, *aErrno);
+	}
+
+/* A reentrant version of wchdir().
+*/
+EXPORT_C int _wchdir_r (int *aErrno, const wchar_t *_path)
+	{
+	return Backend()->chdir(_path, *aErrno);
+	}
+
+/* A reentrant version of rmdir().
+*/
+EXPORT_C int _rmdir_r (int *aErrno, const wchar_t *_path)
+	{
+	 return Backend()->rmdir(_path, *aErrno);
+	}
+
+
+/* A reentrant version of wrmdir().
+*/
+EXPORT_C int _wrmdir_r (int *aErrno, const wchar_t *_path)
+	{
+	return Backend()->rmdir(_path, *aErrno);
+	}
+
+
+/* A reentrant version of mkdir().
+*/
+EXPORT_C int _mkdir_r (int *aErrno, const wchar_t *_path, mode_t _mode)
+	{
+	return Backend()->mkdir(_path, _mode, *aErrno);
+	}
+
+/* A reentrant version of wmkdir().
+*/
+EXPORT_C int _wmkdir_r (int *aErrno, const wchar_t *_path, mode_t _mode)
+	{
+	return Backend()->mkdir(_path, _mode, *aErrno);
+	}
+
+
+/* A reentrant version of chmod().
+*/
+EXPORT_C int _chmod_r (int *aErrno, const wchar_t *_path, mode_t _mode)
+	{
+	return Backend()->chmod(_path, _mode, *aErrno);
+	}
+
+/* A reentrant version of chmod().
+*/
+EXPORT_C int _fchmod_r (int *aErrno, int _fd , mode_t _mode)
+	{
+	return Backend()->fchmod(_fd, _mode, *aErrno);
+	}
+/* A reentrant version of wchmod().
+*/
+EXPORT_C int _wchmod_r (int *aErrno, const wchar_t *_path, mode_t _mode)
+	{
+	return Backend()->chmod(_path, _mode, *aErrno);
+	}
+
+/* A wide-character version of reentrant of unlink().
+*/
+EXPORT_C int _wunlink_r (int *aErrno, const wchar_t *_path)
+	{
+	return Backend()->unlink(_path, *aErrno);
+	}
+
+
+/* A reentrant version of rename().
+*/
+EXPORT_C int _rename_r (int *aErrno, const wchar_t *oldpath, const wchar_t *newpath)
+	{
+	return Backend()->rename(oldpath, newpath, *aErrno);
+	}
+
+
+/* A wide-character version of reentrant of rename().
+*/
+EXPORT_C int _wrename_r (int *aErrno, const wchar_t *oldpath, const wchar_t *newpath)
+	{
+	return Backend()->rename(oldpath, newpath, *aErrno);
+	}
+
+/* A wide-character version of reentrant of realpath().
+*/
+EXPORT_C wchar_t * _wrealpath_r (int *aErrno, const wchar_t *relpath, wchar_t *resolved)
+	{
+		if(relpath == NULL || resolved == NULL)   //invalid arguments
+			{
+				*aErrno = EFAULT;
+				return (NULL);
+			}
+	TPtr16 name((TText16*)resolved,MAXPATHLEN);
+	TParse path;
+	TInt err = Backend()->ResolvePath(path, relpath, &name);
+	if (!err)
+		{
+		err = path.SetNoWild(path.DriveAndPath(),NULL,&name);
+		if (!err)
+			{
+			name = path.FullName();
+			name.ZeroTerminate();
+			return resolved;
+			}
+		}
+	MapError(err, *aErrno);
+	return 0;
+	}
+
+LOCAL_C TInt _parseCmd (const wchar_t* command, wchar_t* exepath, TDes& buf)
+	{
+	TLex lexer((TText*)command);
+	buf = lexer.NextToken();
+	WcsCpy(exepath,(wchar_t*)buf.PtrZ());
+
+	lexer.SkipSpace();
+	if (!lexer.Eos())
+		{
+		buf = lexer.Remainder();
+		buf.TrimRight();
+		}
+	return KErrNone;
+	}
+
+EXPORT_C int _wpopen_r (int* aErrno, const wchar_t* command, const char* mode)
+	{
+	wchar_t exepath[KMaxPath+1];
+	TFileName buf;
+
+	if (_parseCmd(command, exepath, buf) == KErrNotFound)
+		{
+		// no such file
+		*aErrno = ENOENT;
+		return -1;
+		}
+		
+	return Backend()->popen(exepath, (wchar_t*)buf.PtrZ(), mode, *aErrno);
+	}
+
+EXPORT_C int _pclose_r(int* aErrno, int aFid)
+	{
+	return Backend()->pclose(aFid, *aErrno);
+	}
+
+/* A wide-character version of reentrant of popen3().
+*/
+EXPORT_C int _wpopen3_r (int* aErrno, const wchar_t* file, const wchar_t* cmd, 
+						 wchar_t** envp, int fids[3])
+	{
+			
+	wchar_t* cmdargs = NULL;
+	if (cmd)
+		{
+		TFileName buf = (TText*)cmd;
+		buf.Trim();
+		cmdargs = (wchar_t*)buf.PtrZ();
+		}
+
+	return Backend()->popen3(file, cmdargs, envp, fids, *aErrno);
+	}
+
+
+/* A reentrant version of waitpid().
+*/
+EXPORT_C int _waitpid_r (int *aErrno, int pid, int* status, int options)
+	{
+	return Backend()->waitpid(pid, status, options, *aErrno);
+	}
+
+
+/* A reentrant version of wait().
+*/
+EXPORT_C int _wait_r (int *aErrno, int* status)
+	{
+	return _waitpid_r(aErrno, -1, status, 0);
+	}
+
+
+/* A wide-character version of reentrant of system().
+*/
+EXPORT_C int _wsystem_r (int *aErrno, const wchar_t* command)
+	{
+	wchar_t exepath[KMaxPath+1];
+	TFileName buf;		
+	
+	if (NULL == command)
+		{
+		return 1;	// special case, says that we do support wsystem().
+		}		
+		
+	if (_parseCmd(command, (wchar_t*)exepath, buf) == KErrNotFound)
+		{
+		// no such file
+		*aErrno = ENOENT;
+		return -1;
+		}
+	
+	return Backend()->system(exepath, (wchar_t*)buf.PtrZ(), *aErrno);
+	}
+
+
+/* A reentrant version of select().
+*/
+EXPORT_C int _select_r(int *aErrno, int maxfd, fd_set *readfds, fd_set *writefds,
+					   fd_set *exceptfds, struct timeval *tvptr)
+	{
+	return Backend()->select(maxfd, readfds, writefds, exceptfds, tvptr, *aErrno);
+	}	
+
+
+EXPORT_C int _fchdir_r(int *aErrno, int filedesc)
+	{
+	struct stat st;
+	
+	if(_fstat_r(aErrno, filedesc, &st)!=0)
+		{
+		*aErrno  = EBADF ;//Not an open file descriptor
+		return -1;
+		}
+	else 
+		{
+		if (!(S_ISDIR(st.st_mode)))
+			{
+			*aErrno = ENOTDIR ; //Not a directory
+			return -1;
+			}
+		}
+		
+	const wchar_t* dirName(NULL) ;
+	dirName = Backend()->GetDirName (filedesc);
+
+	if( dirName )
+		{
+		return Backend()->chdir(dirName, *aErrno);
+		}
+	else
+		{
+		//fildesc does not refer to a valid fd.
+		*aErrno = ENOTDIR;
+		return -1;
+		}
+	}
+
+
+/*
+Gets the path name of the current working directory.
+If a buffer is specified, the path name is placed in that buffer,
+and the address of the buffer is returned. 
+@return If successful returns buf, if a non-null pointer was specified, 
+or the address of the allocated memory otherwise.
+@param anErrno Ref to the error no. 
+@param _buf Points to the buffer to copy the current working directory to, 
+or NULL if getcwd() should allocate the buffer.
+@param _size Is the size, in bytes, of the array of characters that buf points to.
+*/
+/* A reentrant version of getcwd()*/
+EXPORT_C wchar_t * _getcwd_r (int *aErrno, wchar_t *_buf, size_t _size)
+	{
+	return Backend()->getcwd(_buf, _size, *aErrno);
+	}
+
+// -----------------------------------------------------------------------------
+// Function name: link
+// Description: Provides link functionality.
+// Returns:  0    : On success
+//          -1    : On error
+// In case of error, errno value set
+// Remark: This is a simulated functionality and not supported by the platform     
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C int _link_r(int *aErrno, const wchar_t *_oldwidename, const wchar_t *_newwidename)
+	{
+   	return Backend()->link(_oldwidename, _newwidename, *aErrno);					            
+	}
+
+
+// -----------------------------------------------------------------------------
+// Function name: unlink
+// Description: Provides unlink functionality.
+// Returns:  0    : On success
+//          -1    : On error
+// In case of error, errno value set
+//      
+// -----------------------------------------------------------------------------
+//
+
+EXPORT_C int _unlink_r(int *aErrno, const wchar_t *_pathwidename)
+	{
+	return Backend()->unlink(_pathwidename, *aErrno);				            
+	}
+
+   
+EXPORT_C int _posix_spawn_r(pid_t* pid, const wchar_t* wpath, 
+							const posix_spawn_file_actions_t* file_actions,
+							const posix_spawnattr_t* attrp,
+							const wchar_t* wargs, 
+							wchar_t** wenvp)
+	{
+	return Backend()->posix_spawn(pid, wpath, file_actions, attrp, wargs, wenvp);
+	}
+	
+// -----------------------------------------------------------------------------
+// Function name: exit
+// Description: Provides exit functionality.
+// In case of error, errno value set
+//      
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void _exit_r(int code)
+	{
+	return Backend()->Exit(code);
+	}
+
+// -----------------------------------------------------------------------------
+// _fcntl_r() : A reentrant version of fcntl().
+// This API is used for setting a file descriptor as non-blocking
+// Returns: System wide error code
+// -----------------------------------------------------------------------------
+//
+EXPORT_C int _fcntl_r (int *aErrno, int aFid, int aCmd, long anArg)
+	{
+	return Backend()->fcntl(aFid, aCmd, anArg, *aErrno);
+	}
+	
+//
+EXPORT_C DIR* _opendir_r (int* aErrno, const wchar_t* _path)
+	{
+	 __EPOC32_DIR* dp = new __EPOC32_DIR();
+	if (!dp ||(Backend()->AddToDirList((DIR*)dp) != KErrNone))
+		{
+		*aErrno = ENOENT;
+		return 0;
+		}
+	TInt err = dp->Open(_path,aErrno);
+	if (err)
+		{
+		Backend()->RemoveDirFromList((DIR*)dp);
+		delete dp;
+		return 0;
+		}
+		
+	return (DIR *)dp;
+	}
+
+//
+EXPORT_C int _wclosedir_r(int* aErrno, WDIR* dp)
+	{
+	if(Backend()->RemoveDirFromList((DIR*)dp) == KErrNotFound)
+		{
+		*aErrno = EBADF;	
+		}
+	delete dp;
+	return 0;
+	}
+
+// 
+
+EXPORT_C struct dirent* _readdir_r (int* aErrno, DIR *dp)
+    {
+	__EPOC32_DIR *Dp  = (__EPOC32_DIR *)dp ;
+	
+	if(!dp || Backend()->FindInDirList((DIR*)dp) == KErrNotFound )
+		{
+		*aErrno = EBADF;
+		return 0;	
+		}
+	if (_wreaddir_r(Dp))
+		{
+		if (Dp->UpdateNarrow()>=0)
+			{
+			return &Dp->iCurrentNarrow;	
+			}
+		else
+			{
+			*aErrno = EINVAL;
+			}
+		}
+	return 0;
+	}
+
+EXPORT_C struct wdirent* _wreaddir_r(WDIR *dp)
+	{
+	struct wdirent *ep=&dp->iCurrent;
+	if ((dp->iIndex < 0) ||  (dp->iIndex > dp->iCount ))
+		return  (wdirent *) NULL;
+	
+	const TEntry& entry=(*dp->iEntries)[(dp->iIndex)++];
+	// in practice, these files must have been created as "X:\something", so they
+	// can't really be longer than KMaxFileName-3
+	dp->iCurrentName.Copy(entry.iName);
+	dp->iCurrentName.ZeroTerminate();
+	ep->d_namlen=(short)dp->iCurrentName.Length();
+	ep->d_name=(wchar_t*)dp->iCurrentName.PtrZ();
+	return ep;
+	}
+
+EXPORT_C void _wrewinddir_r(WDIR *dp)
+	{
+	if (dp==0)
+		return;
+	(void) dp->Open();	// POSIX doesn't allow for rewind failing
+	}
+	
+// -----------------------------------------------------------------------------
+//int _setecho_r(int *aErrno, int aFd, size_t aEchoVal)
+//
+//Sets the echo flag for this fd.
+// -----------------------------------------------------------------------------
+
+EXPORT_C int _setecho_r(int *aErrno, int aFd, uint8_t aEchoVal)
+	{
+	return Backend()->SetEcho(aFd, aEchoVal, *aErrno);
+	}
+	
+} //extern "C" end
+
+// These functions should be out of extern "C"
+/* A reentrant version of aselect().
+*/
+EXPORT_C int _aselect_r(int *aErrno, int maxfd, fd_set *readfds, fd_set *writefds, 
+						fd_set *exceptfds, struct timeval *tvptr,
+						TRequestStatus* requeststatus)
+	{
+	return Backend()->aselect(maxfd, readfds, writefds, exceptfds, tvptr,requeststatus, *aErrno);
+	}	
+
+/* A reentrant version of cancelaselect().
+*/
+EXPORT_C int _cancelaselect_r(int *aErrno, TRequestStatus* requeststatus)
+	{
+	return Backend()->cancelaselect(requeststatus, *aErrno);
+	}	
+
+/* A reentrant version of eselect().
+*/
+EXPORT_C int _eselect_r(int *aErrno, int maxfd, fd_set *readfds, fd_set *writefds,
+						fd_set *exceptfds, struct timeval *tvptr, int numreqs,
+						TRequestStatus* waitarray)
+	{
+	return Backend()->eselect(maxfd, readfds, writefds, exceptfds, tvptr,numreqs, waitarray,*aErrno);
+	}
+