genericopenlibs/cstdlib/LPOSIX/SYSCALLS.CPP
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // connectors for re-entrant system calls
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "SYSIF.H"
       
    19 #include "LPOSIX.H"
       
    20 
       
    21 #include <reent.h>
       
    22 #include <unistd.h>
       
    23 #include <fcntl.h>		// for open()
       
    24 #include <sys/ioctl.h>
       
    25 #include <stdarg.h>
       
    26 #include <sys/errno.h>
       
    27 #include <stdio_r.h>		// for popen3
       
    28 #include <stdlib_r.h>		// for system
       
    29 #include <utf.h>
       
    30 #include <string.h>
       
    31 
       
    32 
       
    33 extern "C" {
       
    34 
       
    35 /**
       
    36 Opens the file which name is stored in the file string.
       
    37 
       
    38 @return	On Success, a non-negative integer representing the lowest numbered unused file descriptor.
       
    39 		On Failure, returns -1, errno may be set.		
       
    40 */
       
    41 EXPORT_C int open (const char *file, int flags, ...)
       
    42 	{
       
    43 	va_list ap;
       
    44 	int ret;
       
    45 
       
    46 	struct _reent *r = _REENT2;
       
    47 	if (!r)
       
    48 		return -1; // Memory for library globals is not allocated (errno not set).
       
    49 
       
    50 	va_start (ap, flags);
       
    51 	ret = _open_r (r, file, flags, va_arg (ap, int));
       
    52 	va_end (ap);
       
    53 	return ret;
       
    54 	}
       
    55 
       
    56 /**
       
    57 A wide_character version of a open().
       
    58 */
       
    59 EXPORT_C int wopen (const wchar_t *file, int flags, ...)
       
    60 	{
       
    61 	va_list ap;
       
    62 	int ret;
       
    63 
       
    64 	struct _reent *r = _REENT2;
       
    65 	if (!r)
       
    66 		return -1; // Memory for library globals is not allocated (errno not set).
       
    67 
       
    68 	va_start (ap, flags);
       
    69 	ret = _wopen_r (r, file, flags, va_arg (ap, int));
       
    70 	va_end (ap);
       
    71 	return ret;
       
    72 	}
       
    73 
       
    74 /** A reentrant version of open().
       
    75 */
       
    76 EXPORT_C int _open_r (struct _reent *r, const char *name, int mode, int perms)
       
    77 	{
       
    78 	wchar_t _widename[KMaxFileName+1];
       
    79 
       
    80 	if (-1 != mbstowcs(_widename, name, KMaxFileName))
       
    81 		{
       
    82 		MSystemInterface& sysIf=Interface(r);
       
    83 		return sysIf.open(_widename,mode,perms,r->_errno);
       
    84 		}
       
    85 	
       
    86 	MapError(EILSEQ, r->_errno);		
       
    87 	return 0;	//null file pointer
       
    88 
       
    89 	}
       
    90 
       
    91 /** A reentrant version of wopen().
       
    92 */
       
    93 EXPORT_C int _wopen_r (struct _reent *r, const wchar_t *name, int mode, int perms)
       
    94 	{
       
    95 	MSystemInterface& sysIf=Interface(r);
       
    96 	return sysIf.open(name,mode,perms,r->_errno);
       
    97 	}
       
    98 
       
    99 /**
       
   100 Reads a block of data of the length specified by cnt.
       
   101 
       
   102 @return On Success, return a non-negative integer indicating the number of bytes actually read.
       
   103 		On Failure, returns -1, errno may be set.		
       
   104 */
       
   105 EXPORT_C int read (int fd, char *buf, size_t cnt)
       
   106 	{
       
   107 	struct _reent *r = _REENT2;
       
   108 	if (!r)
       
   109 		return -1; // Memory for library globals is not allocated (errno not set).
       
   110 	return _read_r (r, fd, buf, cnt);
       
   111 	}
       
   112 
       
   113 /** A reentrant version of read().
       
   114 */
       
   115 EXPORT_C int _read_r (struct _reent *r, int fd, char *buf, size_t nbyte)
       
   116 	{
       
   117 	MSystemInterface& sysIf=Interface(r);
       
   118 	return sysIf.read(fd,buf,nbyte,r->_errno);
       
   119 	}
       
   120 
       
   121 /**
       
   122 Writes a block of data of the length specified by cnt.
       
   123 
       
   124 @return On Success, returns the number of bytes written to the file. The number
       
   125 		shall never be greater than cnt.
       
   126 		On Failure, returns -1, errno may be set.
       
   127 */
       
   128 EXPORT_C int write (int fd, const char *buf, size_t cnt)
       
   129 	{
       
   130 	struct _reent *r = _REENT2;
       
   131 	if (!r)
       
   132 		return -1; // Memory for library globals is not allocated (errno not set).
       
   133 	return _write_r (r, fd, buf, cnt);
       
   134 	}
       
   135 
       
   136 /** A reentrant version of write().
       
   137 */
       
   138 EXPORT_C int _write_r (struct _reent *r, int fd, const char *buf, size_t nbyte)
       
   139 	{
       
   140 	MSystemInterface& sysIf=Interface(r);
       
   141 	return sysIf.write(fd,buf,nbyte,r->_errno);
       
   142 	}
       
   143 
       
   144 /**
       
   145 Close a file.
       
   146 
       
   147 @return	On Success, returns 0. 
       
   148 		On Failure, returns -1, errno may be set.
       
   149 */
       
   150 EXPORT_C int close (int fd)
       
   151 	{
       
   152 	struct _reent *r = _REENT2;
       
   153 	if (!r)
       
   154 		return -1; // Memory for library globals is not allocated (errno not set).
       
   155 	return _close_r (r, fd);
       
   156 	}
       
   157 
       
   158 
       
   159 /** A reentrant version of close().
       
   160 */
       
   161 EXPORT_C int _close_r (struct _reent *r, int fd)
       
   162 	{
       
   163 	MSystemInterface& sysIf=Interface(r);
       
   164 	return sysIf.close(fd,r->_errno);
       
   165 	}
       
   166 
       
   167 /**
       
   168 Synchronizes a file's in-memory state with that on the physical medium.
       
   169 
       
   170 @param fd Is the file descriptor for the file to be synchronized.
       
   171 
       
   172 @return On Success, returns 0. 
       
   173 		On Failure, returns -1, errno may be set.
       
   174 */
       
   175 EXPORT_C int fsync (int fd)
       
   176 	{
       
   177 	struct _reent *r = _REENT2;
       
   178 	if (!r)
       
   179 		return -1; // Memory for library globals is not allocated (errno not set).
       
   180 	return _fsync_r (r, fd);
       
   181 	}
       
   182 
       
   183 /** A reentrant version of fsync().
       
   184 */
       
   185 EXPORT_C int _fsync_r (struct _reent *r, int fd)
       
   186 	{
       
   187 	MSystemInterface& sysIf=Interface(r);
       
   188 	return sysIf.fsync(fd,r->_errno);
       
   189 	}
       
   190 
       
   191 /**
       
   192 Repositions the read/write file offset.
       
   193 @return a nonnegative integer that indicates the file pointer value. 
       
   194 @param fd Is the file descriptor of an open file.
       
   195 @param pos Specifies the number of bytes to offset the file pointer 
       
   196 from a specified file origin.
       
   197 @param whence Specifies the location from which to start seeking.
       
   198 */
       
   199 EXPORT_C off_t lseek (int fd, off_t pos, int whence)
       
   200 	{
       
   201 	return _lseek_r (_REENT, fd, pos, whence);
       
   202 	}
       
   203 
       
   204 /** A reentrant version of fseek().
       
   205 */
       
   206 EXPORT_C off_t _lseek_r (struct _reent *r, int fd, off_t pos, int whence)
       
   207 	{
       
   208 	MSystemInterface& sysIf=Interface(r);
       
   209 	return sysIf.lseek(fd,pos,whence,r->_errno);
       
   210 	}
       
   211 
       
   212 /**
       
   213 Gets information about the named file and writes it to the area that buf points to.
       
   214 The system must be able to search all directories leading to the file; 
       
   215 however, read, write, or execute permission of the file is not required.
       
   216 
       
   217 @param fd Is a file descriptor referring to a file for which status is returned.
       
   218 @param st Points to a stat structure where status information about the file is to be placed.
       
   219 
       
   220 @return On Success, returns 0. 
       
   221 		On Failure, returns -1, errno may be set.
       
   222 */
       
   223 EXPORT_C int fstat (int fd, struct stat *st)
       
   224 	{
       
   225 	struct _reent *r = _REENT2;
       
   226 	if (!r)
       
   227 		return -1; // Memory for library globals is not allocated (errno not set).
       
   228 	return _fstat_r (r, fd, st);
       
   229 	}
       
   230 
       
   231 /** A reentrant version of fstat().
       
   232 */
       
   233 EXPORT_C int _fstat_r (struct _reent *r, int fd, struct stat *st) 
       
   234 	{
       
   235 	MSystemInterface& sysIf=Interface(r);
       
   236 	return sysIf.fstat(fd,st,r->_errno);
       
   237 	}
       
   238 
       
   239 /**
       
   240 Gets the size of a file. 
       
   241 
       
   242 @return On Success, returns 0. 
       
   243 		On Failure, returns -1, errno may be set.
       
   244 */
       
   245 EXPORT_C int stat (const char *name, struct stat *st)
       
   246 	{
       
   247 	struct _reent *r = _REENT2;
       
   248 	if (!r)
       
   249 		return -1; // Memory for library globals is not allocated (errno not set).
       
   250 	return _stat_r (r, name, st);
       
   251 	}
       
   252 
       
   253 /** A reentrant version of stat().
       
   254 */
       
   255 EXPORT_C int _stat_r (struct _reent *r, const char *name, struct stat *st) 
       
   256 	{
       
   257 	wchar_t tmpbuf[KMaxFullName+1];	
       
   258 	if (-1 != mbstowcs(tmpbuf, name, KMaxFullName))
       
   259 		{
       
   260 		MSystemInterface& sysIf=Interface(r);
       
   261 		return sysIf.stat(tmpbuf, st, r->_errno);
       
   262 		}
       
   263 	MapError(EILSEQ, r->_errno);		
       
   264 	return -1;
       
   265 	}
       
   266 
       
   267 /** 
       
   268 A wide_character version of a stat().
       
   269 */
       
   270 EXPORT_C int wstat (const wchar_t *name, struct stat *st)
       
   271 	{
       
   272 	struct _reent *r = _REENT2;
       
   273 	if (!r)
       
   274 		return -1; // Memory for library globals is not allocated (errno not set).
       
   275 	return _wstat_r (r, name, st);
       
   276 	}
       
   277 
       
   278 /** A reentrant version of wstat().
       
   279 */
       
   280 EXPORT_C int _wstat_r (struct _reent *r, const wchar_t *name, struct stat *st) 
       
   281 	{
       
   282 	MSystemInterface& sysIf=Interface(r);
       
   283 	return sysIf.stat(name,st,r->_errno);
       
   284 	}
       
   285 
       
   286 /**
       
   287 Duplicates an open file descriptor. 
       
   288 		
       
   289 @param aFid Is the file descriptor to duplicate.
       
   290 
       
   291 @return On Success, returns a non-negative integer, namely the duplicated file descriptor, which
       
   292 		is the lowest available descriptor. 
       
   293 		On Failure, returns -1, errno may be set.
       
   294 */
       
   295 EXPORT_C int dup (int aFid)
       
   296 	{
       
   297 	struct _reent *r = _REENT2;
       
   298 	if (!r)
       
   299 		return -1; // Memory for library globals is not allocated (errno not set).
       
   300 	return _dup_r(r, aFid);
       
   301 	}
       
   302 
       
   303 /** A reentrant version of dup().
       
   304 */
       
   305 EXPORT_C int _dup_r (struct _reent *r, int aFid)
       
   306 	{
       
   307 	MSystemInterface& sysIf=Interface(r);
       
   308 	return sysIf.dup(aFid,r->_errno);
       
   309 	}
       
   310 
       
   311 /**
       
   312 Function duplicates an open file descriptor. 
       
   313 
       
   314 @param aFid1 Is the file descriptor to duplicate.
       
   315 @param aFid2 Is the file descriptor that filedes is duplicated onto.
       
   316 
       
   317 @return On Success, returns a non-negative integer, namely the duplicated file descriptor, which
       
   318 		is the lowest available descriptor. 
       
   319 		On Failure, returns -1, errno may be set.
       
   320 */
       
   321 EXPORT_C int dup2 (int aFid1, int aFid2)
       
   322 	{
       
   323 	struct _reent *r = _REENT2;
       
   324 	if (!r)
       
   325 		return -1; // Memory for library globals is not allocated (errno not set).
       
   326 	return _dup2_r(r, aFid1, aFid2);
       
   327 	}
       
   328 
       
   329 /** A reentrant version of dup2().
       
   330 */
       
   331 EXPORT_C int _dup2_r (struct _reent *r, int aFid1, int aFid2)
       
   332 	{
       
   333 	MSystemInterface& sysIf=Interface(r);
       
   334 	return sysIf.dup2(aFid1,aFid2,r->_errno);
       
   335 	}
       
   336 
       
   337 /**
       
   338 Performs a variety of device-specific control functions on device special files.
       
   339 
       
   340 @return On Success, returns a value other than -1 that depends upon the STREAMS device control function. 
       
   341         On Failure, return -1, errno may be set.
       
   342 */
       
   343 EXPORT_C int ioctl (int aFid, int aCmd, void* aParam)
       
   344 	{
       
   345 	struct _reent *r = _REENT2;
       
   346 	if (!r)
       
   347 		return -1; // Memory for library globals is not allocated (errno not set).
       
   348 	return _ioctl_r(r, aFid, aCmd, aParam);
       
   349 	}
       
   350 
       
   351 /** A reentrant version of ioctl().
       
   352 */
       
   353 EXPORT_C int _ioctl_r (struct _reent *r, int aFid, int aCmd, void* aParam)
       
   354 	{
       
   355 	MSystemInterface& sysIf=Interface(r);
       
   356 	return sysIf.ioctl(aFid,aCmd,aParam,r->_errno);
       
   357 	}
       
   358 
       
   359 /**
       
   360 Gets the path name of the current working directory.
       
   361 If a buffer is specified, the path name is placed in that buffer,
       
   362 and the address of the buffer is returned. 
       
   363 @return If successful returns buf, if a non-null pointer was specified, 
       
   364 or the address of the allocated memory otherwise. 
       
   365 @param _buf Points to the buffer to copy the current working directory to, 
       
   366 or NULL if getcwd() should allocate the buffer.
       
   367 @param _size Is the size, in bytes, of the array of characters that buf points to.
       
   368 */
       
   369 EXPORT_C char* getcwd (char *_buf, size_t _size)
       
   370 	{
       
   371 	return _getcwd_r(_REENT,_buf,_size);
       
   372 	}
       
   373 
       
   374 /** 
       
   375 A wide_character version of a getcwd().
       
   376 */
       
   377 EXPORT_C wchar_t* wgetcwd (wchar_t *_buf, size_t _size)
       
   378 	{
       
   379 	return _wgetcwd_r(_REENT,_buf,_size);
       
   380 	}
       
   381 
       
   382 /** A reentrant version of getcwd().
       
   383 */
       
   384 EXPORT_C char* _getcwd_r (struct _reent *r, char *_buf, size_t _size)
       
   385 	{
       
   386 	char * _ourbuf = _buf;
       
   387 	if (_buf==0)
       
   388 		{
       
   389 		_ourbuf=(char*)User::Alloc(_size);
       
   390 		if (_ourbuf==0)
       
   391 			{
       
   392 			r->_errno=ENOMEM;
       
   393 			return _buf;
       
   394 			}
       
   395 		}
       
   396 
       
   397 	//we are dealing with wide characters from here so we need a temporary buffer
       
   398 	wchar_t tmpbuf[KMaxFullName];
       
   399 
       
   400 	MSystemInterface& sysIf=Interface(r);
       
   401 	wchar_t * rval = sysIf.getcwd((wchar_t*)tmpbuf, _size, r->_errno);
       
   402 	
       
   403 	if (rval)	//we have a path
       
   404 		{
       
   405 		//convert it to UTF8
       
   406 		size_t x = wcstombs(_ourbuf, tmpbuf, _size);	//convert the buffer
       
   407 		return _ourbuf;
       
   408 		}
       
   409 	//deal with the fact we may have allocated our own buffer
       
   410 	if (_buf != _ourbuf)  //we allocated it.
       
   411 		User::Free(_ourbuf);
       
   412 	return NULL;
       
   413 	}
       
   414 
       
   415 /** A wide-character version of reentrant of getcwd().
       
   416 */
       
   417 EXPORT_C wchar_t * _wgetcwd_r (struct _reent *r, wchar_t *_buf, size_t _size)
       
   418 	{
       
   419 	if (_buf==0)
       
   420 		{
       
   421 		_buf=(wchar_t *)User::Alloc(_size*sizeof(wchar_t));
       
   422 		if (_buf==0)
       
   423 			{
       
   424 			r->_errno=ENOMEM;
       
   425 			return _buf;
       
   426 			}
       
   427 		}
       
   428 	MSystemInterface& sysIf=Interface(r);
       
   429 	return sysIf.getcwd(_buf,_size,r->_errno);
       
   430 	}
       
   431 
       
   432 /**
       
   433 Changes the current working directory to be pathname. The current directory is the
       
   434 beginning point for file searches when path names are not absolute. 
       
   435 If the chdir() function fails, the current working directory remains unchanged.
       
   436 
       
   437 @param _path Is the path name of a directory.
       
   438 
       
   439 @return On Success, returns 0. 
       
   440 		On Failure, returns -1, errno may be set.
       
   441 */
       
   442 EXPORT_C int chdir (const char *_path)
       
   443 	{
       
   444 	struct _reent *r = _REENT2;
       
   445 	if (!r)
       
   446 		return -1; // Memory for library globals is not allocated (errno not set).
       
   447 	return _chdir_r(r, _path);
       
   448 	}
       
   449 
       
   450 /** A reentrant version of chdir().
       
   451 */
       
   452 EXPORT_C int _chdir_r (struct _reent *r, const char *_path)
       
   453 	{
       
   454 	//we need to use a wide buffer and convert
       
   455 	wchar_t tmpbuf[KMaxFullName+1];		//use the max path length possible
       
   456 	if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName))
       
   457 		{
       
   458 		MSystemInterface& sysIf=Interface(r);
       
   459 		return sysIf.chdir(tmpbuf, r->_errno);
       
   460 		}
       
   461 	MapError(EILSEQ, r->_errno);		
       
   462 	return -1;
       
   463 	}
       
   464 
       
   465 /** A wide-character version of chdir().
       
   466 */
       
   467 EXPORT_C int wchdir (const wchar_t *_path)
       
   468 	{
       
   469 	struct _reent *r = _REENT2;
       
   470 	if (!r)
       
   471 		return -1; // Memory for library globals is not allocated (errno not set).
       
   472 	return _wchdir_r(r, _path);
       
   473 	}
       
   474 
       
   475 /** A reentrant version of wchdir().
       
   476 */
       
   477 EXPORT_C int _wchdir_r (struct _reent *r, const wchar_t *_path)
       
   478 	{
       
   479 	MSystemInterface& sysIf=Interface(r);
       
   480 	return sysIf.chdir(_path,r->_errno);
       
   481 	}
       
   482 
       
   483 /**
       
   484 Removes an empty directory whose name is given by pathname.
       
   485 The directory must not have any entries other than dot (.) and dot-dot (..).
       
   486 
       
   487 @param _path Points to the directory that the rmdir() function removes.
       
   488 
       
   489 @return On Success, returns 0. 
       
   490 		On Failure, returns -1, errno may be set.
       
   491 */
       
   492 EXPORT_C int rmdir (const char *_path)
       
   493 	{
       
   494 	struct _reent *r = _REENT2;
       
   495 	if (!r)
       
   496 		return -1; // Memory for library globals is not allocated (errno not set).
       
   497 	return _rmdir_r(r, _path);
       
   498 	}
       
   499 
       
   500 /** A reentrant version of rmdir().
       
   501 */
       
   502 EXPORT_C int _rmdir_r (struct _reent *r, const char *_path)
       
   503 	{
       
   504 	wchar_t tmpbuf[KMaxFullName+1];		//use the max path length possible
       
   505 	if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName))
       
   506 		{
       
   507 		MSystemInterface& sysIf=Interface(r);
       
   508 		return sysIf.rmdir(tmpbuf, r->_errno);
       
   509 		}
       
   510 	MapError(EILSEQ, r->_errno);		
       
   511 	return -1;
       
   512 	}
       
   513 
       
   514 /** A wide-character version of rmdir().
       
   515 */
       
   516 EXPORT_C int wrmdir (const wchar_t *_path)
       
   517 	{
       
   518 	struct _reent *r = _REENT2;
       
   519 	if (!r)
       
   520 		return -1; // Memory for library globals is not allocated (errno not set).
       
   521 	return _wrmdir_r(r,_path);
       
   522 	}
       
   523 
       
   524 /** A reentrant version of wrmdir().
       
   525 */
       
   526 EXPORT_C int _wrmdir_r (struct _reent *r, const wchar_t *_path)
       
   527 	{
       
   528 	MSystemInterface& sysIf=Interface(r);
       
   529 	return sysIf.rmdir(_path,r->_errno);
       
   530 	}
       
   531 
       
   532 /**
       
   533 Creates a new directory with the specified path name. 
       
   534 The file permissions of the new directory are initialized from the specified mode. 
       
   535 
       
   536 @param _path Specifies the name of the new directory. The path name can be absolute or relative. 
       
   537 	   If the specified path name is relative, the directory is created based upon your current
       
   538 	   working directory.
       
   539 @param _mode Is a bitwise-OR field that specifies what permissions the directory has when it is created.
       
   540 
       
   541 @return On Success, returns 0. 
       
   542 		On Failure, returns -1, errno may be set. Does not create a directory.
       
   543 */
       
   544 EXPORT_C int mkdir (const char *_path, mode_t _mode)
       
   545 	{
       
   546 	struct _reent *r = _REENT2;
       
   547 	if (!r)
       
   548 		return -1; // Memory for library globals is not allocated (errno not set).
       
   549 	return _mkdir_r(r,_path,_mode);
       
   550 	}
       
   551 
       
   552 /** A reentrant version of mkdir().
       
   553 */
       
   554 EXPORT_C int _mkdir_r (struct _reent *r, const char *_path, mode_t _mode)
       
   555 	{
       
   556 	//we need to use a wide buffer and convert
       
   557 	wchar_t tmpbuf[KMaxFullName+1];		//use the max path length possible
       
   558 	if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName))
       
   559 		{
       
   560 		MSystemInterface& sysIf=Interface(r);
       
   561 		return sysIf.mkdir(tmpbuf, _mode, r->_errno);
       
   562 		}
       
   563 	MapError(EILSEQ, r->_errno);		
       
   564 	return -1;
       
   565 	}
       
   566 
       
   567 /** A wide-character version of mkdir().
       
   568 */
       
   569 EXPORT_C int wmkdir (const wchar_t *_path, mode_t _mode)
       
   570 	{
       
   571 	struct _reent *r = _REENT2;
       
   572 	if (!r)
       
   573 		return -1; // Memory for library globals is not allocated (errno not set).
       
   574 	return _wmkdir_r(r, _path, _mode);
       
   575 	}
       
   576 
       
   577 /** A reentrant version of wmkdir().
       
   578 */
       
   579 EXPORT_C int _wmkdir_r (struct _reent *r, const wchar_t *_path, mode_t _mode)
       
   580 	{
       
   581 	MSystemInterface& sysIf=Interface(r);
       
   582 	return sysIf.mkdir(_path,_mode,r->_errno);
       
   583 	}
       
   584 
       
   585 /**
       
   586 Sets the access permissions for the file whose name is given by pathname to the bit
       
   587 pattern contained in mode. For this call to succeed, the effective user ID of the
       
   588 process must match the owner of the file, or the process must have appropriate privileges. 
       
   589 The owner of the file pathname always has privileges to change permission modes and file attributes.
       
   590 
       
   591 @param _path Points to the name of the file.
       
   592 @param _mode Is a bitwise-or field that specifies the new permission modes for path name.
       
   593 
       
   594 @return On Success, returns 0. 
       
   595 		On Failure, returns -1, errno may be set.
       
   596 */
       
   597 EXPORT_C int chmod (const char *_path, mode_t _mode)
       
   598 	{
       
   599 	struct _reent *r = _REENT2;
       
   600 	if (!r)
       
   601 		return -1; // Memory for library globals is not allocated (errno not set).
       
   602 	return _chmod_r(r, _path, _mode);
       
   603 	}
       
   604 
       
   605 /** A reentrant version of chmod().
       
   606 */
       
   607 EXPORT_C int _chmod_r (struct _reent *r, const char *_path, mode_t _mode)
       
   608 	{
       
   609 	wchar_t tmpbuf[KMaxFullName+1];	
       
   610 	if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName))
       
   611 		{
       
   612 		MSystemInterface& sysIf=Interface(r);
       
   613 		return sysIf.chmod(tmpbuf,_mode,r->_errno);
       
   614 		}
       
   615 	MapError(EILSEQ, r->_errno);		
       
   616 	return -1;
       
   617 	}
       
   618 
       
   619 /** A wide-character version of chmod().
       
   620 */
       
   621 EXPORT_C int wchmod (const wchar_t *_path, mode_t _mode)
       
   622 	{
       
   623 	struct _reent *r = _REENT2;
       
   624 	if (!r)
       
   625 		return -1; // Memory for library globals is not allocated (errno not set).
       
   626 	return _wchmod_r(r, _path, _mode);
       
   627 	}
       
   628 
       
   629 /** A reentrant version of wchmod().
       
   630 */
       
   631 EXPORT_C int _wchmod_r (struct _reent *r, const wchar_t *_path, mode_t _mode)
       
   632 	{
       
   633 	MSystemInterface& sysIf=Interface(r);
       
   634 	return sysIf.chmod(_path,_mode,r->_errno);
       
   635 	}
       
   636 
       
   637 /**
       
   638 Removes a link to a file, and decrements the link count of the referenced file by one. When
       
   639 the file's link count becomes 0 and no process has the file open, the space occupied by the
       
   640 file is freed, and the file is no longer accessible. If one or more processes have the file
       
   641 open when the last link is removed, the link is removed before unlink() returns, but the
       
   642 removal of the file contents is postponed until all references to the file are closed.
       
   643 
       
   644 @param _path Points to the path name that names the file to be unlinked.
       
   645 
       
   646 @return On Success, returns 0. 
       
   647 		On Failure, returns -1, errno may be set.
       
   648 */
       
   649 EXPORT_C int unlink (const char *_path)
       
   650 	{
       
   651 	struct _reent *r = _REENT2;
       
   652 	if (!r)
       
   653 		return -1; // Memory for library globals is not allocated (errno not set).
       
   654 	return _unlink_r(r, _path);
       
   655 	}
       
   656 
       
   657 /** A reentrant version of unlink().
       
   658 */
       
   659 EXPORT_C int _unlink_r (struct _reent *r, const char *_path)
       
   660 	{
       
   661 	wchar_t tmpbuf[KMaxFullName+1];		
       
   662 	if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName))
       
   663 		{
       
   664 		MSystemInterface& sysIf=Interface(r);
       
   665 		return sysIf.unlink(tmpbuf, r->_errno);
       
   666 		}
       
   667 	MapError(EILSEQ, r->_errno);		
       
   668 	return -1;
       
   669 	}
       
   670 
       
   671 /** A wide-character version of unlink().
       
   672 */
       
   673 EXPORT_C int wunlink (const wchar_t *_path)
       
   674 	{
       
   675 	struct _reent *r = _REENT2;
       
   676 	if (!r)
       
   677 		return -1; // Memory for library globals is not allocated (errno not set).
       
   678 	return _wunlink_r(r, _path);
       
   679 	}
       
   680 
       
   681 /** A wide-character version of reentrant of unlink().
       
   682 */
       
   683 EXPORT_C int _wunlink_r (struct _reent *r, const wchar_t *_path)
       
   684 	{
       
   685 	MSystemInterface& sysIf=Interface(r);
       
   686 	return sysIf.unlink(_path,r->_errno);
       
   687 	}
       
   688 
       
   689 /**
       
   690 Renames a file. 
       
   691 
       
   692 @param oldpath Points to the path name of the file to be renamed. The path name can be
       
   693 	   absolute or relative. If a relative path name is given, the file is searched from
       
   694 	   the current working directory.
       
   695 @param newpath Points to the path name of the file. The path name can be absolute or relative. 
       
   696 	   If a relative path name is given, the file is searched from the current working directory.
       
   697 
       
   698 @return On Success, returns 0. 
       
   699 		On Failure, returns -1, errno may be set. Does not change either the file named
       
   700 		by old or the file named by new (if either exists).
       
   701 */
       
   702 EXPORT_C int rename (const char *oldpath, const char *newpath)
       
   703 	{
       
   704 	struct _reent *r = _REENT2;
       
   705 	if (!r)
       
   706 		return -1; // Memory for library globals is not allocated (errno not set).
       
   707 	return _rename_r (r, oldpath, newpath);
       
   708 	}
       
   709 
       
   710 /** A reentrant version of rename().
       
   711 */
       
   712 EXPORT_C int _rename_r (struct _reent *r, const char *oldpath, const char *newpath)
       
   713 	{
       
   714 	wchar_t _old[KMaxFullName+1];		
       
   715 	wchar_t _new[KMaxFullName+1];		
       
   716 	if (-1 != mbstowcs(_old, oldpath, KMaxFullName))
       
   717 		{
       
   718 		if (-1 != mbstowcs(_new, newpath, KMaxFullName))
       
   719 			{
       
   720 			MSystemInterface& sysIf=Interface(r);
       
   721 			return sysIf.rename(_old, _new, r->_errno);
       
   722 			}
       
   723 		}
       
   724 	MapError(EILSEQ, r->_errno);		
       
   725 	return -1;
       
   726 	}
       
   727 
       
   728 /** A wide-character version of rename().
       
   729 */
       
   730 EXPORT_C int wrename (const wchar_t *oldpath, const wchar_t *newpath)
       
   731 	{
       
   732 	struct _reent *r = _REENT2;
       
   733 	if (!r)
       
   734 		return -1; // Memory for library globals is not allocated (errno not set).
       
   735 	return _wrename_r (r, oldpath, newpath);
       
   736 	}
       
   737 
       
   738 /** A wide-character version of reentrant of rename().
       
   739 */
       
   740 EXPORT_C int _wrename_r (struct _reent *r, const wchar_t *oldpath, const wchar_t *newpath)
       
   741 	{
       
   742 	MSystemInterface& sysIf=Interface(r);
       
   743 	return sysIf.rename(oldpath,newpath,r->_errno);
       
   744 	}
       
   745 
       
   746 /**
       
   747 Takes a specified path name, pathname and resolves all symbolic links,
       
   748 extra slashes (/), and references to /./ and /../. 
       
   749 The resulting absolute path name is placed in the memory location 
       
   750 pointed to by the resolved_path argument.
       
   751 @return resolved_path. 
       
   752 When an error occurs,returns a null pointer, setsresolved_path 
       
   753 to the path name that caused the error.
       
   754 @param path Points to the path name that you want resolved to an absolute form. 
       
   755 This may be either a relative or absolute path name. 
       
   756 All but the final component of this path name must exist when you call realpath().
       
   757 @param resolved Points to the location where the canonical version
       
   758 of pathname is to be placed. 
       
   759 */
       
   760 EXPORT_C char* realpath (const char* path, char* resolved)
       
   761 	{
       
   762 	return _realpath_r(_REENT, path, resolved);
       
   763 	}
       
   764 
       
   765 /** A wide-character version of realpath().
       
   766 */
       
   767 EXPORT_C wchar_t* wrealpath (const wchar_t* path, wchar_t* resolved)
       
   768 	{
       
   769 	return _wrealpath_r(_REENT, path, resolved);
       
   770 	}
       
   771 
       
   772 /** A wide-character version of reentrant of realpath().
       
   773 */
       
   774 EXPORT_C wchar_t * _wrealpath_r (struct _reent *r, const wchar_t *relpath, wchar_t *resolved)
       
   775 	{
       
   776 
       
   777 	TPtr16 name((TText16*)resolved,MAXPATHLEN);
       
   778 	TParse path;
       
   779 	MSystemInterface& sysIf=Interface(r);
       
   780 	TInt err = sysIf.ResolvePath(path, relpath, &name);
       
   781 	if (!err)
       
   782 		{
       
   783 		err = path.SetNoWild(path.DriveAndPath(),NULL,&name);
       
   784 		if (!err)
       
   785 			{
       
   786 			name = path.FullName();
       
   787 			name.ZeroTerminate();
       
   788 			return resolved;
       
   789 			}
       
   790 		}
       
   791 	MapError(err,r->_errno);
       
   792 	return 0;
       
   793 	}
       
   794 
       
   795 /** A reentrant version of realpath().
       
   796 */
       
   797 EXPORT_C char* _realpath_r (struct _reent *r, const char *relpath, char *resolved)
       
   798 	{
       
   799 
       
   800 	TFileName name;
       
   801 	TInt err;
       
   802 	
       
   803 	TParse path;
       
   804 	MSystemInterface& sysIf=Interface(r);
       
   805 
       
   806 	wchar_t _wrelpath[KMaxFileName];
       
   807 
       
   808 	if (-1 != mbstowcs(_wrelpath, relpath , KMaxFileName))
       
   809 		{
       
   810 		err = sysIf.ResolvePath(path, _wrelpath, &name);
       
   811 		if (!err)
       
   812 			{
       
   813 			err = path.SetNoWild(path.DriveAndPath(),NULL,&name);
       
   814 			if (!err)
       
   815 				{
       
   816 				name = path.FullName();
       
   817 
       
   818 				if (-1 != wcstombs(resolved, (wchar_t*)name.PtrZ(), KMaxFileName))
       
   819 					return resolved;
       
   820 				else
       
   821 					{
       
   822 					err = EILSEQ;
       
   823 					}
       
   824 				}
       
   825 			}
       
   826 		}
       
   827 		else
       
   828 		{
       
   829 		err = EILSEQ;
       
   830 		}
       
   831 
       
   832 	MapError(err,r->_errno);
       
   833 	return 0;
       
   834 	}
       
   835 
       
   836 /**
       
   837 Gives access to the client's stdin.
       
   838 
       
   839 @return On Success, returns a pointer to an open stream, used to read or write to the pipe.
       
   840 		On Failure, return a null pointer.
       
   841 */
       
   842 EXPORT_C int popen3 (const char* cmd, const char* mode, char** env, int fids[3])
       
   843 	{
       
   844     struct _reent *r = _REENT2;
       
   845 	if (!r)
       
   846 		return NULL; // Memory for library globals is not allocated (errno not set).
       
   847 	return _popen3_r (r,cmd,mode,env,fids);
       
   848 	}
       
   849 
       
   850 /** A wide-character version of popen3().
       
   851 */
       
   852 EXPORT_C int wpopen3 (const wchar_t* cmd, const wchar_t* mode, wchar_t** env, int fids[3])
       
   853 	{
       
   854     struct _reent *r = _REENT2;
       
   855 	if (!r)
       
   856 		return NULL; // Memory for library globals is not allocated (errno not set).
       
   857 	return _wpopen3_r (r,cmd,mode,env,fids);
       
   858 	}
       
   859 
       
   860 /** A reentrant version of a popen3().
       
   861 */
       
   862 EXPORT_C int _popen3_r (struct _reent *r, const char* cmd, const char* mode, char** env, int fids[3])
       
   863 	{
       
   864 
       
   865 	wchar_t wcmd[MAXPATHLEN+1];
       
   866 	wchar_t wmode[MAXPATHLEN+1];
       
   867 
       
   868 	wchar_t ** wenv = NULL;
       
   869 	wchar_t * buf = NULL;
       
   870 	
       
   871 	TInt ret = 0;
       
   872 
       
   873 	if ((-1 != mbstowcs(wcmd, cmd, MAXPATHLEN)) && 
       
   874 		(-1 != mbstowcs(wmode, mode, MAXPATHLEN)))
       
   875 		{
       
   876 		//OK, we've widened the first 2 args
       
   877 		//now for the environment
       
   878 
       
   879 		//env is basically an array of char pointers with a NULL as the last one
       
   880 		if (env)
       
   881 			{
       
   882 			//OK we have a ptr to something
       
   883 			//count the number of entries and get their lengths so we can work out how much space
       
   884 			//is needed for the new one
       
   885 
       
   886 			TInt count = 0;
       
   887 			TInt total = 0;
       
   888 			while (env[count] != NULL)
       
   889 				{
       
   890 				total+= strlen(env[count])+1;
       
   891 				count++;
       
   892 				}
       
   893 			//total has number of bytes in the strings
       
   894 			//max number of unicode chars is with a 1 to 1 mapping.
       
   895 			wenv = (wchar_t**)malloc(1 + count*sizeof(wchar_t*));
       
   896 			buf = (wchar_t*)malloc(2*total);
       
   897 			
       
   898 			if (!(wenv && buf))		//we've had a malloc failure
       
   899 				{
       
   900 				r->_errno = ENOMEM;
       
   901 				goto bailout;
       
   902 				}
       
   903 
       
   904 			wchar_t* p = buf;
       
   905 
       
   906 			TInt ret;
       
   907 			for (TInt x = 0; x < count; x++)
       
   908 				{
       
   909 				wenv[count] = p;
       
   910 				ret = mbstowcs(p, env[count], MAXPATHLEN);
       
   911 				if (ret >= 0)
       
   912 					{
       
   913 						p += ret;	//step to next bit of space
       
   914 					}
       
   915 				else
       
   916 					{
       
   917 					r->_errno = EILSEQ;
       
   918 					goto bailout;
       
   919 					}
       
   920 
       
   921 				}
       
   922 			}
       
   923 
       
   924 
       
   925 		ret =  _wpopen3_r(r, wcmd, wmode, wenv, fids);
       
   926 		}
       
   927 	else
       
   928 		{
       
   929 		r->_errno = EILSEQ;
       
   930 		}
       
   931 
       
   932 	//don't lose the memory
       
   933 bailout:
       
   934 	free(wenv);
       
   935 	free(buf);
       
   936 
       
   937 	return ret;
       
   938 	}
       
   939 
       
   940 /** A wide-character version of reentrant of popen3().
       
   941 */
       
   942 EXPORT_C int _wpopen3_r (struct _reent *r, const wchar_t* cmd, const wchar_t* mode, wchar_t** env, int fids[3])
       
   943 	{
       
   944 	// Find the full path of the thing we are executing...
       
   945 	const wchar_t* cp=cmd;
       
   946 	while (*cp==L' ')
       
   947 		++cp;	// skip leading spaces
       
   948 	wchar_t file[MAXPATHLEN+1];
       
   949 	TInt i=0;
       
   950 	wchar_t c=0;
       
   951 	for (i=0; i<MAXPATHLEN; i++, cp++)
       
   952 		{
       
   953 		c=*cp;
       
   954 		file[i]=c;
       
   955 		if (c==L' ' || c==L'\t' || c==L'\0')	// stop at first space, tab or \0  
       
   956 			break;
       
   957 		}
       
   958 	file[i]=L'\0';
       
   959 	wchar_t resolved[MAXPATHLEN+1];
       
   960 	if(_wrealpath_r(r, file, resolved)==0)
       
   961 		return -1;	// no such file
       
   962 
       
   963 	// Strip leading whitespace from the rest of the commandline
       
   964 	for (; i<MAXPATHLEN;i++,cp++)
       
   965 		{
       
   966 		c=*cp;
       
   967 		if (c=='\0')
       
   968 			break;
       
   969 		if ((c!=' ') && (c!='\t'))
       
   970 			break;
       
   971 		}
       
   972 
       
   973 	fids[0]=-2;
       
   974 	fids[1]=-2;
       
   975 	fids[2]=-2;
       
   976 	const wchar_t* mp=mode;
       
   977 	while (*mp)
       
   978 		{
       
   979 		wchar_t c=*mp++;
       
   980 		if (c==L'r')
       
   981 			fids[0]=-1;
       
   982 		else if (c==L'w')
       
   983 			fids[1]=-1;
       
   984 		else if (c==L'e')
       
   985 			fids[2]=-1;
       
   986 		}
       
   987 
       
   988 	MSystemInterface& sysIf=Interface(r);
       
   989 	return sysIf.popen3(resolved,cp,mode,env,fids,r->_errno);
       
   990 	}
       
   991 
       
   992 /**
       
   993 Lets the calling process obtain status information about one of its child processes.
       
   994 If status information is available for two or more child processes, the order in
       
   995 which their status is reported is unspecified.
       
   996 
       
   997 @param pid Specifies a set of child processes for which the status is requested
       
   998 @param status Specifies the location to which the child process' exit status is stored.
       
   999 @param options Is the bitwise inclusive-OR of zero or more of the following flags.
       
  1000 
       
  1001 @return On Success, returns a value equal to the process ID of the child process.
       
  1002 		On Failure, returns -1 and errno may be set OR returns 0 if the status is not available
       
  1003 		for the specified process and it's set not to hang in the options.
       
  1004 */
       
  1005 EXPORT_C int waitpid (int pid, int* status, int options)
       
  1006 	{
       
  1007 	struct _reent *r = _REENT2;
       
  1008 	if (!r)
       
  1009 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1010 	return _waitpid_r (r, pid, status, options);
       
  1011 	}
       
  1012 
       
  1013 /** A reentrant version of waitpid().
       
  1014 */
       
  1015 EXPORT_C int _waitpid_r (struct _reent *r, int pid, int* status, int options)
       
  1016 	{
       
  1017 	MSystemInterface& sysIf=Interface(r);
       
  1018 	return sysIf.waitpid(pid,status,options,r->_errno);
       
  1019 	}
       
  1020 
       
  1021 /**
       
  1022 Calls reentrant version of waitpid().
       
  1023 */
       
  1024 EXPORT_C int wait (int* status)
       
  1025 	{
       
  1026 	struct _reent *r = _REENT2;
       
  1027 	if (!r)
       
  1028 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1029 	return _waitpid_r (r, -1, status, 0);
       
  1030 	}
       
  1031 
       
  1032 /** A reentrant version of wait().
       
  1033 */
       
  1034 EXPORT_C int _wait_r (struct _reent *r, int* status)
       
  1035 	{
       
  1036 	return _waitpid_r (r,-1,status,0);
       
  1037 	}
       
  1038 
       
  1039 /**
       
  1040 Execute command.
       
  1041 
       
  1042 @param cmd Null-terminated string containing the system command to be executed.
       
  1043 
       
  1044 @return On Success, the command interpreter returns an adequate value; generally 0
       
  1045         indicates that the action performed by the command interpreter terminated
       
  1046         with no errors. 
       
  1047         On Failure, return -1.
       
  1048 */
       
  1049 EXPORT_C int system (const char* cmd)
       
  1050 	{
       
  1051 	struct _reent *r = _REENT2;
       
  1052 	if (!r)
       
  1053 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1054 	return _system_r (r, cmd);
       
  1055 	}
       
  1056 
       
  1057 /** A reentrant version of system().
       
  1058 */
       
  1059 EXPORT_C int _system_r (struct _reent *r, const char* cmd)
       
  1060 	{
       
  1061 	if (cmd==0)
       
  1062 		return 1;	// special case, says that we do support system().
       
  1063 	int fids[3];
       
  1064 	int pid=_popen3_r(r, cmd, "", 0, fids);
       
  1065 	if (pid<0)
       
  1066 		return -1;
       
  1067 	int status=0;
       
  1068 	pid=_waitpid_r (r,pid,&status,0);
       
  1069 	if (pid<0)
       
  1070 		return -1;
       
  1071 	return status;
       
  1072 	}
       
  1073 
       
  1074 /** A wide-character version of a system().
       
  1075 */
       
  1076 EXPORT_C int wsystem (const wchar_t* cmd)
       
  1077 	{
       
  1078 	struct _reent *r = _REENT2;
       
  1079 	if (!r)
       
  1080 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1081 	return _wsystem_r (r, cmd);
       
  1082 	}
       
  1083 
       
  1084 /** A wide-character version of reentrant of system().
       
  1085 */
       
  1086 EXPORT_C int _wsystem_r (struct _reent *r, const wchar_t* cmd)
       
  1087 	{
       
  1088 	if (cmd==0)
       
  1089 		return 1;	// special case, says that we do support system().
       
  1090 	int fids[3];
       
  1091 	int pid=_wpopen3_r(r, cmd, (wchar_t*)L"", 0, fids);
       
  1092 	if (pid<0)
       
  1093 		return -1;
       
  1094 	int status=0;
       
  1095 	pid=_waitpid_r (r,pid,&status,0);
       
  1096 	if (pid<0)
       
  1097 		return -1;
       
  1098 	return status;
       
  1099 	}
       
  1100 
       
  1101 } // extern "C"
       
  1102 
       
  1103 #include <estlib.h>
       
  1104 
       
  1105 /** Dubious asynchronous interface to ioctl, must be called from C++
       
  1106 
       
  1107 @return On Success, returns a value other than -1.
       
  1108 		On Failure, returns -1 and errno may be set.
       
  1109 */
       
  1110 EXPORT_C int ioctl (int aFid, int aCmd, void* aParam, TRequestStatus& aStatus)
       
  1111 	{
       
  1112 	struct _reent *r = _REENT2;
       
  1113 	if (!r)
       
  1114 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1115 	return _ioctl_r(r, aFid, aCmd, aParam, aStatus);
       
  1116 	}
       
  1117 
       
  1118 /** A reentrant version of a ioctl().
       
  1119 */
       
  1120 EXPORT_C int _ioctl_r (struct _reent *r, int aFid, int aCmd, void* aParam, TRequestStatus& aStatus)
       
  1121 	{
       
  1122 	MSystemInterface& sysIf=Interface(r);
       
  1123 	return sysIf.ioctl(aFid,aCmd,aParam,aStatus,r->_errno);
       
  1124 	}
       
  1125 
       
  1126 EXPORT_C int ioctl_complete (int aFid, int aCmd, void* aParam, TRequestStatus& aStatus)
       
  1127 	{
       
  1128 	struct _reent *r = _REENT2;
       
  1129 	if (!r)
       
  1130 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1131 	return _ioctl_complete_r(r, aFid, aCmd, aParam, aStatus);
       
  1132 	}
       
  1133 
       
  1134 /** A reentrant version of a ioctl_complete().
       
  1135 */
       
  1136 EXPORT_C int _ioctl_complete_r (struct _reent *r, int aFid, int aCmd, void* aParam, TRequestStatus& aStatus)
       
  1137 	{
       
  1138 	MSystemInterface& sysIf=Interface(r);
       
  1139 	return sysIf.ioctl_complete(aFid,aCmd,aParam,aStatus,r->_errno);
       
  1140 	}
       
  1141 
       
  1142 EXPORT_C int ioctl_cancel (int aFid)
       
  1143 	{
       
  1144 	struct _reent *r = _REENT2;
       
  1145 	if (!r)
       
  1146 		return -1; // Memory for library globals is not allocated (errno not set).
       
  1147 	return _ioctl_cancel_r(r, aFid);
       
  1148 	}
       
  1149 
       
  1150 /** A reentrant version of a ioctl_cancel().
       
  1151 */
       
  1152 EXPORT_C int _ioctl_cancel_r (struct _reent *r, int aFid)
       
  1153 	{
       
  1154 	MSystemInterface& sysIf=Interface(r);
       
  1155 	return sysIf.ioctl_cancel(aFid,r->_errno);
       
  1156 	}
       
  1157