+ const tVFS_NodeType* nodetype = h->Node->Type;
+ if(!nodetype || !nodetype->Write) {
+ LOG("FD%i has no write method", FD);
+ errno = EINTERNAL;
+ return 0;
+ }
+
+ if( !MM_GetPhysAddr(nodetype->Write) ) {
+ Log_Error("VFS", "Node type %p(%s) write method is junk %p",
+ nodetype, nodetype->TypeName, nodetype->Write);
+ errno = EINTERNAL;
+ return -1;
+ }
+
+ // Bounds checks
+ if( h->Node->Size != (Uint64)-1 && Offset > h->Node->Size ) {
+ Log_Notice("VFS", "Write starting past EOF of FD%x (%lli > %lli)",
+ FD, Offset, h->Node->Size);
+ //errno = ESPIPE;
+ return 0;
+ }
+ if( Offset + Length > h->Node->Size )
+ {
+ // Going OOB
+ if( !nodetype->Truncate )
+ {
+ LOG("No .Truncate method, emiting write past EOF");
+ }
+ else if( nodetype->Flags & VFS_NODETYPEFLAG_NOAUTOEXPAND )
+ {
+ LOG("NOAUTOEXPAND set, truncating length from %i to %i",
+ Length, h->Node->Size - Offset);
+ Length = h->Node->Size - Offset;
+ }
+ else if( nodetype->Truncate(h->Node, Offset + Length) != Offset + Length )
+ {
+ // oh... fail? Truncate to current size
+ LOG(".Truncate failed, truncating length from %i to %i",
+ Length, h->Node->Size - Offset);
+ Length = h->Node->Size - Offset;
+ }
+ else
+ {
+ // Expansion, node size should now fit
+ LOG("Expanded file");
+ }
+ }
+
+ // Create flag set
+ Uint flags = 0;
+ flags |= (h->Mode & VFS_OPENFLAG_NONBLOCK) ? VFS_IOFLAG_NOBLOCK : 0;
+
+ // Dispatch the read!
+ size_t ret = nodetype->Write(h->Node, Offset, Length, Buffer, flags);
+ if(ret == (size_t)-1) return -1;
+ if(ret != Length) LOG("%i/%i written", ret, Length);