Update contrib.
1 // Copyright (c) 1998-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // POSIX systems calls implemented over EPOC32
23 #include <networking/dnd_err.h>
25 GLDEF_C TInt GetFullPath(TParse& aParse, const TText16* upath, RFs& aSession, TDes* aFileName)
27 // Parse a path of the form "[C:][\]AAA\..\.\BBB\xxx" where:
28 // . indicates the current directory
29 // .. indicates move to the parent directory
30 // An optional "\" at the start of the path indicates the path is not relative to the current path,
31 // and is implied if the drive specifier is present
32 // If aFileName is non-NULL then the final component is a filename and should be copied into
33 // the aFileName descriptor.
42 if (c && upath[1]==KDriveDelimiter)
44 // drive name specified
46 drive.Zero(); // use "?:" to mean scan across drives
49 drive.Copy(TPtrC16(upath, 2));
53 drive.Append(TChar(KPathDelimiter)); // enforce absoluteness
57 // no leading drive specifier
59 if (c==KPathDelimiter||c==L'/')
62 drive.Append(TChar(KPathDelimiter));
65 r = aSession.Parse(drive, aParse);
67 // upath now looks like a relative pathname, to be added onto
68 // aParse a directory at a time. Note that '/' is not allowed in
69 // EPOC32 file or directory names, so treat it as an alternative separator
72 while (c && (r==KErrNone))
74 const TText16* ustart=upath;
77 while (c && c!=KPathDelimiter && c!=L'/');
79 TInt len=(upath-ustart)-1; // excludes delimiter
85 continue; // directory . ignored
86 if (len==2 && ustart[1]==L'.')
89 (void) aParse.PopDir(); // just stick at root dir, no errors
93 if (len>=KMaxFileName)
95 if (c==L'\0' && aFileName!=NULL)
97 // it's the trailing filename
98 aFileName->Copy(TPtrC16(ustart, len));
103 // it's a component of the accumulating path
104 nextBit.Copy(TPtrC16(ustart, len));
105 r = aParse.AddDir(nextBit);
112 GLDEF_C TInt GetFullFile(TFileName& aName, const TText16* upath, RFs& aSession)
113 // Use GetFullPath to establish the pathname, then add the filename onto the end
116 TInt err = GetFullPath(path,upath,aSession,&aName);
119 // Wildcard drive letter for searching across drives
120 if (upath[0]==L'?' && upath[1]==L':')
122 TFindFile search(aSession);
123 err=search.FindByDir(aName,path.Path());
130 err = path.SetNoWild(path.DriveAndPath(),NULL,&aName);
132 aName = path.FullName();
137 // Set errno from an E32STD.H error code or a STDLIB errno value
139 static const TUint8 EPOCtoERRNO[43] = {
140 ENOENT, // KErrNotFound=(-1);
141 0, // KErrGeneral=(-2);
142 EINTR, // KErrCancel=(-3);
143 ENOMEM, // KErrNoMemory=(-4);
144 ENOSYS, // KErrNotSupported=(-5);
145 EINVAL, // KErrArgument=(-6);
146 0, // KErrTotalLossOfPrecision=(-7);
147 0, // KErrBadHandle=(-8);
148 ERANGE, // KErrOverflow=(-9);
149 ERANGE, // KErrUnderflow=(-10);
150 EEXIST, // KErrAlreadyExists=(-11);
151 ENOENT, // KErrPathNotFound=(-12);
152 EPIPE, // KErrDied=(-13);
153 EACCES, // KErrInUse=(-14);
154 EPIPE, // KErrServerTerminated=(-15);
155 EBUSY, // KErrServerBusy=(-16);
156 0, // KErrCompletion=(-17);
157 0, // KErrNotReady=(-18);
158 0, // KErrUnknown=(-19);
159 0, // KErrCorrupt=(-20);
160 EACCES, // KErrAccessDenied=(-21);
161 EACCES, // KErrLocked=(-22);
162 0, // KErrWrite=(-23);
163 ENODEV, // KErrDisMounted=(-24);
164 EPIPE, // KErrEof=(-25);
165 ENOSPC, // KErrDiskFull=(-26);
166 0, // KErrBadDriver=(-27);
167 EINVAL, // KErrBadName=(-28);
168 ECOMM, // KErrCommsLineFail=(-29);
169 ECOMM, // KErrCommsFrame=(-30);
170 ECOMM, // KErrCommsOverrun=(-31);
171 ECOMM, // KErrCommsParity=(-32);
172 ETIMEDOUT, // KErrTimedOut=(-33);
173 ECONNREFUSED, // KErrCouldNotConnect=(-34);
174 0, // KErrCouldNotDisconnect=(-35);
175 EPIPE, // KErrDisconnected=(-36);
176 0, // KErrBadLibraryEntryPoint=(-37);
177 0, // KErrBadDescriptor=(-38);
178 0, // KErrAbort=(-39);
179 0, // KErrTooBig=(-40);
180 EDOM, // KErrDivideByZero=(-41);
181 EDOM, // KErrBadPower=(-42);
182 ENOSPC // KErrDirFull=(-43);
186 EXPORT_C int MapError(TInt err, int& anErrno)
189 return err; // i.e. return 0 without changing errno
191 if (err<KErrNone && err>=KErrDirFull)
193 ret=EPOCtoERRNO[-1-err];
195 ret=err; // no sensible translation
197 else if ((err == KErrDndNameNotFound) || (err == KErrDndAddrNotFound))
198 // KErrDndNameNotFound Returned when no data found for GetByName
199 // KErrDndAddrNotFound Returned when no data found for GetByAddr
203 anErrno=ret; // KErr* values are negative, so will be distinct anyway
209 // Directory enumeration
211 NONSHARABLE_STRUCT(__EPOC32_WDIR) : public CBase // aka "class __EPOC32_WDIR with everything public"
214 __EPOC32_WDIR(struct _reent* aContext) : iContext(aContext) {}
218 TInt Open(const TDesC& aPath);
219 TInt Open(const wchar_t *_path);
221 virtual TInt UpdateNarrow();
222 struct _reent *iContext;
225 TInt iIndex; // counting down, 0 means "finished"
226 struct wdirent iCurrent;
227 TBuf16<KMaxFileName> iCurrentName;
230 TInt __EPOC32_WDIR::UpdateNarrow()
232 return -1; //this is not supported.
236 NONSHARABLE_STRUCT(__EPOC32_DIR) : public __EPOC32_WDIR
239 __EPOC32_DIR(struct _reent* aContext) : __EPOC32_WDIR(aContext) {}
242 virtual TInt UpdateNarrow();
243 struct dirent iCurrentNarrow;
244 TBuf8<KMaxFileName> iCurrentNarrowName;
248 TInt __EPOC32_DIR::UpdateNarrow()
250 //update the narrow one
252 TInt ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(iCurrentNarrowName, iCurrentName);
255 iCurrentNarrow.d_namlen=(short)iCurrentNarrowName.Length();
256 iCurrentNarrow.d_name = (char*)iCurrentNarrowName.PtrZ();
262 __EPOC32_WDIR::~__EPOC32_WDIR()
268 TInt __EPOC32_WDIR::Open(const wchar_t *_path)
270 MSystemInterface& sysIf=Interface(iContext);
272 TInt err = sysIf.ResolvePath(name,_path,NULL);
274 err = Open(name.DriveAndPath());
276 MapError(err,iContext->_errno);
280 TInt __EPOC32_WDIR::Open(const TDesC& aPath)
283 iPath=aPath.Alloc(); //allocate space for a hbufc and initialise it to the TDesC contents
287 TInt __EPOC32_WDIR::Open()
295 TInt err=session.Connect();
298 err=session.GetDir(*iPath,KEntryAttMaskSupported,ESortByName+EDescending,iEntries);
301 iIndex=iEntries->Count();
308 Resets the position to the beginning of the directory.
311 EXPORT_C void wrewinddir (WDIR *dp)
315 (void) dp->Open(); // POSIX doesn't allow for rewind failing
319 Closes the directory.
320 @param dp directory to close.
322 EXPORT_C int wclosedir (WDIR *dp)
330 @return a pointer to the dir object.
331 This object describes the directory
332 and is used in subsequent operations on the directory
333 If error, returns NULL.
334 @param _path path to the directory to be opened.
336 EXPORT_C DIR *opendir (const char *_path)
338 return _opendir_r(_REENT,_path);
341 /** A wide-character version of opendir()
343 EXPORT_C WDIR *wopendir (const wchar_t *_path)
345 return _wopendir_r(_REENT,_path);
348 /** A reentrant version of opendir().
350 EXPORT_C DIR *_opendir_r (struct _reent *r, const char *_path)
353 wchar_t _widepath[KMaxFileName+1];
355 if (mbstowcs(_widepath, _path, KMaxFileName) < 0)
357 MapError(EILSEQ,r->_errno);
363 DIR* dp = new __EPOC32_DIR(r);
370 //coverity[leave_without_push]
372 TInt err = dp->Open(_widepath);
381 /** A reentrant version of wopendir().
383 EXPORT_C WDIR *_wopendir_r (struct _reent *r, const wchar_t *_path)
389 WDIR* dp = new __EPOC32_WDIR(r);
395 //coverity[leave_without_push]
397 TInt err = dp->Open(_path);
407 Sets the index position of the directory stream specified by dp
408 to the position specified by index.
410 EXPORT_C void wseekdir(WDIR *dp,off_t index)
415 EXPORT_C off_t wtelldir(const WDIR *dp)
420 EXPORT_C struct wdirent *wreaddir (WDIR *dp)
424 struct wdirent *ep=&dp->iCurrent;
425 const TEntry& entry=(*dp->iEntries)[--(dp->iIndex)];
426 // in practice, these files must have been created as "X:\something", so they
427 // can't really be longer than KMaxFileName-3
428 dp->iCurrentName.Copy(entry.iName);
429 dp->iCurrentName.ZeroTerminate();
430 ep->d_namlen=(short)dp->iCurrentName.Length();
431 ep->d_name=(wchar_t*)dp->iCurrentName.PtrZ();
436 Returns a pointer to a dirent structure representing
437 the next directory entry in the directory stream pointed to be dir.
438 It returns NULL on reaching the end-of-file or if an error occurred.
439 @return a pointer to a dirent structure, or NULL if an error occurs
440 or end-of-file is reached.
441 @param dp Points to the directory stream of the directory.
443 EXPORT_C struct dirent *readdir (DIR *dp)
445 return _readdir_r(_REENT, dp);
448 /** A reentrant version of readdir().
450 EXPORT_C struct dirent *_readdir_r (struct _reent *r, DIR *dp)
454 if (dp->UpdateNarrow()>=0)
455 return &dp->iCurrentNarrow;
464 Sets the position (associated with the directory stream that dirp points to)
465 to the beginning of the directory.
466 Additionally, it causes the directory stream to refer to the current state of
467 the corresponding directory.
468 @param dp Points to the directory stream of the directory to rewind.
470 EXPORT_C void rewinddir (DIR *dp)
476 closes the directory stream that dirp refers to.
477 The memory associated with the directory stream is released.
478 When this function returns, the value of dirp no longer point to
479 an accessible object of type DIR
480 @return a value of zero. On failure, it returns -1
481 @param dp Is the directory pointer to close (from opendir()).
483 EXPORT_C int closedir (DIR *dp)
485 return wclosedir(dp);
489 sets the position of the next readdir() operation on the directory
490 stream specified by dp to the position specified by index
491 @param dp Points to the directory stream of the directory
494 EXPORT_C void seekdir(DIR *dp,off_t index)
500 Returns the current location associated with the directory stream dir.
501 @return the current location in the directory stream or -1 if an error occurs.
502 @param dp Points to the directory stream of the directory
504 EXPORT_C off_t telldir(const DIR *dp)