1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/USTLIB/LOCALIF.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,476 @@
1.4 +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "SYSIF.H"
1.20 +#include "FDESC.H"
1.21 +#include "LTIME.H"
1.22 +#include "LPOSIX.H"
1.23 +#include <fcntl.h>
1.24 +#include <sys/errno.h>
1.25 +#include <sys/serial.h>
1.26 +
1.27 +// System Interface for thread-local form of STDLIB
1.28 +
1.29 +/**
1.30 +Two-phase constructor method to create a CLocalSystemInterface instance.
1.31 +*/
1.32 +CLocalSystemInterface* CLocalSystemInterface::NewL()
1.33 + {
1.34 + CLocalSystemInterface* self = new (ELeave) CLocalSystemInterface();
1.35 + CleanupStack::PushL(self);
1.36 + self->ConstructL();
1.37 + CleanupStack::Pop(self);
1.38 + return self;
1.39 + }
1.40 +
1.41 +/**
1.42 +Constructor.
1.43 +*/
1.44 +CLocalSystemInterface::CLocalSystemInterface()
1.45 + {
1.46 + }
1.47 +
1.48 +/**
1.49 +Second-phase constructor.
1.50 +Initialises some data members.
1.51 +This function leaves if any system-wide error happens.
1.52 +*/
1.53 +void CLocalSystemInterface::ConstructL()
1.54 + {
1.55 + iFids.InitL();
1.56 +
1.57 + CTtyDesc* console=new CTtyDesc;
1.58 + User::LeaveIfNull(console);
1.59 +
1.60 + iFids.Default(console);
1.61 + console->Close();
1.62 +
1.63 + User::LeaveIfError(iFs.Connect());
1.64 + User::LeaveIfError(PosixFilesystem::SetDefaultDir(iFs));
1.65 + }
1.66 +
1.67 +CLocalSystemInterface::~CLocalSystemInterface()
1.68 +//
1.69 +// Shut down all server connections in use
1.70 +//
1.71 + {
1.72 + iFids.Close();
1.73 + iCs.Close();
1.74 + iSs.Close();
1.75 + iFs.Close();
1.76 + }
1.77 +
1.78 +MSystemInterface& CLocalSystemInterface::Clone()
1.79 + {
1.80 + iUseCount++;
1.81 + return *this;
1.82 + }
1.83 +
1.84 +void CLocalSystemInterface::Release()
1.85 + {
1.86 + if (--iUseCount<0)
1.87 + delete this;
1.88 + }
1.89 +
1.90 +void CLocalSystemInterface::TerminateProcess(int status)
1.91 + {
1.92 + delete this;
1.93 + RProcess().Terminate(status);
1.94 + }
1.95 +
1.96 +
1.97 +// Simple layer over PosixFilesystem
1.98 +
1.99 +wchar_t * CLocalSystemInterface::getcwd (wchar_t* buf, unsigned long len, int& anErrno)
1.100 + {
1.101 + return PosixFilesystem::getcwd(iFs,buf,len,anErrno);
1.102 + }
1.103 +
1.104 +int CLocalSystemInterface::chdir (const wchar_t* aPath, int& anErrno)
1.105 + {
1.106 + return PosixFilesystem::chdir(iFs,aPath,anErrno);
1.107 + }
1.108 +
1.109 +int CLocalSystemInterface::rmdir (const wchar_t* aPath, int& anErrno)
1.110 + {
1.111 + return PosixFilesystem::rmdir(iFs,aPath,anErrno);
1.112 + }
1.113 +
1.114 +int CLocalSystemInterface::mkdir (const wchar_t* aPath, int perms, int& anErrno)
1.115 + {
1.116 + return PosixFilesystem::mkdir(iFs,aPath,perms,anErrno);
1.117 + }
1.118 +
1.119 +int CLocalSystemInterface::stat (const wchar_t* name, struct stat *st, int& anErrno)
1.120 + {
1.121 + return PosixFilesystem::stat(iFs,name,st,anErrno);
1.122 + }
1.123 +
1.124 +int CLocalSystemInterface::chmod (const wchar_t* name, int perms, int& anErrno)
1.125 + {
1.126 + return PosixFilesystem::chmod(iFs,name,perms,anErrno);
1.127 + }
1.128 +
1.129 +int CLocalSystemInterface::unlink (const wchar_t* name, int& anErrno)
1.130 + {
1.131 + return PosixFilesystem::unlink(iFs,name,anErrno);
1.132 + }
1.133 +
1.134 +int CLocalSystemInterface::rename (const wchar_t* oldname, const wchar_t* newname, int& anErrno)
1.135 + {
1.136 + return PosixFilesystem::rename(iFs,oldname,newname,anErrno);
1.137 + }
1.138 +
1.139 +
1.140 +TInt CLocalSystemInterface::ResolvePath (TParse& aResult, const wchar_t* path, TDes* aFilename)
1.141 + {
1.142 + return PosixFilesystem::ResolvePath(iFs, aResult, path, aFilename);
1.143 + }
1.144 +
1.145 +// Simple layer over CFileTable synchronous routines
1.146 +
1.147 +int CLocalSystemInterface::open (const wchar_t* name, int mode, int perms, int& anErrno)
1.148 + {
1.149 + //at this point we need to know if it is a serial port or file
1.150 + if ((L'C' == name[0]) && (L'O' == name[1]) && (L'M' == name[2]) && (L':' == name[4]) && ((name[3] >= L'1') && (name[3] <= L'9')) ||
1.151 + (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')))
1.152 + return iFids.open(name,mode,perms,anErrno, iCs);
1.153 + else
1.154 + return iFids.open(name,mode,perms,anErrno, iFs);
1.155 + }
1.156 +
1.157 +int CLocalSystemInterface::dup (int fid, int& anErrno)
1.158 + {
1.159 + return iFids.dup(fid,anErrno);
1.160 + }
1.161 +
1.162 +int CLocalSystemInterface::dup2 (int fid, int fid2, int& anErrno)
1.163 + {
1.164 + return iFids.dup2(fid,fid2,anErrno);
1.165 + }
1.166 +
1.167 +int CLocalSystemInterface::close (int fid, int& anErrno)
1.168 + {
1.169 +// return iFids.close(fid,anErrno);
1.170 + return iFids.userclose(fid,anErrno);
1.171 + }
1.172 +
1.173 +int CLocalSystemInterface::lseek (int fid, int offset, int whence, int& anErrno)
1.174 + {
1.175 + return iFids.lseek(fid,offset,whence,anErrno);
1.176 + }
1.177 +
1.178 +int CLocalSystemInterface::fstat (int fid, struct stat *st, int& anErrno)
1.179 + {
1.180 + return iFids.fstat(fid,st,anErrno);
1.181 + }
1.182 +
1.183 +int CLocalSystemInterface::socket (int family, int style, int protocol, int& anErrno)
1.184 + {
1.185 + return iFids.socket(family,style,protocol,anErrno,iSs);
1.186 + }
1.187 +
1.188 +int CLocalSystemInterface::listen (int fid, int n, int& anErrno)
1.189 + {
1.190 + return iFids.listen(fid,n,anErrno);
1.191 + }
1.192 +
1.193 +int CLocalSystemInterface::bind (int fid, struct sockaddr* addr, unsigned long size, int& anErrno)
1.194 + {
1.195 + TUSockAddr address(addr,size);
1.196 + return iFids.bind(fid,address,anErrno);
1.197 + }
1.198 +
1.199 +int CLocalSystemInterface::sockname (int fid, struct sockaddr* addr, unsigned long* size, int anEnd, int& anErrno)
1.200 + {
1.201 + TUSockAddr address(addr);
1.202 + TInt ret=iFids.sockname(fid,address,anEnd,anErrno);
1.203 + if (ret==0)
1.204 + address.Get(addr,size);
1.205 + return ret;
1.206 + }
1.207 +
1.208 +int CLocalSystemInterface::getsockopt (int fid, int level, int opt, void* buf, unsigned long* len, int& anErrno)
1.209 + {
1.210 + return iFids.getsockopt(fid,level,opt,buf,len,anErrno);
1.211 + }
1.212 +
1.213 +int CLocalSystemInterface::setsockopt (int fid, int level, int opt, void* buf, unsigned long len, int& anErrno)
1.214 + {
1.215 + return iFids.setsockopt(fid,level,opt,buf,len,anErrno);
1.216 + }
1.217 +
1.218 +wchar_t* CLocalSystemInterface::getenv (const wchar_t* name)
1.219 + {
1.220 + return iEnv.getenv(name);
1.221 + }
1.222 +
1.223 +void CLocalSystemInterface::unsetenv (const wchar_t* name)
1.224 + {
1.225 + iEnv.unsetenv(name);
1.226 + }
1.227 +
1.228 +int CLocalSystemInterface::setenv (const wchar_t* name, const wchar_t* value, int rewrite, int& anErrno)
1.229 + {
1.230 + return iEnv.setenv(name,value,rewrite,anErrno);
1.231 + }
1.232 +
1.233 +
1.234 +int CLocalSystemInterface::popen3 (const wchar_t *, const wchar_t *, const wchar_t *, wchar_t**, int [3], int& anErrno)
1.235 + {
1.236 + return MapError(KErrNotSupported,anErrno);
1.237 + }
1.238 +
1.239 +int CLocalSystemInterface::waitpid (int, int*, int, int& anErrno)
1.240 + {
1.241 + return MapError(KErrNotSupported,anErrno);
1.242 + }
1.243 +
1.244 +// Synchronous layer over CFileTable asynchronous routines
1.245 +
1.246 +int CLocalSystemInterface::read (int fid, char* buf, unsigned long len, int& anErrno)
1.247 + {
1.248 + CFileDescBase* f=0;
1.249 + TBool patchErr = EFalse;
1.250 +
1.251 + TInt err=iFids.Asynch(fid,f);
1.252 + if (!err)
1.253 + {
1.254 + TRequestStatus readStatus;
1.255 + TRequestStatus timerStatus(KRequestPending);
1.256 + RTimer theTimer;
1.257 + TBool timerRunning = EFalse;
1.258 +
1.259 + TPtr8 ptr((TText8 *)buf, len);
1.260 +
1.261 + if (f->TimedRead())
1.262 + {
1.263 + TTimeIntervalMicroSeconds32 timeout(f->TimeoutValue()*1000);
1.264 + theTimer.CreateLocal();
1.265 + theTimer.After(timerStatus, timeout);
1.266 + timerRunning = ETrue;
1.267 + }
1.268 +
1.269 + f->Read(ptr, readStatus);
1.270 +
1.271 + User::WaitForRequest(readStatus, timerStatus);
1.272 +
1.273 + if (timerRunning)
1.274 + {
1.275 + if (timerStatus.Int() != KRequestPending)
1.276 + {
1.277 + //cancel the read and wait for it
1.278 + f->ReadCancel();
1.279 + patchErr = ETrue; //report this as a timeout not a cancel!!
1.280 + User::WaitForRequest(readStatus);
1.281 + }
1.282 + else
1.283 + {
1.284 + //if the timer was in operation
1.285 + //cancel the timer
1.286 + theTimer.Cancel();
1.287 + User::WaitForRequest(timerStatus);
1.288 + }
1.289 + theTimer.Close();
1.290 + }
1.291 +
1.292 + err=f->ReadCompletion(ptr, readStatus.Int());
1.293 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.294 + if (err==0)
1.295 + return ptr.Length();
1.296 + }
1.297 + if (patchErr)
1.298 + err = ETIMEDOUT;
1.299 +
1.300 + return MapError(err,anErrno);
1.301 + }
1.302 +
1.303 +int CLocalSystemInterface::write (int fid, const char* buf, unsigned long len, int& anErrno)
1.304 + {
1.305 + CFileDescBase* f=0;
1.306 + TInt err=iFids.Asynch(fid,f);
1.307 + if (!err)
1.308 + {
1.309 + TRequestStatus status;
1.310 + TPtr8 ptr((TText8 *)buf, len, len);
1.311 + f->Write(ptr,status);
1.312 + User::WaitForRequest(status);
1.313 + err=f->WriteCompletion(ptr, status.Int());
1.314 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.315 + if (err==0)
1.316 + return ptr.Length();
1.317 + }
1.318 + return MapError(err,anErrno);
1.319 + }
1.320 +
1.321 +int CLocalSystemInterface::recvfrom (int fid, char* buf, unsigned long len, int flags, struct sockaddr* from, unsigned long* fromsize, int& anErrno)
1.322 + {
1.323 + CFileDescBase* f=0;
1.324 + TInt err=iFids.Asynch(fid,f);
1.325 + if (!err)
1.326 + {
1.327 + TRequestStatus status;
1.328 + TPtr8 ptr((TText8 *)buf, len);
1.329 + TUSockAddr addr(from);
1.330 + f->RecvFrom(ptr,addr,flags,status);
1.331 + User::WaitForRequest(status);
1.332 + TInt ret=0;
1.333 + err=f->RecvFromCompletion(ret, status.Int());
1.334 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.335 + if (err==0)
1.336 + {
1.337 + addr.Get(from,fromsize);
1.338 + return ptr.Length();
1.339 + }
1.340 + }
1.341 + return MapError(err,anErrno);
1.342 + }
1.343 +
1.344 +int CLocalSystemInterface::sendto (int fid, const char* buf, unsigned long len, int flags, struct sockaddr* to, unsigned long tosize, int& anErrno)
1.345 + {
1.346 + CFileDescBase* f=0;
1.347 + TInt err=iFids.Asynch(fid,f);
1.348 + if (!err)
1.349 + {
1.350 + TRequestStatus status;
1.351 + TPtr8 ptr((TText8 *)buf, len, len);
1.352 + TUSockAddr addr(to,tosize);
1.353 + f->SendTo(ptr,addr,flags,status);
1.354 + User::WaitForRequest(status);
1.355 + err=f->SendToCompletion(ptr, status.Int());
1.356 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.357 + if (err==0)
1.358 + return ptr.Length();
1.359 + }
1.360 + return MapError(err,anErrno);
1.361 + }
1.362 +
1.363 +int CLocalSystemInterface::fsync (int fid, int& anErrno)
1.364 + {
1.365 + CFileDescBase* f=0;
1.366 + TInt err=iFids.Asynch(fid,f);
1.367 + if (!err)
1.368 + {
1.369 + TRequestStatus status;
1.370 + f->Sync(status);
1.371 + User::WaitForRequest(status);
1.372 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.373 + err=status.Int();
1.374 + }
1.375 + return MapError(err,anErrno);
1.376 + }
1.377 +
1.378 +int CLocalSystemInterface::shutdown (int fid, int how, int& anErrno)
1.379 + {
1.380 + CFileDescBase* f=0;
1.381 + TInt err=iFids.Asynch(fid,f);
1.382 + if (!err)
1.383 + {
1.384 + TRequestStatus status;
1.385 + f->Shutdown(how,status);
1.386 + User::WaitForRequest(status);
1.387 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.388 + err=status.Int();
1.389 + }
1.390 + return MapError(err,anErrno);
1.391 + }
1.392 +
1.393 +int CLocalSystemInterface::connect (int fid, struct sockaddr* addr, unsigned long size, int& anErrno)
1.394 + {
1.395 + CFileDescBase* f=0;
1.396 + TInt err=iFids.Asynch(fid,f);
1.397 + if (!err)
1.398 + {
1.399 + TRequestStatus status;
1.400 + TUSockAddr address(addr,size);
1.401 + f->Connect(address,status);
1.402 + User::WaitForRequest(status);
1.403 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.404 + err=status.Int();
1.405 + }
1.406 + return MapError(err,anErrno);
1.407 + }
1.408 +
1.409 +int CLocalSystemInterface::accept (int fid, int& anErrno)
1.410 +//
1.411 +// The CSocketDesc performing the Accept is responsible for creating the new CSocketDesc
1.412 +//
1.413 + {
1.414 + CFileDescBase* f=0;
1.415 + TInt err=iFids.Asynch(fid,f);
1.416 + if (!err)
1.417 + {
1.418 + CSocketDesc* newf=0;
1.419 + int fd=iFids.Reserve();
1.420 + err=fd;
1.421 + if (fd>=0)
1.422 + {
1.423 + TRequestStatus status;
1.424 + f->Accept(newf,status,iSs);
1.425 + CleanupStack::PushL(newf);
1.426 + User::WaitForRequest(status);
1.427 + f->Close(); // balances the Dup() in CFileTable::Asynch()
1.428 + err=status.Int();
1.429 + if (!err)
1.430 + {
1.431 + err=iFids.Attach(fd,newf);
1.432 + if (!err)
1.433 + {
1.434 + CleanupStack::PopAndDestroy(newf);
1.435 + return fd;
1.436 + }
1.437 + }
1.438 + iFids.Attach(fd,0); // cancel the reservation
1.439 + CleanupStack::PopAndDestroy(newf);
1.440 + }
1.441 + }
1.442 + return MapError(err,anErrno);
1.443 + }
1.444 +
1.445 +int CLocalSystemInterface::ioctl (int fid, int cmd, void* param, int& anErrno)
1.446 + {
1.447 + TRequestStatus ioctlStatus;
1.448 + TInt err=ioctl(fid,cmd,param,ioctlStatus,anErrno);
1.449 + if (err==KErrNone)
1.450 + {
1.451 + User::WaitForRequest(ioctlStatus);
1.452 + err=ioctl_complete(fid,cmd,param,ioctlStatus,anErrno);
1.453 + }
1.454 + return err;
1.455 + }
1.456 +
1.457 +// C++ version of asynchronous ioctl
1.458 +
1.459 +int CLocalSystemInterface::ioctl (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno)
1.460 + {
1.461 + CFileDescBase* f=0;
1.462 + TInt err=iFids.Asynch(fid,f);
1.463 + if (!err)
1.464 + {
1.465 + f->Ioctl(cmd,param,aStatus);
1.466 + f->Close(); // balances the Dup() in CFileTable::Asynch() - live dangerously!
1.467 + }
1.468 + return MapError(err,anErrno);
1.469 + }
1.470 +
1.471 +int CLocalSystemInterface::ioctl_complete (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno)
1.472 + {
1.473 + return iFids.ioctlcomplete(fid,cmd,param,aStatus,anErrno);
1.474 + }
1.475 +
1.476 +int CLocalSystemInterface::ioctl_cancel (int fid, int& anErrno)
1.477 + {
1.478 + return iFids.ioctlcancel(fid,anErrno);
1.479 + }