os/ossrv/genericopenlibs/cstdlib/LPOSIX/SYSCALLS.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
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".
     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