genericopenlibs/openenvcore/libc/src/Fmscalls.cpp
changeset 0 e4d67989cc36
child 64 c44f36bb61a3
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: connectors for re-entrant system calls
       
    15 */
       
    16 
       
    17 
       
    18 // connectors for re-entrant system calls
       
    19 
       
    20 #include "sysif.h"
       
    21 #include "lposix.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 <sys/stat.h>
       
    28 #include <utf.h>
       
    29 #include <string.h>
       
    30 #include <unistd.h>
       
    31 #include <sys/types.h>
       
    32 #include "sysreent.h"
       
    33 #include <sys/aeselect.h>
       
    34 #include "aeselectreent.h"
       
    35 #include "fdesc.h"
       
    36 #include "stdio_r.h"		// for popen3
       
    37 #include "stdlib_r.h"		// for system
       
    38 
       
    39 #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
       
    40 #include "libc_wsd_defs.h"
       
    41 #endif
       
    42 #define	MAXPATHLEN	260	/* E32STD.H: KMaxFullName + 4 to avoid data loss */
       
    43 
       
    44 extern "C" {
       
    45 
       
    46 /*
       
    47 Opens the file which name is stored in the file string.
       
    48 */
       
    49 EXPORT_C int open (const char *file, int flags, ...)
       
    50 	{
       
    51 	va_list argList; 
       
    52 	register int perms;
       
    53 	
       
    54 	if(!file) 
       
    55 		{
       
    56     	errno = EFAULT ;
       
    57     	return -1 ;	//null file pointer
       
    58 		}
       
    59 	
       
    60 	va_start (argList, flags);
       
    61 	perms = va_arg(argList,int);
       
    62 	va_end (argList);
       
    63 
       
    64 	//If mode is invalid
       
    65 	if( perms  > (S_IRWXU | S_IRWXG | S_IRWXO ) )
       
    66 		{
       
    67 		//make it read-write for all
       
    68 		perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
       
    69 		}
       
    70 	wchar_t _widename[MAXPATHLEN+1];
       
    71 
       
    72 	if ((size_t)-1 != mbstowcs(_widename, file, MAXPATHLEN))
       
    73 		{
       
    74 		return _open_r (&errno, _widename, flags, perms);  
       
    75 		}
       
    76 	else
       
    77 		{
       
    78 		errno = EILSEQ;		
       
    79 		return -1;	// Illegal Sequence of wide characeters
       
    80 		}
       
    81 
       
    82 	}
       
    83 
       
    84 /*
       
    85 A wide_character version of a open().
       
    86 */
       
    87 EXPORT_C int wopen (const wchar_t *file, int flags, ...)
       
    88 	{
       
    89 	va_list ap;
       
    90 	int ret;
       
    91 	register int perms;
       
    92 	
       
    93 	if(!file)
       
    94 		{
       
    95     	errno = EFAULT ;
       
    96     	return -1 ;	
       
    97 		}
       
    98 		
       
    99 	va_start (ap, flags);
       
   100 	perms = va_arg(ap,int);
       
   101 	va_end (ap);
       
   102 	
       
   103 	//If mode is invalid
       
   104 	if( perms  > (S_IRWXU | S_IRWXG | S_IRWXO ) )
       
   105 		{
       
   106 		//make it read-write for all
       
   107 		perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
       
   108 		}
       
   109 
       
   110 	ret = _wopen_r (&errno, file, flags, perms);
       
   111 	
       
   112 	return ret;
       
   113 	}
       
   114 
       
   115 
       
   116 /*
       
   117 Reads a block of data of the length specified by cnt.
       
   118 */
       
   119 EXPORT_C int read (int fd, void *buf, size_t cnt)
       
   120 	{
       
   121 	if((int)cnt == 0)       
       
   122 		{
       
   123 			return 0 ;
       
   124 		}	
       
   125 	if((int)cnt < 0) 
       
   126 		{
       
   127 	  	errno = EINVAL ;
       
   128 	  	return -1 ;
       
   129 		}
       
   130 	if(!buf)
       
   131 	  	{
       
   132 	  	errno = EFAULT ;
       
   133 	  	return -1 ;
       
   134 	  	}
       
   135 	
       
   136 	//If the fd corresponding to STDIN
       
   137 	if(fd == STDIN_FILENO && (Backend()->GetDesc(STDIN_FILENO))->Attributes() == KConsoleFd) 
       
   138 		{
       
   139 		int len = 0;
       
   140 		char ch = '\0';
       
   141 		int ret = -1;
       
   142 		do
       
   143 			{
       
   144 			ret = _read_r(&errno, STDIN_FILENO, &ch, 1);
       
   145 
       
   146 			//Copy requested count of data, ignore the rest
       
   147 			if(ret > 0 && len < cnt )
       
   148 				{
       
   149 				((char*)buf)[len] = ch;
       
   150 				len++;
       
   151 				}
       
   152 			else if(ret < 0)
       
   153 				{
       
   154 				break;
       
   155 				}
       
   156 			
       
   157 			}while(ch != '\n');
       
   158 		
       
   159 		//Handle error case.
       
   160 		if(ret == -1)
       
   161 			{
       
   162 			return ret;
       
   163 			}
       
   164 
       
   165 		return len;
       
   166 		}
       
   167 	else
       
   168 		{
       
   169 		return _read_r(&errno, fd, (char*)buf, cnt);
       
   170 		}
       
   171 	}
       
   172 
       
   173 
       
   174 /*
       
   175 Writes a block of data of the length specified by cnt.
       
   176 */
       
   177 EXPORT_C int write (int fd, const void *buf, size_t cnt)
       
   178 	{
       
   179 		if((int)cnt == 0) 
       
   180 		{
       
   181 	   	return 0;
       
   182 		}
       
   183 	if((int)cnt < 0) 
       
   184 		{
       
   185 	   	errno = EINVAL;
       
   186 	   	return -1;
       
   187 		}
       
   188 	if(!buf) 
       
   189 	   	{
       
   190 	   	errno = EFAULT ;
       
   191 	   	return -1 ;
       
   192 	   	}
       
   193 	return _write_r(&errno, fd, (char*)buf, cnt);
       
   194 	}
       
   195 
       
   196 
       
   197 /*
       
   198 Close a file.
       
   199 */
       
   200 EXPORT_C int close (int fd)
       
   201 	{
       
   202 	return  _close_r(&errno, fd);
       
   203 	}
       
   204 
       
   205 
       
   206 
       
   207 /*
       
   208 Synchronizes a file's in-memory state with that on the physical medium.
       
   209 */
       
   210 EXPORT_C int fsync (int fd)
       
   211 	{
       
   212 	return _fsync_r(&errno, fd);
       
   213 	}
       
   214 
       
   215 /*
       
   216 Repositions the read/write file offset.
       
   217 */
       
   218 EXPORT_C off_t lseek (int fd, off_t pos, int whence)
       
   219 	{
       
   220 	return _lseek_r(&errno, fd, pos, whence);
       
   221 	}
       
   222 
       
   223 
       
   224 /*
       
   225 Gets information about the named file and writes it to the area that buf points to.
       
   226 The system must be able to search all directories leading to the file; 
       
   227 however, read, write, or execute permission of the file is not required.
       
   228 */
       
   229 EXPORT_C int fstat (int fd, struct stat *st)
       
   230 	{
       
   231 	if(!st)
       
   232 	   {
       
   233 	    errno = EFAULT ;
       
   234 	    return -1 ;	
       
   235 	   }
       
   236 	return _fstat_r(&errno, fd, st);
       
   237 	}
       
   238 
       
   239 
       
   240 /*
       
   241 Gets the size of a file. 
       
   242 */
       
   243 EXPORT_C int stat (const char *name, struct stat *st)
       
   244 	{
       
   245 	if(!st)
       
   246 	   {
       
   247 	    errno = EFAULT ;
       
   248 	    return -1 ;	
       
   249 	   }
       
   250     
       
   251     wchar_t tmpbuf[MAXPATHLEN+1];	
       
   252 	if ((size_t)-1 != mbstowcs(tmpbuf, name, MAXPATHLEN))
       
   253 		{
       
   254 		return _stat_r(&errno, tmpbuf, st);
       
   255 		}
       
   256 	errno = EILSEQ;		
       
   257 	return -1;
       
   258 	}
       
   259 
       
   260 
       
   261 EXPORT_C int utime (const char *name, const struct utimbuf *filetimes)
       
   262 	{
       
   263 	if(!name) 
       
   264 		{
       
   265 		errno = EFAULT ;
       
   266 		return -1 ;
       
   267 		}
       
   268 
       
   269 	wchar_t tmpbuf[MAXPATHLEN+1];	
       
   270 	if ((size_t)-1 != mbstowcs(tmpbuf, name, MAXPATHLEN))
       
   271 		{
       
   272 		return _utime_r (&errno, tmpbuf, filetimes);
       
   273 		}
       
   274 	
       
   275 	errno = EILSEQ;		
       
   276 	return -1;
       
   277 	}
       
   278 
       
   279 
       
   280 
       
   281 /*
       
   282 A wide_character version of a stat().
       
   283 */
       
   284 EXPORT_C int wstat (const wchar_t *name, struct stat *st)
       
   285 	{
       
   286 			if( !name || !st )
       
   287 			{
       
   288 					errno = EFAULT;
       
   289 					return -1;
       
   290 			}
       
   291 	return _wstat_r (&errno, name, st);
       
   292 	}
       
   293 
       
   294 
       
   295 /*
       
   296 duplicates an open file descriptor.
       
   297 */
       
   298 EXPORT_C int dup (int aFid)
       
   299 	{
       
   300 	return _dup_r(&errno, aFid);
       
   301 	}
       
   302 
       
   303 
       
   304 /*
       
   305 function duplicates an open file descriptor.
       
   306 */
       
   307 EXPORT_C int dup2 (int aFid1, int aFid2)
       
   308 	{
       
   309 	return _dup2_r(&errno, aFid1, aFid2);
       
   310 	}
       
   311 
       
   312 
       
   313 /*
       
   314 sorms a variety of device-specific control functions on device special files.
       
   315 */
       
   316 EXPORT_C int ioctl (int aFid, unsigned long aCmd, ...)
       
   317 	{
       
   318 	void* aParam ;
       
   319 	va_list  Vlist ;
       
   320 	int ret;
       
   321 	va_start(Vlist , aCmd ) ;
       
   322 	aParam = va_arg(Vlist , void *)  ;
       
   323 	if(!aParam) 
       
   324 		{
       
   325 		errno = EFAULT ; 
       
   326 		return -1 ;
       
   327 		}
       
   328 
       
   329 	ret = _ioctl_r(&errno, aFid, aCmd, aParam);
       
   330 	
       
   331 	va_end(Vlist) ;
       
   332 	return ret;
       
   333 	}
       
   334 
       
   335 
       
   336 
       
   337 /*
       
   338 Gets the path name of the current working directory.
       
   339 If a buffer is specified, the path name is placed in that buffer,
       
   340 and the address of the buffer is returned.
       
   341 */
       
   342 
       
   343 /*
       
   344 A wide_character version of a getcwd().
       
   345 */
       
   346 EXPORT_C wchar_t* wgetcwd (wchar_t *_buf, size_t _size)
       
   347 	{
       
   348 	return _wgetcwd_r(&errno, _buf, _size);
       
   349 	}
       
   350 
       
   351 
       
   352 /*
       
   353 Changes the current working directory to be pathname. 
       
   354 The current directory is the beginning point for file 
       
   355 searches when path names are not absolute. 
       
   356 If the chdir() function fails, the current working directory remains unchanged.
       
   357 */
       
   358 EXPORT_C int chdir (const char *_path)
       
   359 	{
       
   360 	if(!_path) 
       
   361 		{
       
   362 		errno = EFAULT;
       
   363 		return -1;
       
   364 	  	}
       
   365 
       
   366 	//we need to use a wide buffer and convert
       
   367 	wchar_t tmpbuf[MAXPATHLEN+1];		//use the max path length possible
       
   368 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
       
   369 		{
       
   370 		return _chdir_r(&errno, tmpbuf);
       
   371 		}
       
   372 	errno = EILSEQ;		
       
   373 	return -1;
       
   374 	}
       
   375 
       
   376 
       
   377 /* A wide-character version of chdir().
       
   378 */
       
   379 EXPORT_C int wchdir (const wchar_t *_path)
       
   380 	{
       
   381 
       
   382 	if(!_path) 
       
   383 		{
       
   384 		errno = EFAULT;
       
   385 		return -1;
       
   386 	  	}
       
   387 
       
   388 	return _wchdir_r(&errno, _path);
       
   389 	}
       
   390 
       
   391 
       
   392 /*
       
   393 Removes an empty directory whose name is given by pathname.
       
   394 The directory must not have any entries other than dot (.) and dot-dot (..).
       
   395 */
       
   396 EXPORT_C int rmdir (const char *_path)
       
   397 	{
       
   398 	if(!_path)
       
   399 		{
       
   400 		errno = EFAULT ;
       
   401 		return -1 ;
       
   402 		}
       
   403 
       
   404 	if(!strcmp((_path + strlen(_path) -1 ) , ".") ) 
       
   405 		{
       
   406 		errno = EINVAL ;
       
   407 		return -1 ;  
       
   408 		}
       
   409 
       
   410 	wchar_t tmpbuf[MAXPATHLEN+1];		//use the max path length possible
       
   411 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
       
   412 		{
       
   413 		return _rmdir_r(&errno, tmpbuf);
       
   414 		}
       
   415 	errno = EILSEQ;		
       
   416 	return -1;
       
   417 	}
       
   418 
       
   419 
       
   420 
       
   421 /* A wide-character version of rmdir().
       
   422 */
       
   423 EXPORT_C int wrmdir (const wchar_t *_path)
       
   424 	{
       
   425 			if( !_path )
       
   426 			{
       
   427 				 errno = EFAULT;
       
   428 				 return -1;
       
   429 			}
       
   430 	return _wrmdir_r(&errno, _path);
       
   431 	}
       
   432 
       
   433 
       
   434 /*
       
   435 Creates a new directory with the specified path name. 
       
   436 The file permissions of the new directory are initialized from the specified mode. 
       
   437 */
       
   438 EXPORT_C int mkdir (const char *_path, mode_t _mode)
       
   439 	{
       
   440 	if(!_path)
       
   441 		{
       
   442 		errno = EFAULT ;
       
   443 		return -1 ;
       
   444 		}
       
   445 
       
   446 	//we need to use a wide buffer and convert
       
   447 	wchar_t tmpbuf[MAXPATHLEN+1];		//use the max path length possible
       
   448 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
       
   449 		{
       
   450 		return _mkdir_r(&errno, tmpbuf, _mode);
       
   451 		}
       
   452 	errno = EILSEQ;		
       
   453 	return -1;
       
   454 	}
       
   455 
       
   456 
       
   457 
       
   458 /* A wide-character version of mkdir().
       
   459 */
       
   460 EXPORT_C int wmkdir (const wchar_t *_path, mode_t _mode)
       
   461 	{
       
   462 
       
   463 	if(!_path)
       
   464 		{
       
   465 		errno = EFAULT ;
       
   466 		return -1 ;
       
   467 		}
       
   468 	
       
   469 	return _wmkdir_r(&errno, _path, _mode);
       
   470 	}
       
   471 
       
   472 
       
   473 /*
       
   474 Sets the access permissions for the file 
       
   475 whose name is given by pathname to the bit pattern contained in mode. 
       
   476 For this call to succeed, the effective user ID of the process must match 
       
   477 the owner of the file, or the process must have appropriate privileges. 
       
   478 The owner of the file pathname always has privileges to change permission modes 
       
   479 and file attributes.
       
   480 */
       
   481 EXPORT_C int chmod (const char *_path, mode_t _mode)
       
   482 	{
       
   483 	if(!_path)
       
   484 		{
       
   485 		errno = EFAULT ;
       
   486 		return -1 ;
       
   487 		}
       
   488 
       
   489 	wchar_t tmpbuf[MAXPATHLEN+1];	
       
   490 	if ((size_t)-1 != mbstowcs(tmpbuf, _path, MAXPATHLEN))
       
   491 		{
       
   492 		return _chmod_r(&errno, tmpbuf, _mode);
       
   493 		}
       
   494 	errno = EILSEQ;		
       
   495 	return -1;
       
   496 	}
       
   497 /*
       
   498 Sets the access permissions for the file specifed by file descriptor
       
   499 whose name is given by pathname to the bit pattern contained in mode. 
       
   500 For this call to succeed, the effective user ID of the process must match 
       
   501 the owner of the file, or the process must have appropriate privileges. 
       
   502 The owner of the file pathname always has privileges to change permission modes 
       
   503 and file attributes.
       
   504 */
       
   505 EXPORT_C int fchmod (int fd , mode_t _mode)
       
   506 	{
       
   507 	
       
   508 		return _fchmod_r(&errno, fd, _mode);
       
   509 	}
       
   510 
       
   511 
       
   512 
       
   513 /* A wide-character version of chmod().
       
   514 */
       
   515 EXPORT_C int wchmod (const wchar_t *_path, mode_t _mode)
       
   516 	{
       
   517 	
       
   518 	if(!_path)
       
   519 		{
       
   520 		errno = EFAULT ;
       
   521 		return -1 ;
       
   522 		}
       
   523 	
       
   524 	return _wchmod_r(&errno, _path, _mode);
       
   525 	}
       
   526 
       
   527 
       
   528 
       
   529 /* A wide-character version of unlink().
       
   530 */
       
   531 EXPORT_C int wunlink (const wchar_t *_path)
       
   532 	{
       
   533 			if( !_path )
       
   534 			{
       
   535 					errno = EFAULT;
       
   536 					return -1;
       
   537 			}
       
   538 	return _wunlink_r(&errno, _path);
       
   539 	}
       
   540 
       
   541 
       
   542 /*
       
   543 Renames a file.
       
   544 */
       
   545 EXPORT_C int rename (const char *oldpath, const char *newpath)
       
   546 	{
       
   547 	if((!oldpath) ||(!newpath))
       
   548 		{
       
   549 		errno = EFAULT ;
       
   550 		return -1 ;
       
   551 		}
       
   552 
       
   553 	wchar_t _old[MAXPATHLEN+1];		
       
   554 	wchar_t _new[MAXPATHLEN+1];		
       
   555 	if ((size_t)-1 != mbstowcs(_old, oldpath, MAXPATHLEN))
       
   556 		{
       
   557 		if ((size_t)-1 != mbstowcs(_new, newpath, MAXPATHLEN))
       
   558 			{
       
   559 			return _rename_r(&errno, _old, _new);
       
   560 			}
       
   561 		}
       
   562 	errno = EILSEQ;		
       
   563 	return -1;
       
   564 	}
       
   565 
       
   566 
       
   567 /* A wide-character version of rename().
       
   568 */
       
   569 EXPORT_C int wrename (const wchar_t *oldpath, const wchar_t *newpath)
       
   570 	{
       
   571 	
       
   572 	if((!oldpath) ||(!newpath))
       
   573 		{
       
   574 		errno = EFAULT ;
       
   575 		return -1 ;
       
   576 		}
       
   577 	
       
   578 	return _wrename_r(&errno, oldpath, newpath);
       
   579 	}
       
   580 
       
   581 
       
   582 /*
       
   583 Takes a specified path name, pathname and resolves all symbolic links,
       
   584 extra slashes (/), and references to /./ and /../. 
       
   585 The resulting absolute path name is placed in the memory location 
       
   586 pointed to by the resolved_path argument.
       
   587 */
       
   588 
       
   589 /* A wide-character version of realpath().
       
   590 */
       
   591 EXPORT_C wchar_t* wrealpath (const wchar_t* path, wchar_t* resolved)
       
   592 	{
       
   593 	return _wrealpath_r(&errno, path, resolved);
       
   594 	}
       
   595 
       
   596 
       
   597 /*
       
   598 Gives access to the client's stdin
       
   599 */
       
   600 EXPORT_C FILE* popen (const char* command, const char* mode)
       
   601 	{
       
   602 	// Check for the validity of command.
       
   603 	// On Linux, the shell would return cannot find command to execute
       
   604 	if (command == NULL)
       
   605 		{
       
   606 		errno = ENOENT;
       
   607 		return NULL;
       
   608 		}
       
   609 		
       
   610 	if(strlen(command) > KMaxPath)
       
   611 		{
       
   612 		errno = ENAMETOOLONG;
       
   613 		return NULL;
       
   614 		}
       
   615 	// Check for the validity of Mode.
       
   616 	if( (!mode) || mode[0] != 'r' && mode[0] != 'w' )
       
   617 		{
       
   618 		// Invalid mode
       
   619 		errno = EINVAL;
       
   620 		return NULL;
       
   621 		}
       
   622 		
       
   623 	wchar_t wcmd[KMaxPath+1];
       
   624 		
       
   625 	// Widen command
       
   626 	if ((size_t)-1 != mbstowcs(wcmd, command, KMaxPath))
       
   627 		{
       
   628 		int fd = _wpopen_r(&errno, wcmd, mode);
       
   629 		if (fd > 0)
       
   630 			{
       
   631 			// return value is a valid fd
       
   632 			return fdopen(fd, mode);
       
   633 			}
       
   634 		}
       
   635 	else
       
   636 		{
       
   637 		errno = EILSEQ;
       
   638 		}
       
   639 
       
   640 	return NULL;
       
   641 	}
       
   642 	
       
   643 	
       
   644 EXPORT_C FILE* wpopen (const wchar_t* command, const wchar_t* wmode)
       
   645 	{
       
   646 	char mode[2];
       
   647 	size_t sz;
       
   648 
       
   649 	mode[0] = '\0';
       
   650 	sz = wcstombs(mode, wmode, 2);
       
   651 	//Check for the validity of Mode.
       
   652 	if (sz <= 0 || (mode[0] != 'r' && mode[0] != 'w'))
       
   653 		{
       
   654 		//If its neither "r" nor "w", its undefined behavior
       
   655 		errno = EINVAL;
       
   656 		return NULL;
       
   657 		}
       
   658 
       
   659 	if(command)
       
   660 		{
       
   661 		if(wcslen(command) > KMaxPath)
       
   662 			{
       
   663 			errno = ENAMETOOLONG;
       
   664 			return NULL;
       
   665 			}
       
   666 			
       
   667 		int fd = _wpopen_r(&errno, command, mode );
       
   668 		//If return Value is valid fd
       
   669 		if (fd > 0)
       
   670 			{
       
   671 			return fdopen(fd, mode);
       
   672 			}
       
   673 		}
       
   674 	else
       
   675 		{
       
   676 		errno = ENOENT;
       
   677 		}
       
   678 	return NULL;
       
   679 	}
       
   680 
       
   681 
       
   682 EXPORT_C int pclose(FILE* stream)
       
   683 	{
       
   684 	TInt fd;
       
   685 	if (!stream || ((fd = fileno(stream)) == -1))
       
   686 		{
       
   687 		errno = EINVAL;
       
   688 		return -1;
       
   689 		}
       
   690 		
       
   691 	TInt err = _pclose_r(&errno, fd);
       
   692 	
       
   693 	if (err != 0)
       
   694 		{
       
   695 		if (errno == ECHILD)
       
   696 			{
       
   697 			fclose(stream);
       
   698 			// reset errno just in case it has been modified by fclose
       
   699 			errno = ECHILD;
       
   700 			}
       
   701 		
       
   702 		return -1;
       
   703 		}
       
   704 		
       
   705 	return fclose(stream);
       
   706 	}
       
   707 	
       
   708 /* A wide-character version of popen3().
       
   709 */
       
   710 EXPORT_C int wpopen3 (const wchar_t* file, const wchar_t* cmd, wchar_t** env, int fids[3])
       
   711 	{
       
   712 	if (file == NULL)
       
   713 		{
       
   714 		errno = ENOENT;
       
   715 		return -1;
       
   716 		}
       
   717 		
       
   718 	if(wcslen(file) > KMaxPath)
       
   719 		{
       
   720 		errno = ENAMETOOLONG;
       
   721 		return -1;	
       
   722 		}
       
   723 		
       
   724 	return _wpopen3_r(&errno, file, cmd, env, fids);
       
   725 	}
       
   726 
       
   727 
       
   728 EXPORT_C int popen3 (const char* file, const char* cmd, char** env, int fids[3])
       
   729 	{
       
   730 	if (file == NULL)
       
   731 		{
       
   732 		errno = ENOENT;
       
   733 		return -1;
       
   734 		}
       
   735 		
       
   736 	if(strlen(file) > KMaxPath)
       
   737 		{
       
   738 		errno = ENAMETOOLONG;
       
   739 		return -1;	
       
   740 		}
       
   741 		
       
   742 	wchar_t wfile[KMaxPath+1];
       
   743 	wchar_t wcmd[KMaxPath+1];
       
   744 	
       
   745 	wchar_t** wenv = NULL;
       
   746 	
       
   747 	TInt ret = mbstowcs(wfile, file, KMaxPath);
       
   748 	TInt cmdlen = mbstowcs(wcmd, cmd, KMaxPath);
       
   749 	
       
   750 	if (ret != (size_t)-1 && cmdlen != (size_t)-1)
       
   751 		{
       
   752 		//OK, we've widened the first 2 args
       
   753 		//now for the environment
       
   754 
       
   755 		//env will be an array of char pointers with a NULL as the last one
       
   756 		if (env)
       
   757 			{
       
   758 			TInt count = 0;
       
   759 			
       
   760 			for (; env[count]; ++count) { }
       
   761 
       
   762 			//coverity[alloc_fn]
       
   763 			//coverity[assign]
       
   764 			
       
   765 			wenv = (wchar_t **)malloc((count+1) * sizeof(wchar_t*));
       
   766 			if (!wenv)
       
   767 				{
       
   768 				errno = ENOMEM;
       
   769 				return -1;
       
   770 				}
       
   771 			
       
   772 			for (int i = 0; i < count; ++i)
       
   773 				{
       
   774 				int len = strlen(env[i]) + 1;
       
   775 				wenv[i] = (wchar_t *)malloc(len * sizeof(wchar_t));
       
   776 				if (wenv[i] == NULL)
       
   777 					{
       
   778 					//coverity[leave_without_push]
       
   779 
       
   780 					errno = ENOMEM;
       
   781 					goto bailout;
       
   782 					}
       
   783 				if (mbstowcs(wenv[i], env[i], len) == (size_t)-1)
       
   784 					{
       
   785 					//coverity[leave_without_push]
       
   786 					errno = EILSEQ;
       
   787 					wenv[i+1] = NULL;
       
   788 					goto bailout;
       
   789 					}
       
   790 				}
       
   791 				
       
   792 			wenv[count] = 0;
       
   793 			}
       
   794 
       
   795 		if (cmdlen)
       
   796 			{
       
   797 			//coverity[leave_without_push]
       
   798 			ret =  wpopen3(wfile, wcmd, wenv, fids);
       
   799 			}
       
   800 		else
       
   801 			{
       
   802 			//coverity[leave_without_push]
       
   803 			ret = wpopen3(wfile, NULL, wenv, fids);
       
   804 			}
       
   805 			
       
   806 		}
       
   807 	else
       
   808 		{
       
   809 		errno = EILSEQ;
       
   810 		return -1;
       
   811 		}
       
   812 
       
   813 bailout:
       
   814 	if (wenv)
       
   815 		{
       
   816 		for (int i = 0; wenv[i]; ++i)
       
   817 			{
       
   818 			free(wenv[i]);
       
   819 			}
       
   820 		free(wenv);
       
   821 		}
       
   822 
       
   823 	return ret;
       
   824 	}
       
   825 
       
   826 /*
       
   827 Lets the calling process obtain status information about one of its child processes.
       
   828 If status information is available for two or more child processes,
       
   829 the order in which their status is reported is unspecified.
       
   830 */
       
   831 EXPORT_C int waitpid (int pid, int* status, int options)
       
   832 	{
       
   833 	return _waitpid_r(&errno, pid, status, options);
       
   834 	}
       
   835 
       
   836 
       
   837 /*
       
   838 Calls reentrant version of waitpid().
       
   839 */
       
   840 EXPORT_C int wait (int* status)
       
   841 	{
       
   842 	return _wait_r(&errno, status);
       
   843 	}
       
   844 
       
   845 
       
   846 
       
   847 /*
       
   848 Execute command.
       
   849 */
       
   850 
       
   851 /* A wide-character version of a system().
       
   852 */
       
   853 EXPORT_C int wsystem (const wchar_t* cmd)
       
   854 	{
       
   855 	if (cmd==0)
       
   856 		{
       
   857 		return 1;	// special case, says that we do support system().	
       
   858 		}
       
   859 
       
   860 	if(wcslen(cmd) > KMaxPath)
       
   861 		{
       
   862 		errno = ENAMETOOLONG;
       
   863 		return -1;	
       
   864 		}
       
   865 		
       
   866 	return _wsystem_r(&errno, cmd);
       
   867 	}
       
   868 
       
   869 
       
   870 // -----------------------------------------------------------------------------
       
   871 // Select() : Implementation of Select for I/O multiplexing
       
   872 // This API is used for waiting on multiple descriptors to become ready
       
   873 // Maximum timeout to wait can also be specified
       
   874 // Returns: System wide error code
       
   875 // -----------------------------------------------------------------------------
       
   876 //
       
   877 EXPORT_C int select(int maxfd, fd_set *readfds, fd_set *writefds,
       
   878 					fd_set *exceptfds, struct timeval *tvptr)
       
   879 	{	
       
   880 	return _select_r(&errno, maxfd, readfds, writefds, exceptfds, tvptr);
       
   881 	}
       
   882 } // extern "C"
       
   883 
       
   884 // -----------------------------------------------------------------------------
       
   885 // aselect() : Implementation of Select for asynchronous I/O multiplexing
       
   886 // This API is used for waiting on multiple descriptors to become ready
       
   887 // Maximum timeout to wait can also be specified
       
   888 // Returns: System wide error code
       
   889 // This api does not provide C Linkage
       
   890 // -----------------------------------------------------------------------------
       
   891 //
       
   892 EXPORT_C int aselect(int maxfd, fd_set *readfds, fd_set *writefds,
       
   893 					fd_set *exceptfds, struct timeval *tvptr,
       
   894 					TRequestStatus* requeststatus)
       
   895 	{	
       
   896 	return _aselect_r(&errno, maxfd, readfds, writefds, exceptfds, tvptr, requeststatus);
       
   897 	}
       
   898 
       
   899 // -----------------------------------------------------------------------------
       
   900 // cancelaselect() : Implementation of Select for asynchronous I/O multiplexing
       
   901 // This API is used for cancelling the aselect issued on requeststatus
       
   902 // Returns: System wide error code
       
   903 // This api does not provide C Linkage
       
   904 // -----------------------------------------------------------------------------
       
   905 //
       
   906 EXPORT_C int cancelaselect(TRequestStatus* requeststatus)
       
   907 	{	
       
   908 	return _cancelaselect_r(&errno, requeststatus);
       
   909 	}
       
   910 
       
   911 // -----------------------------------------------------------------------------
       
   912 // eselect() : Implementation of Select for I/O multiplexing
       
   913 // This API is used for waiting on multiple descriptors to become ready,
       
   914 // or for any of the TRequestStatus object in the TRequestStatus array passed
       
   915 // to be signalled
       
   916 // Maximum timeout to wait can also be specified
       
   917 // Returns: System wide error code
       
   918 // This api does not provide C Linkage
       
   919 // -----------------------------------------------------------------------------
       
   920 //
       
   921 EXPORT_C int eselect(int maxfd, fd_set *readfds, fd_set *writefds,
       
   922 					fd_set *exceptfds, struct timeval *tvptr, int numreqs,
       
   923 					TRequestStatus* waitarray)
       
   924 	{	
       
   925 	return _eselect_r(&errno, maxfd, readfds, writefds, exceptfds, tvptr, numreqs, waitarray);
       
   926 	}
       
   927 
       
   928 // -----------------------------------------------------------------------------
       
   929 // fcntl() : Implementation of fcntl for supporting Non-Blocking I/O 
       
   930 // This API is used for setting a file descriptor as non-blocking
       
   931 // Returns: System wide error code
       
   932 // -----------------------------------------------------------------------------
       
   933 //
       
   934 EXPORT_C int fcntl (int aFid, int aCmd, ...)
       
   935 	{
       
   936 	va_list ap;
       
   937 	va_start(ap, aCmd);
       
   938 
       
   939 	int ret;
       
   940 	ret = _fcntl_r(&errno, aFid,aCmd, va_arg(ap, long)); 
       
   941 	
       
   942  	va_end(ap);
       
   943 	return ret ;
       
   944 	}
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 //int setecho(int fd, unsigned int echoval)
       
   948 //
       
   949 //Sets the echo flag for this fd.
       
   950 // -----------------------------------------------------------------------------
       
   951 
       
   952 extern "C" {
       
   953 EXPORT_C int setecho(int fd, uint8_t echoval)
       
   954 	{
       
   955 	return _setecho_r(&errno, fd, echoval);
       
   956 	}
       
   957 } //extern "C"
       
   958 
       
   959 
       
   960