os/ossrv/genericopenlibs/cstdlib/USTLIB/FTABLE.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Handle a table of CFileDescBase pointers
    15 // 
    16 //
    17 
    18 #include "SYSIF.H"
    19 #include "FDESC.H"
    20 #include "LTIME.H"
    21 #include "LPOSIX.H"
    22 #include <fcntl.h>
    23 #include <sys/errno.h>
    24 
    25 #define RESERVED(i)	((CFileDescBase*)((i)+1))
    26 
    27 const TInt MINFILES = 8;
    28 
    29 CFileTable::CFileTable() : iFids(MINFILES)
    30 	{
    31 	}
    32 
    33 void CFileTable::InitL()
    34 	{
    35 	CFileDescBase* ptr=0;
    36 	iFids.InsertL(0, ptr, 8);	// set up the first 8 entries with zero
    37 	}
    38 
    39 CFileTable::~CFileTable()
    40 	{
    41 	Close();
    42 	}
    43 
    44 void CFileTable::Close()
    45 	{
    46 	for (TInt aFid=0; aFid<iFids.Count(); aFid++)
    47 		{
    48 		if (iFids[aFid]!=0 && iFids[aFid]!=RESERVED(aFid))
    49 			{
    50 			iFids[aFid]->RecvFromCancel();
    51 			iFids[aFid]->Close();
    52 			}
    53 		Release(aFid);
    54 		}
    55 	}
    56 
    57 void CFileTable::Release(TInt aFid)
    58 	{
    59 	iFids[aFid]=0;
    60 	if (aFid<MINFILES || aFid<iFids.Count()-1)
    61 		return;
    62 	// opportunity to shrink the array
    63 	while (aFid>=MINFILES && iFids[aFid]==0)
    64 		{
    65 		iFids.Delete(aFid);
    66 		aFid--;
    67 		}
    68 	iFids.Compress();
    69 	}
    70 
    71 void CFileTable::Default(CFileDescBase* aConsole)
    72 	{
    73 	if (iFids[0]==0)
    74 		iFids[0]=aConsole->Dup();
    75 	if (iFids[1]==0)
    76 		iFids[1]=aConsole->Dup();
    77 	if (iFids[2]==0)
    78 		iFids[2]=aConsole->Dup();
    79 	}
    80 
    81 TInt CFileTable::Attach(TInt aFid, CFileDescBase* aFile)
    82 	{
    83 	if (aFid<0 || aFid>=iFids.Count() || (iFids[aFid] != 0 && iFids[aFid]!=RESERVED(aFid)))
    84 		return KErrArgument;
    85 	iFids[aFid]=aFile;
    86 	return KErrNone;
    87 	}
    88 
    89 TInt CFileTable::Reserve()
    90 	{
    91 	TInt aFid=0;
    92 	TInt err=KErrNone;
    93 	for (aFid=0; aFid<iFids.Count(); aFid++)
    94 		if (iFids[aFid]==0)
    95 			goto success;
    96 	TRAP(err,iFids.ExtendL());
    97 	if (err!=KErrNone)
    98 		return err;
    99 	aFid=iFids.Count()-1;
   100 
   101 success:
   102 	iFids[aFid]=RESERVED(aFid);
   103 	return aFid;
   104 	}
   105 
   106 TInt CFileTable::Reserve(int aFids[3])
   107 	{
   108 	TInt i=0;
   109 	for (i=0; i<3; i++)
   110 		{
   111 		if (aFids[i]==-1)
   112 			{
   113 			TInt fd=Reserve();
   114 			if (fd<0)
   115 				{
   116 				Detach(aFids);	// release the ones we did get
   117 				return KErrInUse;
   118 				}
   119 			aFids[i]=fd;
   120 			}
   121 		}
   122 	return KErrNone;
   123 	}
   124 
   125 TInt CFileTable::Detach(int aFids[3])
   126 	{
   127 	TInt i=0;
   128 	for (i=0; i<3; i++)
   129 		{
   130 		if (aFids[i]>=0)
   131 			Attach(aFids[i],0);
   132 		}
   133 	return KErrInUse;
   134 	}
   135 
   136 TInt CFileTable::Detach(TInt aFid, CFileDescBase*& aDetached)
   137 	{
   138 	if (aFid<0 || aFid>=iFids.Count())
   139 		return KErrArgument;
   140 	aDetached=iFids[aFid];
   141 	Release(aFid);
   142 	return KErrNone;
   143 	}
   144 
   145 TInt CFileTable::At(TInt aFid, CFileDescBase*& aFound) const
   146 	{
   147 	if (aFid<0 || aFid>=iFids.Count())
   148 		return KErrArgument;
   149 	aFound=iFids[aFid];
   150 	if (aFound==0)
   151 		return KErrNotFound;
   152 	return KErrNone;
   153 	}
   154 
   155 TInt CFileTable::Dup(TInt& aFid)
   156 	{
   157 	if (aFid<0 || aFid>=iFids.Count())
   158 		return KErrArgument;
   159 	CFileDescBase* fdesc=iFids[aFid];
   160 	if (fdesc==0)
   161 		return KErrNotFound;
   162 	TInt aFid2=0;
   163 	for (aFid2=0; aFid2<iFids.Count(); aFid2++)
   164 		if (iFids[aFid2]==0)
   165 			{
   166 			iFids[aFid2]=fdesc->Dup();
   167 			aFid=aFid2;
   168 			return KErrNone;
   169 			}
   170 	return KErrInUse;
   171 	}
   172 
   173 TInt CFileTable::Dup2(TInt aFid, TInt aFid2)
   174 	{
   175 	if (aFid<0 || aFid>=iFids.Count() || aFid2<0 || aFid2>=iFids.Count() || aFid==aFid2)
   176 		return KErrArgument;
   177 	CFileDescBase* fdesc=iFids[aFid];
   178 	if (fdesc==0)
   179 		return KErrNotFound;
   180 	CFileDescBase* old=iFids[aFid2];
   181 	iFids[aFid2]=fdesc->Dup();
   182 	if (old)
   183 		old->Close();
   184 	return KErrNone;
   185 	}
   186 
   187 // Simple synchronous services
   188 
   189 int CFileTable::dup (int fid, int& anErrno)
   190 	{
   191 	TInt ret=Dup(fid);
   192 	if (ret==KErrNone)
   193 		return fid;
   194 	return MapError(ret,anErrno);
   195 	}
   196 
   197 int CFileTable::dup2 (int fid, int fid2, int& anErrno)
   198 	{
   199 	TInt err=Dup2(fid,fid2);
   200 	return MapError(err,anErrno);
   201 	}
   202 	
   203 //int CFileTable::open (const char* name, int mode, int perms, int& anErrno, RFs& aFs)
   204 //int CFileTable::open (const wchar_t* name, int mode, int perms, int& anErrno, RFs& aFs)
   205 int CFileTable::open (const wchar_t* name, int mode, int perms, int& anErrno, RSessionBase& aFs)
   206 	{
   207 	int fd=Reserve();
   208 	TInt err=fd;
   209 	if (fd>=0)
   210 		{
   211 		//coverity[alloc_fn]
   212 		//coverity[var_assign]
   213 		CFileDescBase *f=CFileDescBase::Open(aFs,name,mode,perms,err);
   214 		if (!err)
   215 			{
   216 			err=Attach(fd,f);
   217 			if (!err)
   218 				return fd;
   219 			delete f;
   220 			}
   221 		Attach(fd,0);	// cancel the reservation
   222 		//coverity[leaked_storage]
   223 		}
   224 	return MapError(err,anErrno);
   225 	}
   226 
   227 int CFileTable::socket (int family, int style, int protocol, int& anErrno, RSocketServ& aSs)
   228 	{
   229 	int fd=Reserve();
   230 	TInt err=fd;
   231 	if (fd>=0)
   232 		{
   233 		CFileDescBase *f=CFileDescBase::Socket(aSs,family,style,protocol,err);
   234 		if (!err)
   235 			{
   236 			CleanupStack::PushL(f);
   237 			err=Attach(fd,f);
   238 			CleanupStack::PopAndDestroy(f);
   239 			
   240 			if (!err)
   241 				{
   242 				return fd;	
   243 				}
   244 			
   245 			}
   246 		
   247 		Attach(fd,0);	// cancel the reservation
   248 		}
   249 
   250 	return MapError(err,anErrno);
   251 	}
   252 
   253 int CFileTable::userclose(int fid, int& anErrno)
   254 	{
   255 	CFileDescBase *f=0;
   256 	TInt err=At(fid,f);
   257 	if (!err)
   258 		{
   259 		f->UserClose();
   260 		close(fid, anErrno);
   261 		}
   262 	else
   263 		{
   264 		if (KErrNotFound == err)
   265 			err = EBADF;
   266 		}
   267 	return MapError(err,anErrno);
   268 	}
   269 
   270 int CFileTable::close (int fid, int& anErrno)
   271 	{
   272 	CFileDescBase *f=0;
   273 	TInt err=Detach(fid,f);
   274 	if (!err)
   275 	   {
   276 		if (f==0)
   277 		  {
   278 			err=EBADF;
   279 		  }
   280 		else
   281 		  {
   282 		    f->RecvFromCancel();
   283 			err=f->Close();
   284 		  }
   285 	   }
   286 	return MapError(err,anErrno);
   287 	}
   288 
   289 
   290 
   291 int CFileTable::lseek (int fid, int offset, int whence, int& anErrno)
   292 	{
   293 	CFileDescBase *f=0;
   294 	TInt err=At(fid,f);
   295 	if (!err)
   296 		{
   297 		err=f->LSeek(offset, whence);
   298 		if (err==KErrNone)
   299 			return offset;
   300 		}
   301 	return MapError(err,anErrno);
   302 	}
   303 
   304 int CFileTable::fstat (int fid, struct stat *st, int& anErrno)
   305 	{
   306 	CFileDescBase *f=0;
   307 	TInt err=At(fid,f);
   308 	if (!err)
   309 		err=f->FStat(st);
   310 	return MapError(err,anErrno);
   311 	}
   312 
   313 int CFileTable::listen (int fid, int n, int& anErrno)
   314 	{
   315 	CFileDescBase *f=0;
   316 	TInt err=At(fid,f);
   317 	if (!err)
   318 		err=f->Listen(n);
   319 	return MapError(err,anErrno);
   320 	}
   321 
   322 int CFileTable::bind (int fid, TSockAddr& address, int& anErrno)
   323 	{
   324 	CFileDescBase *f=0;
   325 	TInt err=At(fid,f);
   326 	if (!err)
   327 		err=f->Bind(address);
   328 	return MapError(err,anErrno);
   329 	}
   330 
   331 int CFileTable::sockname (int fid, TSockAddr& address, int anEnd, int& anErrno)
   332 	{
   333 	CFileDescBase *f=0;
   334 	TInt err=At(fid,f);
   335 	if (!err)
   336 		err=f->SockName(anEnd, address);
   337 	return MapError(err,anErrno);
   338 	}
   339 
   340 int CFileTable::getsockopt (int fid, int level, int opt, void* buf, unsigned long* len, int& anErrno)
   341 	{
   342 	CFileDescBase *f=0;
   343 	TInt err=At(fid,f);
   344 	if (!err)
   345 		{
   346 		TPtr8 ptr((TText8 *)buf, *len, *len);
   347 		err=f->GetSockOpt(opt,level,ptr);
   348 		if (err==0)
   349 			*len=ptr.Length();
   350 		}
   351 	return MapError(err,anErrno);
   352 	}
   353 
   354 int CFileTable::setsockopt (int fid, int level, int opt, void* buf, unsigned long len, int& anErrno)
   355 	{
   356 	CFileDescBase *f=0;
   357 	TInt err=At(fid,f);
   358 	if (err==KErrNone)
   359 		{
   360 		//Negative option is not supported and have not been implemented yet
   361 		//anErrno is then mapped to ENOSYS(88) (function not implemented yet)
   362 		if (opt<=0)
   363 			return MapError(KErrNotSupported,anErrno);
   364 		TPtrC8 ptr((TText8 *)buf, len);
   365 		err=f->SetSockOpt(opt,level,ptr);
   366 		}
   367 	return MapError(err,anErrno);
   368 	}
   369 
   370 int CFileTable::ioctlcomplete (int fid, int cmd, void* param, TRequestStatus& aStatus, int& anErrno)
   371 	{
   372 	CFileDescBase *f=0;
   373 	TInt err=At(fid,f);
   374 	if (!err)
   375 		err=f->IoctlCompletion(cmd,param, aStatus.Int());
   376 	return MapError(err,anErrno);
   377 	}
   378 
   379 int CFileTable::ioctlcancel (int fid, int& anErrno)
   380 	{
   381 	CFileDescBase *f=0;
   382 	TInt err=At(fid,f);
   383 	if (!err)
   384 		f->IoctlCancel();
   385 	return MapError(err,anErrno);
   386 	}
   387 
   388 // Preparation for an Asynchronous service
   389 //
   390 // The CFileDescBase* should be Closed after completion: the use of Dup prevents other
   391 // clients from invalidating the pointer during an asynchronous operation.
   392 
   393 TInt CFileTable::Asynch (int fid, CFileDescBase*& aFile)
   394 	{
   395 	TInt err=At(fid,aFile);
   396 	if (!err)
   397 		aFile->Dup();
   398 	return err;
   399 	}
   400