Mbed OS version of IoT.js implementation running on GR-PEACH

ビルド方法

ビルド環境セットアップ

Host PC要件 : Ubuntu 16.04 (64-bit)



1. 以下のコマンドを実行し、下表に示すツールをインストールします。

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install [Package]
PackageVersion
build-essential12.1ubuntu2
gyp0.1+20150913git1f374df9-1ubuntu1
mercurial3.7.3-1ubuntu1
cmake3.5.1-1ubuntu3
git1:2.7.4-0ubuntu1.4
python2.72.7.12-1ubuntu016.04.3
valgrind1:3.11.0-1ubuntu4.2
python-pip8.1.1-2ubuntu0.4

2. 以下のコマンドを実行してMbed OS用ビルドツール mbed CLIをインストールします。

$ sudo -H pip install mbed-cli

3. GNU Arm Embedded Toolchainをインストールします。

  • ダウンロードしたファイルを任意のディレクトリに展開します。
    (以下、展開先を${TOOLCHAIN}と記載します)

tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2
  • ツールチェインのパスを設定します。

環境変数を使用する場合

$ export GCC_ARM_ROOT=${TOOLCHAIN}/gcc-arm-none-eabi-6-2017-q2-update/bin
$ export PATH=$GCC_ARM_ROOT:$PATH

mbed CLIで指定する場合

$ mbed config -G GCC_ARM_PATH $GCC_ARM_ROOT

iotjs環境のビルド

1. 本プログラムのクローン

下記コマンドを実行し、本プログラムをクローンしてください。

$ hg clone https://HinoNaka@os.mbed.com/users/HinoNaka/code/GR-PEACH_mbed-os-iotjs/

クローンが正常に終了すると、GR-PEACH_mbed-os-iotjs という名称のディレクトリが生成されますので、下記コマンドで当該ディレクトリへ移動してください。

$ cd GR-PEACH_mbed-os-iotjs

(Optional)
GR-PEACH-mbed-os-iotjsディレクトリを指す環境変数 ROOTを設定してください。以降の記載は本環境変数が設定されているものとします。

$ export ROOT=$(PWD)

2. 作業用ディレクトリ(e.g. work)を作成し、当該ディレクトリに移動してください。

$ mkdir -p work
$ cd work

(Optional)
作業用ディレクトリを指す環境変数 WORK を設定してください。以降の記載は本環境変数 が設定されているものとします。

$ export WORK=$(PWD)

3. iotjsのソースツリーを取得します。

$ git clone https://github.com/pando-project/iotjs

クローンが正常に終了するとiotjsというディレクトリが生成されますので、当該ディレクトリに移動してください。

$cd iotjs

コミットID: acae9c8b2d40e7598b8d39b630b79113ce880a7e を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)

$ git checkout -b posix acae9c8b2d40e7598b8d39b630b79113ce880a7e

4. mbed-osセットアップ
Mbed OSソースツリーを格納するフォルダを生成し、当該フォルダへ移動します。

$ mkdir -p $(WORK)/iotjs/src/platform/mbedos5
$ cd $(WORK)/iotjs/src/platform/mbedos5

Mbed OSのソースツリーをクローンします。

$ git clone -b mbed-os-5.9 https://github.com/ARMmbed/mbed-os.git

クローンが正常に終了するとmbed-osというディレクトリが生成されますので、当該ディレクトリに移動してください。

$ cd mbed-os

コミットID: 50bd61a4a72332baa6b1bac6caccb44dc5423309 を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)

$ git checkout -b posix 50bd61a4a72332baa6b1bac6caccb44dc5423309

5. sd-driverの取得
下記コマンドでmbedos5ディレクトリへ移動します。

$ cd $(WORK)/iotjs/src/platform/mbedos5

sd-driverをクローンします。

$ git clone https://github.com/ARMmbed/sd-driver.git

クローンが正常終了するとsd-driverディレクトリが生成されますので、当該ディレクトリへ移動します。

$ cd sd-driver

コミットID: c8ae38fb291e086232566b0f1372cfb69c277e84 を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)

$ git checkout -b posix c8ae38fb291e086232566b0f1372cfb69c277e84

6. mbed-gr-libsの取得
下記コマンドでmbedos5ディレクトリへ移動します。

$ cd $(WORK)/iotjs/src/platform/mbedos5

mbed-gr-libsをクローンします。

$ git clone https://github.com/d-kato/mbed-gr-libs

クローンが正常終了するとmbed-gr-libsディレクトリが生成されますので、当該ディレクトリへ移動します。

$ cd mbed-gr-libs

コミットID: d921d611d596ecaebaab49070ef82450c583309c を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)

$ git checkout -b posix d921d611d596ecaebaab49070ef82450c583309c

7. AsciiFONTの取得
下記コマンドでmbedos5ディレクトリへ移動します。

$ cd $(WORK)/iotjs/src/platform/mbedos5

AsciiFONTライブラリを追加します。

$ mbed add https://os.mbed.com/teams/Renesas/code/AsciiFont/

8. iotjs環境のビルド
下記コマンドでiotjs環境のビルドディレクトリに移動し、ビルドを実行します。

$ cd $(WORK)/iotjs
$ ./tools/build.py --no-snapshot

9. GR-PEACH用コードのコピー
(Optional) 既存のiotjs環境に上書きする場合、下記コマンドを実行してください。

$ rm -rf $(WORK)/iotjs/deps/posix
$ rm -rf $(WORK)/iotjs/src/ext-modules
$ rm -rf $(WORK)/iotjs/src/platform/mbedos5/iotjs_def.h

下記コマンドでGR-PEACH用コードをコピーします。

