diff -r 000000000000 -r e4d67989cc36 genericopenlibs/openenvcore/backend/src/syscall/handlefms.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/openenvcore/backend/src/syscall/handlefms.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,667 @@ +/* +* 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 +#include "sysreent.h" +#include "aeselectreent.h" +#include +#include // for open() +#include +#include +#include +#include +#include +#include +#include +#include "sys/stat.h" +#include +#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); + } + +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); + } +