diff --git a/ports/include/noux_session/noux_session.h b/ports/include/noux_session/noux_session.h index 7698eb0f1..197bf56db 100644 --- a/ports/include/noux_session/noux_session.h +++ b/ports/include/noux_session/noux_session.h @@ -75,6 +75,7 @@ namespace Noux { SYSCALL_GETTIMEOFDAY, SYSCALL_CLOCK_GETTIME, SYSCALL_UTIMES, + SYSCALL_SYNC, SYSCALL_INVALID = -1 }; @@ -122,6 +123,7 @@ namespace Noux { NOUX_DECL_SYSCALL_NAME(GETTIMEOFDAY) NOUX_DECL_SYSCALL_NAME(CLOCK_GETTIME) NOUX_DECL_SYSCALL_NAME(UTIMES) + NOUX_DECL_SYSCALL_NAME(SYNC) case SYSCALL_INVALID: return 0; } return 0; diff --git a/ports/include/noux_session/sysio.h b/ports/include/noux_session/sysio.h index 535525389..1e21d71c5 100644 --- a/ports/include/noux_session/sysio.h +++ b/ports/include/noux_session/sysio.h @@ -494,6 +494,8 @@ namespace Noux { SYSIO_DECL(utimes, { Path path; unsigned long sec; unsigned long usec; }, { }); + + SYSIO_DECL(sync, { }, { }); }; }; }; diff --git a/ports/src/lib/libc_noux/plugin.cc b/ports/src/lib/libc_noux/plugin.cc index 12910942e..dc1887c17 100644 --- a/ports/src/lib/libc_noux/plugin.cc +++ b/ports/src/lib/libc_noux/plugin.cc @@ -550,6 +550,12 @@ void endpwent(void) } +extern "C" void sync(void) +{ + noux_syscall(Noux::Session::SYSCALL_SYNC); +} + + /******************** ** Time functions ** ********************/ diff --git a/ports/src/noux/dir_file_system.h b/ports/src/noux/dir_file_system.h index 608f5d606..84954d67c 100644 --- a/ports/src/noux/dir_file_system.h +++ b/ports/src/noux/dir_file_system.h @@ -652,6 +652,30 @@ namespace Noux { char const *name() const { return "dir"; } + /** + * Synchronize all file systems + * + * Only file system using the File_system_session interface are + * synchronized. + */ + void sync() + { + for (File_system *fs = _first_file_system; fs; fs = fs->next) { + Fs_file_system *fs_fs = dynamic_cast(fs); + if (fs_fs) { + fs_fs->sync(); + continue; + } + + /* the directory might contain Fs_file_systems */ + Dir_file_system *dir_fs = dynamic_cast(fs); + if (dir_fs) { + dir_fs->sync(); + continue; + } + } + } + /******************************** ** File I/O service interface ** diff --git a/ports/src/noux/file_system.h b/ports/src/noux/file_system.h index 446e9e5b8..59ed17cb6 100644 --- a/ports/src/noux/file_system.h +++ b/ports/src/noux/file_system.h @@ -42,6 +42,15 @@ namespace Noux { * This function is used for debugging only. */ virtual char const *name() const = 0; + + /** + * Synchronize file system + * + * This function is only used by a Fs_file_system because such a + * file system may employ a backend, which maintains a internal + * cache, that needs to be flushed. + */ + virtual void sync() { } }; } diff --git a/ports/src/noux/fs_file_system.h b/ports/src/noux/fs_file_system.h index bd1fa60d7..e2d94764d 100644 --- a/ports/src/noux/fs_file_system.h +++ b/ports/src/noux/fs_file_system.h @@ -576,6 +576,11 @@ namespace Noux { char const *name() const { return "fs"; } + void sync() + { + _fs.sync(); + } + /******************************** ** File I/O service interface ** diff --git a/ports/src/noux/main.cc b/ports/src/noux/main.cc index 4a7c6e5ab..b60008c52 100644 --- a/ports/src/noux/main.cc +++ b/ports/src/noux/main.cc @@ -789,6 +789,12 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) return true; } + case SYSCALL_SYNC: + { + root_dir()->sync(); + return true; + } + case SYSCALL_SOCKET: case SYSCALL_GETSOCKOPT: case SYSCALL_SETSOCKOPT: diff --git a/ports/src/noux/net/net.cc b/ports/src/noux/net/net.cc index 8f1d347d0..894cd795f 100644 --- a/ports/src/noux/net/net.cc +++ b/ports/src/noux/net/net.cc @@ -111,6 +111,7 @@ bool Noux::Child::_syscall_net(Noux::Session::Syscall sc) case SYSCALL_GETTIMEOFDAY: case SYSCALL_CLOCK_GETTIME: case SYSCALL_UTIMES: + case SYSCALL_SYNC: break; case SYSCALL_SOCKET: {