$ cp -pr $(ROOT)/src/iotjs/* $(WORK)/iotjs/

10. lwipパッチ適用
以下コマンドでlwipパッチを適用します。

$ cd $(WORK)/iotjs/src/platform/mbedos5/mbed-os
$ git apply lwip_improve.patch

11. ESP32 TRNG対応パッチ適用
以下コマンドでESP32のTRNGを活用するためのパッチを適用します。

$ cd $(WORK)/iotjs/src/platform/mbedos5/mbed-os
$ git apply trng_support.patch

12. Mbed OS版iotjs環境のビルド
下記コマンドを実行してMbed OS版iotjs環境をビルドします。
(リリースビルドの場合)

$ cd $(WORK)/iotjs/src/platform/mbedos5
$ make clean; make DEBUG=0

(デバッグビルドの場合)

$ cd $(WORK)/iotjs/src/platform/mbedos5
$ make clean; make DEBUG=1

13. ビルドが正常に終了すると、以下の通りバイナリが生成されます。
(リリースビルドの場合)

$ ls -l ${WORK}/iotjs/src/platform/mbedos5/BUILD/RZ_A1H/GCC_ARM-RELEASE/iotjs.bin

(デバッグビルドの場合)

$ ls -l ${WORK}/iotjs/src/platform/mbedos5/BUILD/RZ_A1H/GCC_ARM-DEBUG/iotjs.bin

実行方法

1. GR-PEACHにmicro SDカードを挿入します。

2. GR-PEACHのEthernetポートから遠い側のUSBポートとHost PCをマイクロUSBケーブルで接続します。

3. Host PCでGR-PEACHが『mbed:』ドライブとして認識されたら、iotjs.binをmbedドライブにコピーします。

4. ターミナルS/Wを立上げ、『mbed Serial Port』と接続します。
/media/uploads/HinoNaka/img1.jpg
シリアルポートは下記設定としてください。

Baud rate115200
Data8 bit
Paritynone
Stop1 bit
Flow controlnone

5. 正常に書込みが終了したらGR-PEACHのRESETボタンを押下します。

6. ターミナルS/W上に下記メッセージが表示されます。
/media/uploads/HinoNaka/img2.jpg

7. Enterキーを押下してコード入力モードに移行します。
/media/uploads/HinoNaka/img3.jpg

8. 実行するJavascriptコードをターミナルソフトウェアに貼り付けてEnterキーを押下すると、実行開始します。Javascriptコード例については、test/case.txtを参照ください。

src/iotjs/deps/posix/posix4.cpp

Committer:
Osamu Nakamura
Date:
2019-07-11
Revision:
0:7cc000799c93

File content as of revision 0:7cc000799c93:

/* Copyright 2017-present Renesas Electronics Corporation and other contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "./posix4_target.h"

inline const char* safe_str(const char* in) { return in ? in : "<null>"; }

char* P4(getcwd)(char* buf, P4(size_t) size)
{
	TRACE(ENTER "getcwd(buf=%p, size=%u)", buf, size);
	char* rc = posix::getcwd( buf, size );
	TRACE(LEAVE "getcwd(buf=%p, size=%u) = %s(errno:%d)", buf, size, safe_str(rc), errno);
	return rc;
}

int P4(chdir)(const char* path)
{
	TRACE(ENTER "chdir(path=%s)", safe_str(path));
	int rc = posix::chdir( path );
	TRACE(LEAVE "chdir(path=%s) = %d(errno:%d)", safe_str(path), rc, errno);
	return rc;
}

int P4(fdatasync)(int fd)
{
	TRACE(ENTER "fdatasync(fd=%d)", fd);
	int rc = posix::fdatasync( fd );
	TRACE(LEAVE "fdatasync(fd=%d) = %d(errno:%d)", fd, rc, errno);
	return rc;
}

int P4(fsync)(int fd)
{
	TRACE(ENTER "fsync(fd=%d)", fd);
	int rc = posix::fsync( fd );
	TRACE(LEAVE "fsync(fd=%d) = %d(errno:%d)", fd, rc, errno);
	return rc;
}

int P4(ftruncate)(int fd, P4(off_t) length)
{
	TRACE(ENTER "ftruncate(fd=%d, length=%ld)", fd, length);
	int rc = posix::ftruncate( fd, length );
	TRACE(LEAVE "ftruncate(fd=%d, length=%ld) = %d(errno:%d)", fd, length, rc, errno);
	return rc;
}

int P4(scandir)(const char* dirp, struct P4(dirent)*** namelist, int (*filter)(const struct P4(dirent)*), int (*compar)(const struct P4(dirent)**, const struct P4(dirent)**))
{
	TRACE(ENTER "scandir(dirp=%s, namelist=%p, filter=%p, compar=%p)", safe_str(dirp), namelist, filter, compar);
	int rc = posix::scandir( dirp, namelist, filter, compar );
	TRACE(LEAVE "scandir(dirp=%s, namelist=%p, filter=%p, compar=%p) = %d(errno:%d)", safe_str(dirp), namelist, filter, compar, rc, errno);
	return rc;
}

int P4(utime)(const char* filename, const struct P4(utimbuf)* times)
{
	TRACE(ENTER "utime(filename=%s, times=%p)", safe_str(filename), times);
	int rc = posix::utime( filename, times );
	TRACE(LEAVE "utime(filename=%s, times=%p) = %d(errno:%d)", safe_str(filename), times, rc, errno);
	return rc;
}

int P4(utimes)(const char* filename, const struct P4(timeval) times[2])
{
	TRACE(ENTER "utimes(filename=%s, times[2]=maybe_later)", safe_str(filename));
	int rc = posix::utimes( filename, times );
	TRACE(LEAVE "utimes(filename=%s, times[2]=maybe_later) = %d(errno:%d)", safe_str(filename), rc, errno);
	return rc;
}

P4(ssize_t) P4(pread)(int fd, void* buf, P4(size_t) count, P4(off_t) offset)
{
	TRACE(ENTER "pread(fd=%d, buf=%p, count=%d, offset=%ld)", fd, buf, count, offset);
	P4(ssize_t) rc = posix::pread( fd, buf, count, offset );
	TRACE(LEAVE "pread(fd=%d, buf=%p, count=%d, offset=%ld) = %d(errno:%d)", fd, buf, count, offset, rc, errno);
	return rc;
}

P4(ssize_t) P4(pwrite)(int fd, const void* buf, P4(size_t) count, P4(off_t) offset)
{
	TRACE(ENTER "pwrite(fd=%d, buf=%p, count=%d, offset=%ld)", fd, buf, count, offset);
	P4(ssize_t) rc = posix::pwrite( fd, buf, count, offset );
	TRACE(LEAVE "pwrite(fd=%d, buf=%p, count=%d, offset=%ld) = %d(errno:%d)", fd, buf, count, offset, rc, errno);
	return rc;
}

P4(ssize_t) P4(readv)(int fd, const struct P4(iovec)* iov, int iovcnt)
{
	TRACE(ENTER "readv(fd=%d, iov=%p, iovcnt=%d)", fd, iov, iovcnt);
	P4(ssize_t) rc = posix::readv( fd, iov, iovcnt );
	TRACE(LEAVE "readv(fd=%d, iov=%p, iovcnt=%d) = %d(errno:%d)", fd, iov, iovcnt, rc, errno);
	return rc;
}

P4(ssize_t) P4(writev)(int fd, const struct P4(iovec)* iov, int iovcnt)
{
	TRACE(ENTER "writev(fd=%d, iov=%p, iovcnt=%d)", fd, iov, iovcnt);
	P4(ssize_t) rc = posix::writev( fd, iov, iovcnt );
	TRACE(LEAVE "writev(fd=%d, iov=%p, iovcnt=%d) = %d(errno:%d)", fd, iov, iovcnt, rc, errno);
	return rc;
}

int P4(utimensat)(int dirfd, const char* pathname, const struct P4(timespec) times[2], int flags)
{
	TRACE(ENTER "utimensat(dirfd=%d, pathname=%s, times=%p, flags=%d)", dirfd, safe_str(pathname), times, flags);
	int rc = posix::utimensat( dirfd, pathname, times, flags );
	TRACE(LEAVE "utimensat(dirfd=%d, pathname=%s, times=%p, flags=%d) = %d(errno:%d)", dirfd, safe_str(pathname), times, flags, rc, errno);
	return rc;
}

int P4(clock_getres)(P4(clockid_t) clk_id, struct P4(timespec)* res)
{
	TRACE(ENTER "clock_getres(clk_id=%lu, res=%p)", clk_id, res);
	int rc = posix::clock::getres( clk_id, res );
	TRACE(LEAVE "clock_getres(clk_id=%lu, res={%ld.%09ld}) = %d(errno:%d)", clk_id, res->tv_sec, res->tv_nsec, rc, errno);
	return rc;
}

int P4(clock_gettime)(P4(clockid_t) clk_id, struct P4(timespec)* tp)
{
	TRACE(ENTER "clock_gettime(clk_id=%lu, tp=%p)", clk_id, tp);
	int rc = posix::clock::gettime( clk_id, tp );
	TRACE(LEAVE "clock_gettime(clk_id=%lu, tp={%ld.%09ld}) = %d(errno:%d)", clk_id, tp->tv_sec, tp->tv_nsec, rc, errno);
	return rc;
}

int P4(pthread_create)(P4(pthread_t)* thread, P4(pthread_attr_t)* attr, void* (*start_routine)(void*), void* arg)
{
	TRACE(ENTER "pthread_create(thread=%p, attr=%p, start_routine=%p, arg=%p)", thread, attr, start_routine, arg);
	int rc = posix::pthread::create( thread, attr, start_routine, arg );
	TRACE(LEAVE "pthread_create(thread={%p}, attr=%p, start_routine=%p, arg=%p) = %d", *thread, attr, start_routine, arg, rc);
	return rc;
}

int P4(pthread_join)(P4(pthread_t) thread, void** retval)
{
	TRACE(ENTER "pthread_join(thread=%p, retval=%p)", thread, retval);
	int rc = posix::pthread::join( thread, retval );
	TRACE(LEAVE "pthread_join(thread=%p, retval=%p) = %d", thread, retval, rc);
	return rc;
}

int P4(pthread_once)(P4(pthread_once_t)* once_control, void (*init_routine)(void))
{
	TRACE(ENTER "pthread_once(once_control={0x%08X}, init_routine=%p)", *once_control, init_routine);
	int rc = posix::pthread::once( once_control, init_routine );
	TRACE(LEAVE "pthread_once(once_control={0x%08X}, init_routine=%p) = %d", *once_control, init_routine, rc);
	return rc;
}

int P4(pthread_sigmask)(int how, const P4(sigset_t)* set, P4(sigset_t)* oldset)
{
	TRACE(ENTER "pthread_sigmask(how=%d, set=%p, oldset=%p)", how, set, oldset);
	int rc = posix::pthread::sigmask( how, set, oldset );
	TRACE(LEAVE "pthread_sigmask(how=%d, set=%p, oldset=%p) = %d", how, set, oldset, rc);
	return rc;
}

int P4(pthread_attr_destroy)(P4(pthread_attr_t)* attr)
{
	TRACE(ENTER "pthread_attr_destroy(attr=%p)", attr);
	int rc = posix::pthread::attr::destroy( attr );
	TRACE(LEAVE "pthread_attr_destroy(attr=%p) = %d", attr, rc);
	return rc;
}

int P4(pthread_cond_destroy)(P4(pthread_cond_t)* cond)
{
	TRACE(ENTER "pthread_cond_destroy(cond=%p)", cond);
	int rc = posix::pthread::cond::destroy( cond );
	TRACE(LEAVE "pthread_cond_destroy(cond=%p) = %d", cond, rc);
	return rc;
}

int P4(pthread_cond_init)(P4(pthread_cond_t)* cond, P4(pthread_condattr_t)* cond_attr)
{
	TRACE(ENTER "pthread_cond_init(cond=%p, cond_attr=%p)", cond, cond_attr);
	int rc = posix::pthread::cond::init( cond, cond_attr );
	TRACE(LEAVE "pthread_cond_init(cond=%p, cond_attr=%p) = %d", cond, cond_attr, rc);
	return rc;
}

int P4(pthread_cond_signal)(P4(pthread_cond_t)* cond)
{
	TRACE(ENTER "pthread_cond_signal(cond=%p)", cond);
	int rc = posix::pthread::cond::signal( cond );
	TRACE(LEAVE "pthread_cond_signal(cond=%p) = %d", cond, rc);
	return rc;
}

int P4(pthread_cond_wait)(P4(pthread_cond_t)* cond, P4(pthread_mutex_t)* mutex)
{
	TRACE(ENTER "pthread_cond_wait(cond=%p, mutex=%p)", cond, mutex);
	int rc = posix::pthread::cond::wait( cond, mutex );
	TRACE(LEAVE "pthread_cond_wait(cond=%p, mutex=%p) = %d", cond, mutex, rc);
	return rc;
}

int P4(pthread_condattr_destroy)(P4(pthread_condattr_t)* attr)
{
	TRACE(ENTER "pthread_condattr_destroy(attr=%p)", attr);
	int rc = posix::pthread::condattr::destroy( attr );
	TRACE(LEAVE "pthread_condattr_destroy(attr=%p) = %d", attr, rc);
	return rc;
}

int P4(pthread_condattr_init)(P4(pthread_condattr_t)* attr)
{
	TRACE(ENTER "pthread_condattr_init(attr=%p)", attr);
	int rc = posix::pthread::condattr::init( attr );
	TRACE(LEAVE "pthread_condattr_init(attr=%p) = %d", attr, rc);
	return rc;
}

int P4(pthread_condattr_setclock)(P4(pthread_condattr_t)* attr, P4(clockid_t) clock_id)
{
	TRACE(ENTER "pthread_condattr_setclock(attr=%p, clock_id=%lu)", attr, clock_id);
	int rc = posix::pthread::condattr::setclock( attr, clock_id );
	TRACE(LEAVE "pthread_condattr_setclock(attr=%p, clock_id=%lu) = %d", attr, clock_id, rc);
	return rc;
}

int P4(pthread_mutex_destroy)(P4(pthread_mutex_t)* mutex)
{
	TRACE(ENTER "pthread_mutex_destroy(mutex=%p)", mutex);
	int rc = posix::pthread::mutex::destroy( mutex );
	TRACE(LEAVE "pthread_mutex_destroy(mutex=%p) = %d", mutex, rc);
	return rc;
}

int P4(pthread_mutex_init)(P4(pthread_mutex_t)* mutex, const P4(pthread_mutexattr_t)* mutexattr)
{
	TRACE(ENTER "pthread_mutex_init(mutex=%p, mutexattr=%p)", mutex, mutexattr);
	int rc = posix::pthread::mutex::init( mutex, mutexattr );
	TRACE(LEAVE "pthread_mutex_init(mutex=%p, mutexattr=%p) = %d", mutex, mutexattr, rc);
	return rc;
}

int P4(pthread_mutex_lock)(P4(pthread_mutex_t)* mutex)
{
	TRACE(ENTER "pthread_mutex_lock(mutex=%p)", mutex);
	int rc = posix::pthread::mutex::lock( mutex );
	TRACE(LEAVE "pthread_mutex_lock(mutex=%p) = %d", mutex, rc);
	return rc;
}

int P4(pthread_mutex_unlock)(P4(pthread_mutex_t)* mutex)
{
	TRACE(ENTER "pthread_mutex_unlock(mutex=%p)", mutex);
	int rc = posix::pthread::mutex::unlock( mutex );
	TRACE(LEAVE "pthread_mutex_unlock(mutex=%p) = %d", mutex, rc);
	return rc;
}

int P4(pthread_rwlock_destroy)(P4(pthread_rwlock_t)* rwlock)
{
	TRACE(ENTER "pthread_rwlock_destroy(rwlock=%p)", rwlock);
	int rc = posix::pthread::rwlock::destroy( rwlock );
	TRACE(LEAVE "pthread_rwlock_destroy(rwlock=%p) = %d", rwlock, rc);
	return rc;
}

int P4(pthread_rwlock_init)(P4(pthread_rwlock_t)* rwlock, const P4(pthread_rwlockattr_t)* attr)
{
	TRACE(ENTER "pthread_rwlock_init(rwlock=%p, attr=%p)", rwlock, attr);
	int rc = posix::pthread::rwlock::init( rwlock, attr );
	TRACE(LEAVE "pthread_rwlock_init(rwlock=%p, attr=%p) = %d", rwlock, attr, rc);
	return rc;
}

int P4(pthread_rwlock_rdlock)(P4(pthread_rwlock_t)* rwlock)
{
	TRACE(ENTER "pthread_rwlock_rdlock(rwlock=%p)", rwlock);
	int rc = posix::pthread::rwlock::rdlock( rwlock );
	TRACE(LEAVE "pthread_rwlock_rdlock(rwlock=%p) = %d", rwlock, rc);
	return rc;
}

int P4(pthread_rwlock_unlock)(P4(pthread_rwlock_t)* rwlock)
{
	TRACE(ENTER "pthread_rwlock_unlock(rwlock=%p)", rwlock);
	int rc = posix::pthread::rwlock::unlock( rwlock );
	TRACE(LEAVE "pthread_rwlock_unlock(rwlock=%p) = %d", rwlock, rc);
	return rc;
}

struct P4(cmsghdr)* P4(cmsg_nxthdr)(struct P4(msghdr)* mhdr, struct P4(cmsghdr)* cmsg)
{
#define OFFSET(addr, bytes)	((void*)((char*)addr + bytes))
	if((P4(size_t))cmsg->cmsg_len < sizeof( struct P4(cmsghdr) )) {
		return 0;
	}
	cmsg = (struct P4(cmsghdr)*)OFFSET( cmsg, CMSG_ALIGN( cmsg->cmsg_len ) );
	if( cmsg + 1 > OFFSET( mhdr->msg_control, mhdr->msg_controllen ) ) {
		return 0;
	}
	if( OFFSET( cmsg, CMSG_ALIGN( cmsg->cmsg_len ) ) > OFFSET( mhdr->msg_control, mhdr->msg_controllen ) ) {
		return 0;
	}
#undef OFFSET
	return cmsg;
}

int P4(accept)(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen)
{
	TRACE(ENTER "accept(sockfd=%d, addr=%p, addrlen=%p)", sockfd, addr, addrlen);
	int rc = posix::sock::accept( sockfd, addr, addrlen );
	TRACE(LEAVE "accept(sockfd=%d, addr=%p, addrlen=%p) = %d(errno:%d)", sockfd, addr, addrlen, rc, errno);
	return rc;
}

int P4(bind)(int sockfd, const struct P4(sockaddr)* addr, P4(socklen_t) addrlen)
{
	TRACE(ENTER "bind(sockfd=%d, addr=%p, addrlen=%lu)", sockfd, addr, addrlen);
	int rc = posix::sock::bind( sockfd, addr, addrlen );
	TRACE(LEAVE "bind(sockfd=%d, addr=%p, addrlen=%lu) = %d(errno:%d)", sockfd, addr, addrlen, rc, errno);
	return rc;
}

int P4(connect)(int sockfd, const struct P4(sockaddr)* addr, P4(socklen_t) addrlen)
{
	TRACE(ENTER "connect(sockfd=%d, addr=%p, addrlen=%lu)", sockfd, addr, addrlen);
	int rc = posix::sock::connect( sockfd, addr, addrlen );
	TRACE(LEAVE "connect(sockfd=%d, addr=%p, addrlen=%lu) = %d(errno:%d)", sockfd, addr, addrlen, rc, errno);
	return rc;
}

void P4(freeaddrinfo)(struct P4(addrinfo)* res)
{
	TRACE(ENTER "freeaddrinfo(res=%p)", res);
	posix::sock::freeaddrinfo( res );
	TRACE(LEAVE "freeaddrinfo(res=%p)", res);
}

int P4(getaddrinfo)(const char* node, const char* service, const struct P4(addrinfo)* hints, struct P4(addrinfo)** res)
{
	TRACE(ENTER "getaddrinfo(node={%s}, service={%s}, hints=%p, res=%p)", safe_str(node), safe_str(service), hints, res);
	int rc = posix::sock::getaddrinfo( node, service, hints, res );
	TRACE(LEAVE "getaddrinfo(node={%s}, service={%s}, hints=%p, res=%p) = %d", safe_str(node), safe_str(service), hints, res, rc);
	return rc;
}

int P4(getsockname)(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen)
{
	TRACE(ENTER "getsockname(sockfd=%d, addr=%p, addrlen={%ld})", sockfd, addr, *addrlen);
	int rc = posix::sock::getsockname( sockfd, addr, addrlen );
	TRACE(LEAVE "getsockname(sockfd=%d, addr=%p, addrlen={%ld}) = %d(errno:%d)", sockfd, addr, *addrlen, rc, errno);
	return rc;
}

int P4(getsockopt)(int sockfd, int level, int optname, void* optval, P4(socklen_t)* optlen)
{
	TRACE(ENTER "getsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%p)", sockfd, level, optname, optval, optlen);
	uint32_t rc = posix::sock::getsockopt( sockfd, level, optname, optval, optlen );
	TRACE(LEAVE "getsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%p) = %lu(errno:%d)", sockfd, level, optname, optval, optlen, rc, errno);
	return rc;
}

uint32_t P4(htonl)(uint32_t hostlong)
{
	TRACE(ENTER "htonl(hostlong=0x%08lX)", hostlong);
	uint32_t rc = posix::sock::htonl( hostlong );
	TRACE(LEAVE "htonl(hostlong=0x%08lX) = 0x%08lX", hostlong, rc);
	return rc;
}

uint16_t P4(htons)(uint16_t hostshort)
{
	TRACE(ENTER "htons(hostshort=0x%04X)", hostshort);
	uint16_t rc = posix::sock::htons( hostshort );
	TRACE(LEAVE "htons(hostshort=0x%04X) = 0x%04X", hostshort, rc);
	return rc;
}

unsigned int P4(if_nametoindex)(const char* ifname)
{
	TRACE(ENTER "if_nametoindex(ifname={%s})", safe_str(ifname));
	unsigned int rc = posix::sock::if_nametoindex( ifname );
	TRACE(LEAVE "if_nametoindex(ifname={%s}) = %u(errno:%d)", safe_str(ifname), rc, errno);
	return rc;
}

int P4(listen)(int sockfd, int backlog)
{
	TRACE(ENTER "listen(sockfd=%d, backlog=%d)", sockfd, backlog);
	int rc = posix::sock::listen( sockfd, backlog );
	TRACE(LEAVE "listen(sockfd=%d, backlog=%d) = %d(errno:%d)", sockfd, backlog, rc, errno);
	return rc;
}

uint16_t P4(ntohs)(uint16_t netshort)
{
	TRACE(ENTER "ntohs(netshort=0x%04X)", netshort);
	uint16_t rc = posix::sock::ntohs( netshort );
	TRACE(LEAVE "ntohs(netshort=0x%04X) = 0x%04X", netshort, rc);
	return rc;
}

P4(ssize_t) P4(recvmsg)(int sockfd, struct P4(msghdr)* msg, int flags)
{
	TRACE(ENTER "recvmsg(sockfd=%d, msg=%p, flags=%d)", sockfd, msg, flags);
	P4(ssize_t) rc = posix::sock::recvmsg( sockfd, msg, flags );
	TRACE(LEAVE "recvmsg(sockfd=%d, msg=%p, flags=%d) = %d(errno:%d)", sockfd, msg, flags, rc, errno);
	return rc;
}

P4(ssize_t) P4(sendmsg)(int sockfd, const struct P4(msghdr)* msg, int flags)
{
	TRACE(ENTER "sendmsg(sockfd=%d, msg=%p, flags=%d)", sockfd, msg, flags);
	P4(ssize_t) rc = posix::sock::sendmsg( sockfd, msg, flags );
	TRACE(LEAVE "sendmsg(sockfd=%d, msg=%p, flags=%d) = %d(errno:%d)", sockfd, msg, flags, rc, errno);
	return rc;
}

int P4(setsockopt)(int sockfd, int level, int optname, const void* optval, P4(socklen_t) optlen)
{
	TRACE(ENTER "setsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%lu)", sockfd, level, optname, optval, optlen);
	int rc = posix::sock::setsockopt( sockfd, level, optname, optval, optlen );
	TRACE(LEAVE "setsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%lu) = %d(errno:%d)", sockfd, level, optname, optval, optlen, rc, errno);
	return rc;
}

int P4(shutdown)(int sockfd, int how)
{
	TRACE(ENTER "shutdown(sockfd=%d, how=%d)", sockfd, how);
	int rc = posix::sock::shutdown( sockfd, how );
	TRACE(LEAVE "shutdown(sockfd=%d, how=%d) = %d(errno:%d)", sockfd, how, rc, errno);
	return rc;
}

int P4(socket)(int domain, int type, int protocol)
{
	TRACE(ENTER "socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol);
	int rc = posix::sock::socket( domain, type, protocol );
	TRACE(LEAVE "socket(domain=%d, type=%d, protocol=%d) = %d(errno:%d)", domain, type, protocol, rc, errno);
	return rc;
}

int P4(nanosleep)(const struct P4(timespec)* req, struct P4(timespec)* rem)
{
	return posix::sys::nanosleep( req, rem );
}

int P4(pipe)(int pipefd[2])
{
	TRACE(ENTER "pipe(pipefd[2]=[%d,%d])", pipefd[0], pipefd[1]);
	int rc = posix::sys::pipe( pipefd );
	TRACE(LEAVE "pipe(pipefd[2]=[%d,%d]) = %d(errno:%d)", pipefd[0], pipefd[1], rc, errno);
	return rc;
}

long P4(sysconf)(int name)
{
	TRACE(ENTER "sysconf(name=%d)", name);
	long rc = posix::sys::sysconf( name );
	TRACE(LEAVE "sysconf(name=%d) = %ld(errno:%d)", name, rc, errno);
	return rc;
}


P4(ssize_t) P4(preadv)(int fd, const struct P4(iovec)* iov, int iovcnt, P4(off_t) offset)
{
	TRACE(ENTER "preadv(fd=%d, iov=%p, iovcnt=%d, offset=%ld)", fd, iov, iovcnt, offset);
	P4(ssize_t) rc = linux::preadv( fd, iov, iovcnt, offset );
	TRACE(LEAVE "preadv(fd=%d, iov=%p, iovcnt=%d, offset=%ld) = %d(errno:%d)", fd, iov, iovcnt, offset, rc, errno);
	return rc;
}

P4(ssize_t) P4(pwritev)(int fd, const struct P4(iovec)* iov, int iovcnt, P4(off_t) offset)
{
	TRACE(ENTER "pwritev(fd=%d, iov=%p, iovcnt=%d, offset=%ld)", fd, iov, iovcnt, offset);
	P4(ssize_t) rc = linux::pwritev( fd, iov, iovcnt, offset );
	TRACE(LEAVE "pwritev(fd=%d, iov=%p, iovcnt=%d, offset=%ld) = %d(errno:%d)", fd, iov, iovcnt, offset, rc, errno);
	return rc;
}

int P4(epoll_create)(int size)
{
	TRACE(ENTER "epoll_create(size=%d)", size);
	int rc = linux::epoll::create( size );
	TRACE(LEAVE "epoll_create(size=%d) = %d(errno:%d)", size, rc, errno);
	return rc;
}

int P4(epoll_create1)(int flags)
{
	TRACE(ENTER "epoll_create1(flags=0x%08X)", flags);
	int rc = linux::epoll::create1( flags );
	TRACE(LEAVE "epoll_create1(flags=0x%08X) = %d(errno:%d)", flags, rc, errno);
	return rc;
}

int P4(epoll_ctl)(int epfd, int op, int fd, struct P4(poll_event)* event)
{
	TRACE(ENTER "epoll_ctl(epfd=%d, op=%d, fd=%d, event=%p{0x%08lX})", epfd, op, fd, event, event->events);
	int rc = linux::epoll::ctl( epfd, op, fd, event );
	TRACE(LEAVE "epoll_ctl(epfd=%d, op=%d, fd=%d, event=%p) = %d(errno:%d)", epfd, op, fd, event, rc, errno);
	return rc;
}

int P4(epoll_pwait)(int epfd, struct P4(poll_event)* events, int maxevents, int timeout, const P4(sigset_t)* sigmask)
{
	TRACE(ENTER "epoll_pwait(epfd=%d, events=%p, maxevents=%d, timeout=%d, sigmask=%p)", epfd, events, maxevents, timeout, sigmask);
	int rc = linux::epoll::pwait( epfd, events, maxevents, timeout, sigmask );
	TRACE(LEAVE "epoll_pwait(epfd=%d, events=%p, maxevents=%d, timeout=%d, sigmask=%p) = %d(errno:%d)", epfd, events, maxevents, timeout, sigmask, rc, errno);
	return rc;
}

int P4(epoll_wait)(int epfd, struct P4(poll_event)* events, int maxevents, int timeout)
{
	TRACE(ENTER "epoll_wait(epfd=%d, events=%p, maxevents=%d, timeout=%d)", epfd, events, maxevents, timeout);
	int rc = linux::epoll::wait( epfd, events, maxevents, timeout );
	TRACE(LEAVE "epoll_wait(epfd=%d, events=%p, maxevents=%d, timeout=%d) = %d(errno:%d)", epfd, events, maxevents, timeout, rc, errno);
	return rc;
}

int P4(eventfd)(unsigned int initval, int flags)
{
	TRACE(ENTER "eventfd(initval=%u, flags=%d)", initval, flags);
	int rc = linux::epoll::eventfd( initval, flags );
	TRACE(LEAVE "eventfd(initval=%u, flags=%d) = %d(errno:%d)", initval, flags, rc, errno);
	return rc;
}

int P4(eventfd2)(unsigned int initval, int flags)
{
	TRACE(ENTER "eventfd2(initval=%u, flags=0x%08X)", initval, flags);
	int rc = linux::epoll::eventfd2( initval, flags );
	TRACE(LEAVE "eventfd2(initval=%u, flags=0x%08X) = %d(errno:%d)", initval, flags, rc, errno);
	return rc;
}

int P4(accept4)(int fd, struct P4(sockaddr)* addr, P4(socklen_t)* addr_len, int flags)
{
	TRACE(ENTER "accept4(fd=%d, addr=%p, addr_len=%p, flags=%d)", fd, addr, addr_len, flags);
	int rc = linux::sock::accept4( fd, addr, addr_len, flags );
	TRACE(LEAVE "accept4(fd=%d, addr=%p, addr_len=%p, flags=%d) = %d(errno:%d)", fd, addr, addr_len, flags, rc, errno);
	return rc;
}

int P4(socketcall)(int call, unsigned long* args)
{
	TRACE(ENTER "socketcall(call=%d, args=%p)", call, args);
	int rc = linux::sock::socketcall( call, args );
	TRACE(LEAVE "socketcall(call=%d, args=%p) = %d(errno:%d)", call, args, rc, errno);
	return rc;
}

int P4(ioctl)(int fd, unsigned long request, ...)
{
	TRACE(ENTER "ioctl(fd=%d, request=0x%08lX, ...)", fd, request);
	va_list args;
	va_start( args, request );
	int rc = linux::sys::ioctl( fd, request, args );
	va_end( args );
	TRACE(LEAVE "ioctl(fd=%d, request=0x%08lX, ...) = %d(errno:%d)", fd, request, rc, errno);
	return rc;
}

long P4(syscall)(long number, ...)
{
	TRACE(ENTER "syscall(number=%ld, ...)", number);
	va_list args;
	va_start( args, number );
	long rc = linux::sys::syscall( number, args );
	va_end( args );
	TRACE(LEAVE "syscall(number=%ld, ...) = %ld(errno:%d)", number, rc, errno);
	return rc;
}

int P4(pipe2)(int pipefd[2], int flags)
{
	TRACE(ENTER "pipe2(pipefd[]=[%d, %d], flags=%d)", pipefd[0], pipefd[1], flags);
	int rc = linux::sys::pipe2( pipefd, flags );
	TRACE(LEAVE "pipe2(pipefd[]=[%d, %d], flags=%d) = %d(errno:%d)", pipefd[0], pipefd[1], flags, rc, errno);
	return rc;
}

void* P4(dlopen)(const char* filename, int flag)
{
	TRACE(ENTER "dlopen(filename=%s, flag=%d)", safe_str(filename), flag);
	void* rc = linux::sys::dlopen( filename, flag );
	TRACE(ENTER "dlopen(filename=%s, flag=%d) = %p", safe_str(filename), flag, rc);
	return rc;
}

void* P4(dlsym)(void* handle, char* symbol)
{
	TRACE(ENTER "dlsym(handle=%p, symbol=%s)", handle, safe_str(symbol));
	void* rc = linux::sys::dlsym( handle, symbol );
	TRACE(ENTER "dlsym(handle=%p, symbol=%s) = %p", handle, safe_str(symbol), rc);
	return rc;
}

int P4(dlclose)(void* handle)
{
	TRACE(ENTER "dlclose(handle=%p)", handle);
	int rc = linux::sys::dlclose( handle );
	TRACE(ENTER "dlclose(handle=%p) = %d", handle, rc);
	return rc;
}

char** P4(backtrace_symbols)(void*const* buffer, int size)
{
	TRACE(ENTER "backtrace_symbols(buffer=%p, size=%d)", buffer, size);
	char** rc = linux::debug::backtrace_symbols( buffer, size );
	TRACE(LEAVE "backtrace_symbols(buffer=%p, size=%d) = %p", buffer, size, rc);
	return rc;
}

int P4(backtrace)(void** buffer, int size)
{
	TRACE(ENTER "backtrace(buffer=%p, size=%d)", buffer, size);
	int rc = linux::debug::backtrace( buffer, size );
	TRACE(LEAVE "backtrace(buffer=%p, size=%d) = %d", buffer, size, rc);
	return rc;
}


void P4(abort)(void)
{
	TRACE(INFO "abort called from [%p]", CALLED_FROM);
	overridden::abort();
}

int P4(gettimeofday)(struct P4(timeval)* tv, void* tz)
{
	TRACE(ENTER "overridden_gettimeofday(tv=%d, tz=%p)", tv, tz);
	int rc = overridden::gettimeofday( tv, tz );
	TRACE(LEAVE "overridden_gettimeofday(tv=%d, tz=%p) = %d(errno:%d)", tv, tz, rc, errno);
	return rc;
}

P4(ssize_t) P4(read)(int fd, void* buf, P4(size_t) count)
{
	TRACE(ENTER "overridden_read(fd=%d, buf=%p, count=%u)", fd, buf, count);
	P4(ssize_t) rc = overridden::read( fd, buf, count );
	TRACE(LEAVE "overridden_read(fd=%d, buf=%p, count=%u) = %d(errno:%d)", fd, buf, count, rc, errno);
	return rc;
}

P4(ssize_t) P4(write)(int fd, const void* buf, P4(size_t) count)
{
	TRACE(ENTER "overridden_write(fd=%d, buf=%p, count=%u)", fd, buf, count);
	P4(ssize_t) rc = overridden::write( fd, buf, count );
	TRACE(LEAVE "overridden_write(fd=%d, buf=%p, count=%u) = %d(errno:%d)", fd, buf, count, rc, errno);
	return rc;
}

int P4(open)(const char* pathname, ...)
{
	TRACE(ENTER "overridden_open(pathname=%s, ...)", safe_str(pathname));
	va_list args;
	va_start( args, pathname );
	int rc = overridden::open( pathname, args );
	va_end( args );
	TRACE(LEAVE "overridden_open(pathname=%s, ...) = %d(errno:%d)", safe_str(pathname), rc, errno);
	return rc;
}

int P4(close)(int fd)
{
	TRACE(ENTER "overridden_close(fd=%d)", fd);
	int rc = overridden::close( fd );
	TRACE(LEAVE "overridden_close(fd=%d) = %d(errno:%d)", fd, rc, errno);
	return rc;
}

int P4(unlink)(const char* pathname)
{
	TRACE(ENTER "overridden_unlink(pathname=%s)", safe_str(pathname));
	int rc = overridden::unlink( pathname );
	TRACE(LEAVE "overridden_unlink(pathname=%s) = %d(errno:%d)", safe_str(pathname), rc, errno);
	return rc;
}

int P4(mkdir)(const char* pathname, P4(mode_t) mode)
{
	TRACE(ENTER "overridden_mkdir(pathname=%s, mode=0x%04X)", safe_str(pathname), mode);
	int rc = overridden::mkdir( pathname, mode );
	TRACE(LEAVE "overridden_mkdir(pathname=%s, mode=0x%04X) = %d(errno:%d)", safe_str(pathname), mode, rc, errno);
	return rc;
}

int P4(rmdir)(const char* pathname)
{
	TRACE(ENTER "overridden_rmdir(pathname=%s)", safe_str(pathname));
	int rc = overridden::rmdir( pathname );
	TRACE(LEAVE "overridden_rmdir(pathname=%s) = %d(errno:%d)", safe_str(pathname), rc, errno);
	return rc;
}

int P4(stat)(const char* pathname, P4(stat_t)* buf)
{
	TRACE(ENTER "overridden_stat(pathname=%s, buf=%p)", safe_str(pathname), buf);
	int rc = overridden::stat( pathname, buf );
	TRACE(LEAVE "overridden_stat(pathname=%s, buf=%p) = %d(errno:%d)", safe_str(pathname), buf, rc, errno);
	return rc;
}

int P4(fstat)(int fd, P4(stat_t)* buf)
{
	TRACE(ENTER "overridden_fstat(fd=%d, buf=%p)", fd, buf);
	int rc = overridden::fstat( fd, buf );
	TRACE(LEAVE "overridden_fstat(fd=%d, buf=%p) = %d(errno:%d)", fd, buf, rc, errno);
	return rc;
}


char* P4(nic_enumerate)(void)
{
	TRACE(ENTER "nic_enumerate()");
	char* rc = nic::enumerate();
	TRACE(LEAVE "nic_enumerate() = {%s}", safe_str(rc));
	return rc;
}

int P4(nic_ifup)(const char* nic, const char* params)
{
	TRACE(ENTER "nic_ifup(nic={%s}, params={%s})", safe_str(nic), safe_str(params));
	int rc = nic::ifup( nic, params );
	TRACE(LEAVE "nic_ifup(nic={%s}, params={%s}) = %d", safe_str(nic), safe_str(params), rc);
	return rc;
}

int P4(nic_ifdown)(const char* nic)
{
	TRACE(ENTER "nic_ifdown(nic={%s})", safe_str(nic));
	int rc = nic::ifdown( nic );
	TRACE(LEAVE "nic_ifdown(nic={%s}) = %d", safe_str(nic), rc);
	return rc;
}

char* P4(nic_ifconfig)(const char* nic)
{
	TRACE(ENTER "nic_ifconfig(nic={%s})", safe_str(nic));
	char* rc = nic::ifconfig( nic );
	TRACE(LEAVE "nic_ifconfig(nic={%s}) = {%s}", safe_str(nic), safe_str(rc));
	return rc;
}

int P4(nic_ntpdate)(const char* nic, const char* server, int port, int timeout)
{
	TRACE(ENTER "nic_ntpdate(nic={%s}, server={%s}, port=%d, timeout=%d)", safe_str(nic), safe_str(server), port, timeout);
	int rc = nic::ntpdate( nic, server, port, timeout );
	TRACE(LEAVE "nic_ntpdate(nic={%s}, server={%s}, port=%d, timeout=%d) = %d", safe_str(nic), safe_str(server), port, timeout, rc);
	return rc;
}