Here is the solution I end up using. This is based on a solution suggested by Julius Kavay :

set cmd="netstat -anp TCP"
set oldIO = $io
open cmd:"QR":10
use cmd
// in case, $zeof is not set per default
// set old=$system.Process.SetZEOF(1)  
for {
  read line  //timeout alternative, no need of $zeof: read line:1 
  quit:$zeof
  ... //do something with line
}
close cmd
use:oldIO]"" oldIO
// d $system.Process.SetZEOF(old)

You can find more info about it here.

As an alternative, it's also possible to use pipes ($zeof must be used as well): 

set dev="|CPIPE|"_$job   
open dev:cmd:10   
use dev
...

close dev

It's possible to change (and thus disable) concurrency of a persistent object by calling this private method (eg: in constructor) :

Method %OnNew() As %Status
{
    do ..%ConcurrencySet(0) // <--- here
    quit $$$OK
}

Disclaimer : this is an undocumented method. It might be removed from IRIS implementation in the future, use it at your own risk.

The parameter of that method accept same values as what is returned by $system.OBJ.GetConcurrencyMode().
Once is concurrency is disabled, updates from other processes to related global can occurs even within transactions (data consistency is lost). A possible workaround is to create a single lock on the global :

do ##class(Test.Test).%LockExtent()   //same as lock +^Test.TestD
//do something here 
//...
do ##class(Test.Test).%UnlockExtent() //same as lock -^Test.TestD

This prevent having many locks created during long duration transactions that create many persistent objects (but on the other side, it locks the whole global, not individual nodes).

I found the following XSD file which seems to be what I want :

C:\InterSystems\Cache\bin\cacheexport.xsd

It's much more complex than what I thought. Maybe exporting all cache files as UDL (as Dmitriy suggested) is a better approach. I don't know if SyncTool is able to export cache entities in that format directly. If not, I will need a second pass (that convert xml to udl).