sl@0: // Copyright (c) 1999-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: sl@0: // sl@0: sl@0: #include "SYSIF.H" sl@0: #include "FDESC.H" sl@0: #include "LTIME.H" sl@0: #include "LPOSIX.H" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // System Interface for thread-local form of STDLIB sl@0: sl@0: /** sl@0: Two-phase constructor method to create a CLocalSystemInterface instance. sl@0: */ sl@0: CLocalSystemInterface* CLocalSystemInterface::NewL() sl@0: { sl@0: CLocalSystemInterface* self = new (ELeave) CLocalSystemInterface(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: Constructor. sl@0: */ sl@0: CLocalSystemInterface::CLocalSystemInterface() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Second-phase constructor. sl@0: Initialises some data members. sl@0: This function leaves if any system-wide error happens. sl@0: */ sl@0: void CLocalSystemInterface::ConstructL() sl@0: { sl@0: iFids.InitL(); sl@0: sl@0: CTtyDesc* console=new CTtyDesc; sl@0: User::LeaveIfNull(console); sl@0: sl@0: iFids.Default(console); sl@0: console->Close(); sl@0: sl@0: User::LeaveIfError(iFs.Connect()); sl@0: User::LeaveIfError(PosixFilesystem::SetDefaultDir(iFs)); sl@0: } sl@0: sl@0: CLocalSystemInterface::~CLocalSystemInterface() sl@0: // sl@0: // Shut down all server connections in use sl@0: // sl@0: { sl@0: iFids.Close(); sl@0: iCs.Close(); sl@0: iSs.Close(); sl@0: iFs.Close(); sl@0: } sl@0: sl@0: MSystemInterface& CLocalSystemInterface::Clone() sl@0: { sl@0: iUseCount++; sl@0: return *this; sl@0: } sl@0: sl@0: void CLocalSystemInterface::Release() sl@0: { sl@0: if (--iUseCount<0) sl@0: delete this; sl@0: } sl@0: sl@0: void CLocalSystemInterface::TerminateProcess(int status) sl@0: { sl@0: delete this; sl@0: RProcess().Terminate(status); sl@0: } sl@0: sl@0: sl@0: // Simple layer over PosixFilesystem sl@0: sl@0: wchar_t * CLocalSystemInterface::getcwd (wchar_t* buf, unsigned long len, int& anErrno) sl@0: { sl@0: return PosixFilesystem::getcwd(iFs,buf,len,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::chdir (const wchar_t* aPath, int& anErrno) sl@0: { sl@0: return PosixFilesystem::chdir(iFs,aPath,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::rmdir (const wchar_t* aPath, int& anErrno) sl@0: { sl@0: return PosixFilesystem::rmdir(iFs,aPath,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::mkdir (const wchar_t* aPath, int perms, int& anErrno) sl@0: { sl@0: return PosixFilesystem::mkdir(iFs,aPath,perms,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::stat (const wchar_t* name, struct stat *st, int& anErrno) sl@0: { sl@0: return PosixFilesystem::stat(iFs,name,st,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::chmod (const wchar_t* name, int perms, int& anErrno) sl@0: { sl@0: return PosixFilesystem::chmod(iFs,name,perms,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::unlink (const wchar_t* name, int& anErrno) sl@0: { sl@0: return PosixFilesystem::unlink(iFs,name,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::rename (const wchar_t* oldname, const wchar_t* newname, int& anErrno) sl@0: { sl@0: return PosixFilesystem::rename(iFs,oldname,newname,anErrno); sl@0: } sl@0: sl@0: sl@0: TInt CLocalSystemInterface::ResolvePath (TParse& aResult, const wchar_t* path, TDes* aFilename) sl@0: { sl@0: return PosixFilesystem::ResolvePath(iFs, aResult, path, aFilename); sl@0: } sl@0: sl@0: // Simple layer over CFileTable synchronous routines sl@0: sl@0: int CLocalSystemInterface::open (const wchar_t* name, int mode, int perms, int& anErrno) sl@0: { sl@0: //at this point we need to know if it is a serial port or file sl@0: if ((L'C' == name[0]) && (L'O' == name[1]) && (L'M' == name[2]) && (L':' == name[4]) && ((name[3] >= L'1') && (name[3] <= L'9')) || sl@0: (L'I' == name[0]) && (L'R' == name[1]) && (L'C' == name[2]) && (L'O' == name[3]) && (L'M' == name[4]) && (L':' == name[6]) && ((name[5] >= L'1') && (name[5] <= L'9'))) sl@0: return iFids.open(name,mode,perms,anErrno, iCs); sl@0: else sl@0: return iFids.open(name,mode,perms,anErrno, iFs); sl@0: } sl@0: sl@0: int CLocalSystemInterface::dup (int fid, int& anErrno) sl@0: { sl@0: return iFids.dup(fid,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::dup2 (int fid, int fid2, int& anErrno) sl@0: { sl@0: return iFids.dup2(fid,fid2,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::close (int fid, int& anErrno) sl@0: { sl@0: // return iFids.close(fid,anErrno); sl@0: return iFids.userclose(fid,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::lseek (int fid, int offset, int whence, int& anErrno) sl@0: { sl@0: return iFids.lseek(fid,offset,whence,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::fstat (int fid, struct stat *st, int& anErrno) sl@0: { sl@0: return iFids.fstat(fid,st,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::socket (int family, int style, int protocol, int& anErrno) sl@0: { sl@0: return iFids.socket(family,style,protocol,anErrno,iSs); sl@0: } sl@0: sl@0: int CLocalSystemInterface::listen (int fid, int n, int& anErrno) sl@0: { sl@0: return iFids.listen(fid,n,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::bind (int fid, struct sockaddr* addr, unsigned long size, int& anErrno) sl@0: { sl@0: TUSockAddr address(addr,size); sl@0: return iFids.bind(fid,address,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::sockname (int fid, struct sockaddr* addr, unsigned long* size, int anEnd, int& anErrno) sl@0: { sl@0: TUSockAddr address(addr); sl@0: TInt ret=iFids.sockname(fid,address,anEnd,anErrno); sl@0: if (ret==0) sl@0: address.Get(addr,size); sl@0: return ret; sl@0: } sl@0: sl@0: int CLocalSystemInterface::getsockopt (int fid, int level, int opt, void* buf, unsigned long* len, int& anErrno) sl@0: { sl@0: return iFids.getsockopt(fid,level,opt,buf,len,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::setsockopt (int fid, int level, int opt, void* buf, unsigned long len, int& anErrno) sl@0: { sl@0: return iFids.setsockopt(fid,level,opt,buf,len,anErrno); sl@0: } sl@0: sl@0: wchar_t* CLocalSystemInterface::getenv (const wchar_t* name) sl@0: { sl@0: return iEnv.getenv(name); sl@0: } sl@0: sl@0: void CLocalSystemInterface::unsetenv (const wchar_t* name) sl@0: { sl@0: iEnv.unsetenv(name); sl@0: } sl@0: sl@0: int CLocalSystemInterface::setenv (const wchar_t* name, const wchar_t* value, int rewrite, int& anErrno) sl@0: { sl@0: return iEnv.setenv(name,value,rewrite,anErrno); sl@0: } sl@0: sl@0: sl@0: int CLocalSystemInterface::popen3 (const wchar_t *, const wchar_t *, const wchar_t *, wchar_t**, int [3], int& anErrno) sl@0: { sl@0: return MapError(KErrNotSupported,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::waitpid (int, int*, int, int& anErrno) sl@0: { sl@0: return MapError(KErrNotSupported,anErrno); sl@0: } sl@0: sl@0: // Synchronous layer over CFileTable asynchronous routines sl@0: sl@0: int CLocalSystemInterface::read (int fid, char* buf, unsigned long len, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TBool patchErr = EFalse; sl@0: sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus readStatus; sl@0: TRequestStatus timerStatus(KRequestPending); sl@0: RTimer theTimer; sl@0: TBool timerRunning = EFalse; sl@0: sl@0: TPtr8 ptr((TText8 *)buf, len); sl@0: sl@0: if (f->TimedRead()) sl@0: { sl@0: TTimeIntervalMicroSeconds32 timeout(f->TimeoutValue()*1000); sl@0: theTimer.CreateLocal(); sl@0: theTimer.After(timerStatus, timeout); sl@0: timerRunning = ETrue; sl@0: } sl@0: sl@0: f->Read(ptr, readStatus); sl@0: sl@0: User::WaitForRequest(readStatus, timerStatus); sl@0: sl@0: if (timerRunning) sl@0: { sl@0: if (timerStatus.Int() != KRequestPending) sl@0: { sl@0: //cancel the read and wait for it sl@0: f->ReadCancel(); sl@0: patchErr = ETrue; //report this as a timeout not a cancel!! sl@0: User::WaitForRequest(readStatus); sl@0: } sl@0: else sl@0: { sl@0: //if the timer was in operation sl@0: //cancel the timer sl@0: theTimer.Cancel(); sl@0: User::WaitForRequest(timerStatus); sl@0: } sl@0: theTimer.Close(); sl@0: } sl@0: sl@0: err=f->ReadCompletion(ptr, readStatus.Int()); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: if (err==0) sl@0: return ptr.Length(); sl@0: } sl@0: if (patchErr) sl@0: err = ETIMEDOUT; sl@0: sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::write (int fid, const char* buf, unsigned long len, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus status; sl@0: TPtr8 ptr((TText8 *)buf, len, len); sl@0: f->Write(ptr,status); sl@0: User::WaitForRequest(status); sl@0: err=f->WriteCompletion(ptr, status.Int()); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: if (err==0) sl@0: return ptr.Length(); sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::recvfrom (int fid, char* buf, unsigned long len, int flags, struct sockaddr* from, unsigned long* fromsize, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus status; sl@0: TPtr8 ptr((TText8 *)buf, len); sl@0: TUSockAddr addr(from); sl@0: f->RecvFrom(ptr,addr,flags,status); sl@0: User::WaitForRequest(status); sl@0: TInt ret=0; sl@0: err=f->RecvFromCompletion(ret, status.Int()); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: if (err==0) sl@0: { sl@0: addr.Get(from,fromsize); sl@0: return ptr.Length(); sl@0: } sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::sendto (int fid, const char* buf, unsigned long len, int flags, struct sockaddr* to, unsigned long tosize, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus status; sl@0: TPtr8 ptr((TText8 *)buf, len, len); sl@0: TUSockAddr addr(to,tosize); sl@0: f->SendTo(ptr,addr,flags,status); sl@0: User::WaitForRequest(status); sl@0: err=f->SendToCompletion(ptr, status.Int()); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: if (err==0) sl@0: return ptr.Length(); sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::fsync (int fid, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus status; sl@0: f->Sync(status); sl@0: User::WaitForRequest(status); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: err=status.Int(); sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::shutdown (int fid, int how, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus status; sl@0: f->Shutdown(how,status); sl@0: User::WaitForRequest(status); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: err=status.Int(); sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::connect (int fid, struct sockaddr* addr, unsigned long size, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: TRequestStatus status; sl@0: TUSockAddr address(addr,size); sl@0: f->Connect(address,status); sl@0: User::WaitForRequest(status); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: err=status.Int(); sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::accept (int fid, int& anErrno) sl@0: // sl@0: // The CSocketDesc performing the Accept is responsible for creating the new CSocketDesc sl@0: // sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: CSocketDesc* newf=0; sl@0: int fd=iFids.Reserve(); sl@0: err=fd; sl@0: if (fd>=0) sl@0: { sl@0: TRequestStatus status; sl@0: f->Accept(newf,status,iSs); sl@0: CleanupStack::PushL(newf); sl@0: User::WaitForRequest(status); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() sl@0: err=status.Int(); sl@0: if (!err) sl@0: { sl@0: err=iFids.Attach(fd,newf); sl@0: if (!err) sl@0: { sl@0: CleanupStack::PopAndDestroy(newf); sl@0: return fd; sl@0: } sl@0: } sl@0: iFids.Attach(fd,0); // cancel the reservation sl@0: CleanupStack::PopAndDestroy(newf); sl@0: } sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::ioctl (int fid, int cmd, void* param, int& anErrno) sl@0: { sl@0: TRequestStatus ioctlStatus; sl@0: TInt err=ioctl(fid,cmd,param,ioctlStatus,anErrno); sl@0: if (err==KErrNone) sl@0: { sl@0: User::WaitForRequest(ioctlStatus); sl@0: err=ioctl_complete(fid,cmd,param,ioctlStatus,anErrno); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: // C++ version of asynchronous ioctl sl@0: sl@0: int CLocalSystemInterface::ioctl (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno) sl@0: { sl@0: CFileDescBase* f=0; sl@0: TInt err=iFids.Asynch(fid,f); sl@0: if (!err) sl@0: { sl@0: f->Ioctl(cmd,param,aStatus); sl@0: f->Close(); // balances the Dup() in CFileTable::Asynch() - live dangerously! sl@0: } sl@0: return MapError(err,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::ioctl_complete (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno) sl@0: { sl@0: return iFids.ioctlcomplete(fid,cmd,param,aStatus,anErrno); sl@0: } sl@0: sl@0: int CLocalSystemInterface::ioctl_cancel (int fid, int& anErrno) sl@0: { sl@0: return iFids.ioctlcancel(fid,anErrno); sl@0: }