diff -r 000000000000 -r e4d67989cc36 genericopenlibs/cstdlib/LPOSIX/SYSCALLS.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cstdlib/LPOSIX/SYSCALLS.CPP Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,1157 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// connectors for re-entrant system calls +// +// + +#include "SYSIF.H" +#include "LPOSIX.H" + +#include +#include +#include // for open() +#include +#include +#include +#include // for popen3 +#include // for system +#include +#include + + +extern "C" { + +/** +Opens the file which name is stored in the file string. + +@return On Success, a non-negative integer representing the lowest numbered unused file descriptor. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int open (const char *file, int flags, ...) + { + va_list ap; + int ret; + + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + + va_start (ap, flags); + ret = _open_r (r, file, flags, va_arg (ap, int)); + va_end (ap); + return ret; + } + +/** +A wide_character version of a open(). +*/ +EXPORT_C int wopen (const wchar_t *file, int flags, ...) + { + va_list ap; + int ret; + + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + + va_start (ap, flags); + ret = _wopen_r (r, file, flags, va_arg (ap, int)); + va_end (ap); + return ret; + } + +/** A reentrant version of open(). +*/ +EXPORT_C int _open_r (struct _reent *r, const char *name, int mode, int perms) + { + wchar_t _widename[KMaxFileName+1]; + + if (-1 != mbstowcs(_widename, name, KMaxFileName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.open(_widename,mode,perms,r->_errno); + } + + MapError(EILSEQ, r->_errno); + return 0; //null file pointer + + } + +/** A reentrant version of wopen(). +*/ +EXPORT_C int _wopen_r (struct _reent *r, const wchar_t *name, int mode, int perms) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.open(name,mode,perms,r->_errno); + } + +/** +Reads a block of data of the length specified by cnt. + +@return On Success, return a non-negative integer indicating the number of bytes actually read. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int read (int fd, char *buf, size_t cnt) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _read_r (r, fd, buf, cnt); + } + +/** A reentrant version of read(). +*/ +EXPORT_C int _read_r (struct _reent *r, int fd, char *buf, size_t nbyte) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.read(fd,buf,nbyte,r->_errno); + } + +/** +Writes a block of data of the length specified by cnt. + +@return On Success, returns the number of bytes written to the file. The number + shall never be greater than cnt. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int write (int fd, const char *buf, size_t cnt) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _write_r (r, fd, buf, cnt); + } + +/** A reentrant version of write(). +*/ +EXPORT_C int _write_r (struct _reent *r, int fd, const char *buf, size_t nbyte) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.write(fd,buf,nbyte,r->_errno); + } + +/** +Close a file. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int close (int fd) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _close_r (r, fd); + } + + +/** A reentrant version of close(). +*/ +EXPORT_C int _close_r (struct _reent *r, int fd) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.close(fd,r->_errno); + } + +/** +Synchronizes a file's in-memory state with that on the physical medium. + +@param fd Is the file descriptor for the file to be synchronized. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int fsync (int fd) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _fsync_r (r, fd); + } + +/** A reentrant version of fsync(). +*/ +EXPORT_C int _fsync_r (struct _reent *r, int fd) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.fsync(fd,r->_errno); + } + +/** +Repositions the read/write file offset. +@return a nonnegative integer that indicates the file pointer value. +@param fd Is the file descriptor of an open file. +@param pos Specifies the number of bytes to offset the file pointer +from a specified file origin. +@param whence Specifies the location from which to start seeking. +*/ +EXPORT_C off_t lseek (int fd, off_t pos, int whence) + { + return _lseek_r (_REENT, fd, pos, whence); + } + +/** A reentrant version of fseek(). +*/ +EXPORT_C off_t _lseek_r (struct _reent *r, int fd, off_t pos, int whence) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.lseek(fd,pos,whence,r->_errno); + } + +/** +Gets information about the named file and writes it to the area that buf points to. +The system must be able to search all directories leading to the file; +however, read, write, or execute permission of the file is not required. + +@param fd Is a file descriptor referring to a file for which status is returned. +@param st Points to a stat structure where status information about the file is to be placed. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int fstat (int fd, struct stat *st) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _fstat_r (r, fd, st); + } + +/** A reentrant version of fstat(). +*/ +EXPORT_C int _fstat_r (struct _reent *r, int fd, struct stat *st) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.fstat(fd,st,r->_errno); + } + +/** +Gets the size of a file. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int stat (const char *name, struct stat *st) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _stat_r (r, name, st); + } + +/** A reentrant version of stat(). +*/ +EXPORT_C int _stat_r (struct _reent *r, const char *name, struct stat *st) + { + wchar_t tmpbuf[KMaxFullName+1]; + if (-1 != mbstowcs(tmpbuf, name, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.stat(tmpbuf, st, r->_errno); + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** +A wide_character version of a stat(). +*/ +EXPORT_C int wstat (const wchar_t *name, struct stat *st) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wstat_r (r, name, st); + } + +/** A reentrant version of wstat(). +*/ +EXPORT_C int _wstat_r (struct _reent *r, const wchar_t *name, struct stat *st) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.stat(name,st,r->_errno); + } + +/** +Duplicates an open file descriptor. + +@param aFid Is the file descriptor to duplicate. + +@return On Success, returns a non-negative integer, namely the duplicated file descriptor, which + is the lowest available descriptor. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int dup (int aFid) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _dup_r(r, aFid); + } + +/** A reentrant version of dup(). +*/ +EXPORT_C int _dup_r (struct _reent *r, int aFid) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.dup(aFid,r->_errno); + } + +/** +Function duplicates an open file descriptor. + +@param aFid1 Is the file descriptor to duplicate. +@param aFid2 Is the file descriptor that filedes is duplicated onto. + +@return On Success, returns a non-negative integer, namely the duplicated file descriptor, which + is the lowest available descriptor. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int dup2 (int aFid1, int aFid2) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _dup2_r(r, aFid1, aFid2); + } + +/** A reentrant version of dup2(). +*/ +EXPORT_C int _dup2_r (struct _reent *r, int aFid1, int aFid2) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.dup2(aFid1,aFid2,r->_errno); + } + +/** +Performs a variety of device-specific control functions on device special files. + +@return On Success, returns a value other than -1 that depends upon the STREAMS device control function. + On Failure, return -1, errno may be set. +*/ +EXPORT_C int ioctl (int aFid, int aCmd, void* aParam) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _ioctl_r(r, aFid, aCmd, aParam); + } + +/** A reentrant version of ioctl(). +*/ +EXPORT_C int _ioctl_r (struct _reent *r, int aFid, int aCmd, void* aParam) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.ioctl(aFid,aCmd,aParam,r->_errno); + } + +/** +Gets the path name of the current working directory. +If a buffer is specified, the path name is placed in that buffer, +and the address of the buffer is returned. +@return If successful returns buf, if a non-null pointer was specified, +or the address of the allocated memory otherwise. +@param _buf Points to the buffer to copy the current working directory to, +or NULL if getcwd() should allocate the buffer. +@param _size Is the size, in bytes, of the array of characters that buf points to. +*/ +EXPORT_C char* getcwd (char *_buf, size_t _size) + { + return _getcwd_r(_REENT,_buf,_size); + } + +/** +A wide_character version of a getcwd(). +*/ +EXPORT_C wchar_t* wgetcwd (wchar_t *_buf, size_t _size) + { + return _wgetcwd_r(_REENT,_buf,_size); + } + +/** A reentrant version of getcwd(). +*/ +EXPORT_C char* _getcwd_r (struct _reent *r, char *_buf, size_t _size) + { + char * _ourbuf = _buf; + if (_buf==0) + { + _ourbuf=(char*)User::Alloc(_size); + if (_ourbuf==0) + { + r->_errno=ENOMEM; + return _buf; + } + } + + //we are dealing with wide characters from here so we need a temporary buffer + wchar_t tmpbuf[KMaxFullName]; + + MSystemInterface& sysIf=Interface(r); + wchar_t * rval = sysIf.getcwd((wchar_t*)tmpbuf, _size, r->_errno); + + if (rval) //we have a path + { + //convert it to UTF8 + size_t x = wcstombs(_ourbuf, tmpbuf, _size); //convert the buffer + return _ourbuf; + } + //deal with the fact we may have allocated our own buffer + if (_buf != _ourbuf) //we allocated it. + User::Free(_ourbuf); + return NULL; + } + +/** A wide-character version of reentrant of getcwd(). +*/ +EXPORT_C wchar_t * _wgetcwd_r (struct _reent *r, wchar_t *_buf, size_t _size) + { + if (_buf==0) + { + _buf=(wchar_t *)User::Alloc(_size*sizeof(wchar_t)); + if (_buf==0) + { + r->_errno=ENOMEM; + return _buf; + } + } + MSystemInterface& sysIf=Interface(r); + return sysIf.getcwd(_buf,_size,r->_errno); + } + +/** +Changes the current working directory to be pathname. The current directory is the +beginning point for file searches when path names are not absolute. +If the chdir() function fails, the current working directory remains unchanged. + +@param _path Is the path name of a directory. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int chdir (const char *_path) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _chdir_r(r, _path); + } + +/** A reentrant version of chdir(). +*/ +EXPORT_C int _chdir_r (struct _reent *r, const char *_path) + { + //we need to use a wide buffer and convert + wchar_t tmpbuf[KMaxFullName+1]; //use the max path length possible + if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.chdir(tmpbuf, r->_errno); + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** A wide-character version of chdir(). +*/ +EXPORT_C int wchdir (const wchar_t *_path) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wchdir_r(r, _path); + } + +/** A reentrant version of wchdir(). +*/ +EXPORT_C int _wchdir_r (struct _reent *r, const wchar_t *_path) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.chdir(_path,r->_errno); + } + +/** +Removes an empty directory whose name is given by pathname. +The directory must not have any entries other than dot (.) and dot-dot (..). + +@param _path Points to the directory that the rmdir() function removes. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int rmdir (const char *_path) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _rmdir_r(r, _path); + } + +/** A reentrant version of rmdir(). +*/ +EXPORT_C int _rmdir_r (struct _reent *r, const char *_path) + { + wchar_t tmpbuf[KMaxFullName+1]; //use the max path length possible + if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.rmdir(tmpbuf, r->_errno); + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** A wide-character version of rmdir(). +*/ +EXPORT_C int wrmdir (const wchar_t *_path) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wrmdir_r(r,_path); + } + +/** A reentrant version of wrmdir(). +*/ +EXPORT_C int _wrmdir_r (struct _reent *r, const wchar_t *_path) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.rmdir(_path,r->_errno); + } + +/** +Creates a new directory with the specified path name. +The file permissions of the new directory are initialized from the specified mode. + +@param _path Specifies the name of the new directory. The path name can be absolute or relative. + If the specified path name is relative, the directory is created based upon your current + working directory. +@param _mode Is a bitwise-OR field that specifies what permissions the directory has when it is created. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. Does not create a directory. +*/ +EXPORT_C int mkdir (const char *_path, mode_t _mode) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _mkdir_r(r,_path,_mode); + } + +/** A reentrant version of mkdir(). +*/ +EXPORT_C int _mkdir_r (struct _reent *r, const char *_path, mode_t _mode) + { + //we need to use a wide buffer and convert + wchar_t tmpbuf[KMaxFullName+1]; //use the max path length possible + if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.mkdir(tmpbuf, _mode, r->_errno); + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** A wide-character version of mkdir(). +*/ +EXPORT_C int wmkdir (const wchar_t *_path, mode_t _mode) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wmkdir_r(r, _path, _mode); + } + +/** A reentrant version of wmkdir(). +*/ +EXPORT_C int _wmkdir_r (struct _reent *r, const wchar_t *_path, mode_t _mode) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.mkdir(_path,_mode,r->_errno); + } + +/** +Sets the access permissions for the file whose name is given by pathname to the bit +pattern contained in mode. For this call to succeed, the effective user ID of the +process must match the owner of the file, or the process must have appropriate privileges. +The owner of the file pathname always has privileges to change permission modes and file attributes. + +@param _path Points to the name of the file. +@param _mode Is a bitwise-or field that specifies the new permission modes for path name. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int chmod (const char *_path, mode_t _mode) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _chmod_r(r, _path, _mode); + } + +/** A reentrant version of chmod(). +*/ +EXPORT_C int _chmod_r (struct _reent *r, const char *_path, mode_t _mode) + { + wchar_t tmpbuf[KMaxFullName+1]; + if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.chmod(tmpbuf,_mode,r->_errno); + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** A wide-character version of chmod(). +*/ +EXPORT_C int wchmod (const wchar_t *_path, mode_t _mode) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wchmod_r(r, _path, _mode); + } + +/** A reentrant version of wchmod(). +*/ +EXPORT_C int _wchmod_r (struct _reent *r, const wchar_t *_path, mode_t _mode) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.chmod(_path,_mode,r->_errno); + } + +/** +Removes a link to a file, and decrements the link count of the referenced file by one. When +the file's link count becomes 0 and no process has the file open, the space occupied by the +file is freed, and the file is no longer accessible. If one or more processes have the file +open when the last link is removed, the link is removed before unlink() returns, but the +removal of the file contents is postponed until all references to the file are closed. + +@param _path Points to the path name that names the file to be unlinked. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. +*/ +EXPORT_C int unlink (const char *_path) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _unlink_r(r, _path); + } + +/** A reentrant version of unlink(). +*/ +EXPORT_C int _unlink_r (struct _reent *r, const char *_path) + { + wchar_t tmpbuf[KMaxFullName+1]; + if (-1 != mbstowcs(tmpbuf, _path, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.unlink(tmpbuf, r->_errno); + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** A wide-character version of unlink(). +*/ +EXPORT_C int wunlink (const wchar_t *_path) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wunlink_r(r, _path); + } + +/** A wide-character version of reentrant of unlink(). +*/ +EXPORT_C int _wunlink_r (struct _reent *r, const wchar_t *_path) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.unlink(_path,r->_errno); + } + +/** +Renames a file. + +@param oldpath Points to the path name of the file to be renamed. The path name can be + absolute or relative. If a relative path name is given, the file is searched from + the current working directory. +@param newpath Points to the path name of the file. The path name can be absolute or relative. + If a relative path name is given, the file is searched from the current working directory. + +@return On Success, returns 0. + On Failure, returns -1, errno may be set. Does not change either the file named + by old or the file named by new (if either exists). +*/ +EXPORT_C int rename (const char *oldpath, const char *newpath) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _rename_r (r, oldpath, newpath); + } + +/** A reentrant version of rename(). +*/ +EXPORT_C int _rename_r (struct _reent *r, const char *oldpath, const char *newpath) + { + wchar_t _old[KMaxFullName+1]; + wchar_t _new[KMaxFullName+1]; + if (-1 != mbstowcs(_old, oldpath, KMaxFullName)) + { + if (-1 != mbstowcs(_new, newpath, KMaxFullName)) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.rename(_old, _new, r->_errno); + } + } + MapError(EILSEQ, r->_errno); + return -1; + } + +/** A wide-character version of rename(). +*/ +EXPORT_C int wrename (const wchar_t *oldpath, const wchar_t *newpath) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wrename_r (r, oldpath, newpath); + } + +/** A wide-character version of reentrant of rename(). +*/ +EXPORT_C int _wrename_r (struct _reent *r, const wchar_t *oldpath, const wchar_t *newpath) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.rename(oldpath,newpath,r->_errno); + } + +/** +Takes a specified path name, pathname and resolves all symbolic links, +extra slashes (/), and references to /./ and /../. +The resulting absolute path name is placed in the memory location +pointed to by the resolved_path argument. +@return resolved_path. +When an error occurs,returns a null pointer, setsresolved_path +to the path name that caused the error. +@param path Points to the path name that you want resolved to an absolute form. +This may be either a relative or absolute path name. +All but the final component of this path name must exist when you call realpath(). +@param resolved Points to the location where the canonical version +of pathname is to be placed. +*/ +EXPORT_C char* realpath (const char* path, char* resolved) + { + return _realpath_r(_REENT, path, resolved); + } + +/** A wide-character version of realpath(). +*/ +EXPORT_C wchar_t* wrealpath (const wchar_t* path, wchar_t* resolved) + { + return _wrealpath_r(_REENT, path, resolved); + } + +/** A wide-character version of reentrant of realpath(). +*/ +EXPORT_C wchar_t * _wrealpath_r (struct _reent *r, const wchar_t *relpath, wchar_t *resolved) + { + + TPtr16 name((TText16*)resolved,MAXPATHLEN); + TParse path; + MSystemInterface& sysIf=Interface(r); + TInt err = sysIf.ResolvePath(path, relpath, &name); + if (!err) + { + err = path.SetNoWild(path.DriveAndPath(),NULL,&name); + if (!err) + { + name = path.FullName(); + name.ZeroTerminate(); + return resolved; + } + } + MapError(err,r->_errno); + return 0; + } + +/** A reentrant version of realpath(). +*/ +EXPORT_C char* _realpath_r (struct _reent *r, const char *relpath, char *resolved) + { + + TFileName name; + TInt err; + + TParse path; + MSystemInterface& sysIf=Interface(r); + + wchar_t _wrelpath[KMaxFileName]; + + if (-1 != mbstowcs(_wrelpath, relpath , KMaxFileName)) + { + err = sysIf.ResolvePath(path, _wrelpath, &name); + if (!err) + { + err = path.SetNoWild(path.DriveAndPath(),NULL,&name); + if (!err) + { + name = path.FullName(); + + if (-1 != wcstombs(resolved, (wchar_t*)name.PtrZ(), KMaxFileName)) + return resolved; + else + { + err = EILSEQ; + } + } + } + } + else + { + err = EILSEQ; + } + + MapError(err,r->_errno); + return 0; + } + +/** +Gives access to the client's stdin. + +@return On Success, returns a pointer to an open stream, used to read or write to the pipe. + On Failure, return a null pointer. +*/ +EXPORT_C int popen3 (const char* cmd, const char* mode, char** env, int fids[3]) + { + struct _reent *r = _REENT2; + if (!r) + return NULL; // Memory for library globals is not allocated (errno not set). + return _popen3_r (r,cmd,mode,env,fids); + } + +/** A wide-character version of popen3(). +*/ +EXPORT_C int wpopen3 (const wchar_t* cmd, const wchar_t* mode, wchar_t** env, int fids[3]) + { + struct _reent *r = _REENT2; + if (!r) + return NULL; // Memory for library globals is not allocated (errno not set). + return _wpopen3_r (r,cmd,mode,env,fids); + } + +/** A reentrant version of a popen3(). +*/ +EXPORT_C int _popen3_r (struct _reent *r, const char* cmd, const char* mode, char** env, int fids[3]) + { + + wchar_t wcmd[MAXPATHLEN+1]; + wchar_t wmode[MAXPATHLEN+1]; + + wchar_t ** wenv = NULL; + wchar_t * buf = NULL; + + TInt ret = 0; + + if ((-1 != mbstowcs(wcmd, cmd, MAXPATHLEN)) && + (-1 != mbstowcs(wmode, mode, MAXPATHLEN))) + { + //OK, we've widened the first 2 args + //now for the environment + + //env is basically an array of char pointers with a NULL as the last one + if (env) + { + //OK we have a ptr to something + //count the number of entries and get their lengths so we can work out how much space + //is needed for the new one + + TInt count = 0; + TInt total = 0; + while (env[count] != NULL) + { + total+= strlen(env[count])+1; + count++; + } + //total has number of bytes in the strings + //max number of unicode chars is with a 1 to 1 mapping. + wenv = (wchar_t**)malloc(1 + count*sizeof(wchar_t*)); + buf = (wchar_t*)malloc(2*total); + + if (!(wenv && buf)) //we've had a malloc failure + { + r->_errno = ENOMEM; + goto bailout; + } + + wchar_t* p = buf; + + TInt ret; + for (TInt x = 0; x < count; x++) + { + wenv[count] = p; + ret = mbstowcs(p, env[count], MAXPATHLEN); + if (ret >= 0) + { + p += ret; //step to next bit of space + } + else + { + r->_errno = EILSEQ; + goto bailout; + } + + } + } + + + ret = _wpopen3_r(r, wcmd, wmode, wenv, fids); + } + else + { + r->_errno = EILSEQ; + } + + //don't lose the memory +bailout: + free(wenv); + free(buf); + + return ret; + } + +/** A wide-character version of reentrant of popen3(). +*/ +EXPORT_C int _wpopen3_r (struct _reent *r, const wchar_t* cmd, const wchar_t* mode, wchar_t** env, int fids[3]) + { + // Find the full path of the thing we are executing... + const wchar_t* cp=cmd; + while (*cp==L' ') + ++cp; // skip leading spaces + wchar_t file[MAXPATHLEN+1]; + TInt i=0; + wchar_t c=0; + for (i=0; i_errno); + } + +/** +Lets the calling process obtain status information about one of its child processes. +If status information is available for two or more child processes, the order in +which their status is reported is unspecified. + +@param pid Specifies a set of child processes for which the status is requested +@param status Specifies the location to which the child process' exit status is stored. +@param options Is the bitwise inclusive-OR of zero or more of the following flags. + +@return On Success, returns a value equal to the process ID of the child process. + On Failure, returns -1 and errno may be set OR returns 0 if the status is not available + for the specified process and it's set not to hang in the options. +*/ +EXPORT_C int waitpid (int pid, int* status, int options) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _waitpid_r (r, pid, status, options); + } + +/** A reentrant version of waitpid(). +*/ +EXPORT_C int _waitpid_r (struct _reent *r, int pid, int* status, int options) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.waitpid(pid,status,options,r->_errno); + } + +/** +Calls reentrant version of waitpid(). +*/ +EXPORT_C int wait (int* status) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _waitpid_r (r, -1, status, 0); + } + +/** A reentrant version of wait(). +*/ +EXPORT_C int _wait_r (struct _reent *r, int* status) + { + return _waitpid_r (r,-1,status,0); + } + +/** +Execute command. + +@param cmd Null-terminated string containing the system command to be executed. + +@return On Success, the command interpreter returns an adequate value; generally 0 + indicates that the action performed by the command interpreter terminated + with no errors. + On Failure, return -1. +*/ +EXPORT_C int system (const char* cmd) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _system_r (r, cmd); + } + +/** A reentrant version of system(). +*/ +EXPORT_C int _system_r (struct _reent *r, const char* cmd) + { + if (cmd==0) + return 1; // special case, says that we do support system(). + int fids[3]; + int pid=_popen3_r(r, cmd, "", 0, fids); + if (pid<0) + return -1; + int status=0; + pid=_waitpid_r (r,pid,&status,0); + if (pid<0) + return -1; + return status; + } + +/** A wide-character version of a system(). +*/ +EXPORT_C int wsystem (const wchar_t* cmd) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _wsystem_r (r, cmd); + } + +/** A wide-character version of reentrant of system(). +*/ +EXPORT_C int _wsystem_r (struct _reent *r, const wchar_t* cmd) + { + if (cmd==0) + return 1; // special case, says that we do support system(). + int fids[3]; + int pid=_wpopen3_r(r, cmd, (wchar_t*)L"", 0, fids); + if (pid<0) + return -1; + int status=0; + pid=_waitpid_r (r,pid,&status,0); + if (pid<0) + return -1; + return status; + } + +} // extern "C" + +#include + +/** Dubious asynchronous interface to ioctl, must be called from C++ + +@return On Success, returns a value other than -1. + On Failure, returns -1 and errno may be set. +*/ +EXPORT_C int ioctl (int aFid, int aCmd, void* aParam, TRequestStatus& aStatus) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _ioctl_r(r, aFid, aCmd, aParam, aStatus); + } + +/** A reentrant version of a ioctl(). +*/ +EXPORT_C int _ioctl_r (struct _reent *r, int aFid, int aCmd, void* aParam, TRequestStatus& aStatus) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.ioctl(aFid,aCmd,aParam,aStatus,r->_errno); + } + +EXPORT_C int ioctl_complete (int aFid, int aCmd, void* aParam, TRequestStatus& aStatus) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _ioctl_complete_r(r, aFid, aCmd, aParam, aStatus); + } + +/** A reentrant version of a ioctl_complete(). +*/ +EXPORT_C int _ioctl_complete_r (struct _reent *r, int aFid, int aCmd, void* aParam, TRequestStatus& aStatus) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.ioctl_complete(aFid,aCmd,aParam,aStatus,r->_errno); + } + +EXPORT_C int ioctl_cancel (int aFid) + { + struct _reent *r = _REENT2; + if (!r) + return -1; // Memory for library globals is not allocated (errno not set). + return _ioctl_cancel_r(r, aFid); + } + +/** A reentrant version of a ioctl_cancel(). +*/ +EXPORT_C int _ioctl_cancel_r (struct _reent *r, int aFid) + { + MSystemInterface& sysIf=Interface(r); + return sysIf.ioctl_cancel(aFid,r->_errno); + } +