Re: How to do same as 'nmap' command from within a D program?
On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson wrote: I don't see any D std.* libraries that do this. Are there a Dub packages I should look at? If you really want to this in D without any external app or OS API you could just ping all possible hosts, see which respond and then use `getHostByAddr()` to find the hostname. Another more professional way is to query the ARP protocol, where you send a packet as broadcast to all interfaces in the network to find a MAC for a given IP - if any host responses with a MAC, the host is up. You have to build the packet data for yourself, there are examples on the web. The socket to use is family:INET, type:RAW and protocol:ICMP for ping or RAW for ARP or anything that isn't listed in D. As you can see, it's required to test every possible IP out (except for any other discovery protocols supported by your network/router). For this reason, any OS does this scan periodically and caches the result. On UNIX you can just directly read the file `/proc/net/arp`, no need to use nmap.
Re: map question
On Saturday, 22 January 2022 at 19:55:43 UTC, Stanislav Blinov wrote: thanks for the explanation. That really helped :-) writeln( generate!(() => dice(0.6, 1.4)).take(howManyTimes) ); [1, 1, 1, 1, 0] (or after reading Ali's response - getting rid of rnd, and using _ ) writeln( howManyTimes.iota.map!(_ => dice(0.6, 1.4)) ); [1, 0, 1, 1, 1] They produce exactly the same thing, so I guess it comes down to personal choice now.
Re: How to do same as 'nmap' command from within a D program?
On Saturday, 22 January 2022 at 22:44:31 UTC, forkit wrote: and here is how to get the ip (depending on the formatting of your output of course) // --- module test; import std; void main() { auto result = execute(["bash", "-c", "nmap -sn 192.168.11.0/24 | ack -B2 \"Philips\""]); string ip; if(canFind(result.to!string, "Host is up")) { writeln("Host is up"); string str = result.to!string.chop; ip = str[ (indexOf(str, "for Philips (") + 10)..$-4 ]; writeln(ip); } else writeln("Host not found."); } //
Re: How to do same as 'nmap' command from within a D program?
On Saturday, 22 January 2022 at 23:15:18 UTC, forkit wrote: oh.. this is better i think... ip = str[ ((lastIndexOf(str, "(")) + 1) .. lastIndexOf(str, ")") ];
Re: map question
On 1/22/22 11:32, forkit wrote: > trying to make sense of the below: The generate() solution shown by Stanislav Blinov is suitable here. > auto rnd = Random(unpredictableSeed); Somebody else mentioned this before but none of the programs we've seen so far seemed to need a special random number generator. So, the default one, which is already randomized, would suffice. Just drop the line above. > // ok - using 'e =>' makes sense > writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, > 1.4)).format!"%(%s,%)"); When there is a syntactic need for a variable but that variable is not used, the idiomatic way of naming that variable is '_': howManyTimes.iota.map!(_ => dice(0.6, 1.4)) (Note: I did not write rnd.dice.) Ali
Re: How to do same as 'nmap' command from within a D program?
On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson wrote: is this helpful: // --- module test; import std; void main() { auto result = execute(["bash", "-c", "nmap -sn 192.168.11.0/24 | ack -B2 \"Phillips\""]); if(canFind(result.to!string, "Host is up")) writeln("Host is up"); else writeln("Host not found."); } // ---
How to do same as 'nmap' command from within a D program?
I'm writing a command line program to control certain hardware devices. I can hardcode or have in a config file the IP addresses for the devices, if I know that info. If I don't? Then I run an 'nmap' command and look for the devices. But why should I, a human, have to do any work like that? Bah! I want my program to obtain this information at runtime, automatically, and "don't make me think". One thing that might make it tough is nmap must run sudo to report the desired information. (To my knowledge; I'm no networking expert.) The exact command is: sudo nmap -sn 192.168.11.0/24 |ack -B2 "Philips" The IP address is printed two lines before the name match (ack is "better than grep"). Typical nmap output is a series of chunks of text like this: Nmap scan report for 192.168.11.10 Host is up (0.00033s latency). MAC Address: 00:17:88:4D:97:4D (Philips Lighting BV) I don't see any D std.* libraries that do this. Are there a Dub packages I should look at?
Re: map question
On Saturday, 22 January 2022 at 19:32:07 UTC, forkit wrote: trying to make sense of the below: // --- module test; import std; void main() { auto rnd = Random(unpredictableSeed); int howManyTimes = 5; // ok - using 'e =>' makes sense writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, 1.4)).format!"%(%s,%)"); // ok - though using 'howManyTimes =>' doesn't make much sense?? writeln(howManyTimes.iota.map!(howManyTimes => rnd.dice(0.6, 1.4)).format!"%(%s,%)"); // NOT ok - using '5 =>' - but isn't this effectively the same as above line? //writeln(howManyTimes.iota.map!(5 => rnd.dice(0.6, 1.4)).format!"%(%s,%)"); } // --- No, it's not the same. 'Tis not really a "map question", looks more like a question about https://dlang.org/spec/expression.html#function_literals (see #10). In the second case, you're defining a lambda with single parameter named `howManyTimes`, which is not at all related to your local variable of the same name. Third case is invalid, as you're effectively trying to do this: auto func(T)(T 5) { return rnd.dice(0.6, 1.4); } Which, of course, doesn't make any sense, does it? :) Given your use case (call a function N times), I think `generate` would be more appropriate here: ```d import std.random; import std.stdio; import std.range : generate, take; void main() { auto rnd = Random(unpredictableSeed); int howManyTimes = 5; generate!(() => rnd.dice(0.6, 1.4)).take(howManyTimes).writeln; } ```
Re: forward tuple arg to local variable + dtor
On Saturday, 22 January 2022 at 19:01:09 UTC, Stanislav Blinov wrote: On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote: [...] Take by value and make a copy without forwarding: ```d import std.typecons : Tuple; import std.meta : allSatisfy; [...] Thanks, second options is what I need. (In my case forwarding is more complex because weak ptrs need lock()).
map question
trying to make sense of the below: // --- module test; import std; void main() { auto rnd = Random(unpredictableSeed); int howManyTimes = 5; // ok - using 'e =>' makes sense writeln(howManyTimes.iota.map!(e => rnd.dice(0.6, 1.4)).format!"%(%s,%)"); // ok - though using 'howManyTimes =>' doesn't make much sense?? writeln(howManyTimes.iota.map!(howManyTimes => rnd.dice(0.6, 1.4)).format!"%(%s,%)"); // NOT ok - using '5 =>' - but isn't this effectively the same as above line? //writeln(howManyTimes.iota.map!(5 => rnd.dice(0.6, 1.4)).format!"%(%s,%)"); } // ---
Re: forward tuple arg to local variable + dtor
On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote: I want implement something like this: Scratch the previous reply, 'twas a brain fart... Simply take by value, no need for extra copies at all in that case. Arguments themselves will become those copies as needed. ```d import std.meta : allSatisfy; enum bool isRcPtr(T) = is(T == RcPtr!U, U); //@safe access to data of multiple ref counted objects: public auto apply(alias fn, Args...)(Args args) if (allSatisfy!(isRcPtr, Args)) { @property auto ref elm(alias param)()@trusted{ return param.get(); } return fn(staticMap!(elm, args)); } ```
Re: Ensuring allocation isn't thread-local?
On Saturday, 22 January 2022 at 19:06:38 UTC, Adam D Ruppe wrote: No. Anything allocated with `new` is not thread local... and even if it was, you can send the pointer to other threads anyway. The only things in thread local storage are the direct values in the non-shared global variables. What they actually point to is just generally on the main heap just like anything else. Thanks for the response. Good to know.
Re: Ensuring allocation isn't thread-local?
On Saturday, 22 January 2022 at 18:55:30 UTC, Jaime wrote: A) Do I need to worry about data being / not being in thread-local storage? No. Anything allocated with `new` is not thread local... and even if it was, you can send the pointer to other threads anyway. The only things in thread local storage are the direct values in the non-shared global variables. What they actually point to is just generally on the main heap just like anything else.
Re: forward tuple arg to local variable + dtor
On Saturday, 22 January 2022 at 18:00:58 UTC, vit wrote: I want implement something like this: ... Take by value and make a copy without forwarding: ```d import std.typecons : Tuple; import std.meta : allSatisfy; enum bool isRcPtr(T) = is(T == RcPtr!U, U); //@safe access to data of multiple ref counted objects: public auto apply(alias fn, Args...)(Args args) if (allSatisfy!(isRcPtr, Args)) { Tuple!Args params = args; // borrow all @property auto ref elm(alias param)()@trusted{ return param.get(); } return fn(staticMap!(elm, args)); // staticMap over original args tuple } ``` Or make a helper function that takes by value and forward to that: ```d template apply(alias fn) { private auto impl(Args...)(Args args) { @property auto ref elm(alias param)()@trusted{ return param.get(); } return fn(staticMap!(elm, args)); } auto apply(Args...)(auto ref Args args) if (allSatisfy!(isRcPtr, Args)) { import core.lifetime : forward; return impl(forward!args); // impl takes by value - RcPtrs passed by reference will be copied } } ```
Ensuring allocation isn't thread-local?
Howdy. How do I make sure data isn't allocated thread-local, if I also want to immediately use it in a thread-local way, because, for instance, I happen to already possess its intended mutex, which was allocated before it? Is this sufficient? Also, is it even something to worry about? ```d // for classes cast(T) new shared(T)(...) // otherwise cast(T*) new shared(T)(...) ``` For example, this is the full relevant excerpt of my WIP, untested code so far: ```d private struct Message { ulong sender; Variant payload; } private struct MessageQueue { DList!Message* data; Mutex mutex; Condition enqueued; // <-- Should fire on insertion. } // A queue for each recipient thread. private shared(MessageQueue[ulong]) messageTable; private Mutex tableMutex; // <-- Protects messageTable. /* This function should only be called by a thread holding tableMutex. We don't acquire tableMutex in the function itself because maybe the caller wants to do something else with it too. */ private ref MessageQueue getQueue(ulong recipient) { auto nsMessageTable = cast(MessageTable[ulong]*) &messageTable; MessageQueue* qptr = recipient in *nsMessageTable; if (qptr is null) { auto newMutex = cast(Mutex) new shared(Mutex); qptr = &((*nsMessageTable)[recipient] = MessageQueue( /* This is the part where I instantiate stuff as shared and then immediately cast away sharing because we're already holding tableMutex. */ cast(DList!Message*) new shared(DList!Message), newMutex, cast(Condition) new shared(Condition)(newMutex) )); } return *qptr; } ``` (I know it's probably not a good idea to try to implement an alternative to std.concurrency, and I should just use std.concurrency instead, but I have a good reason, and that reason is hands-on learning.) Anyway, yeah, to reiterate: do I have the right idea here? That is: A) Do I need to worry about data being / not being in thread-local storage? B) If so, how do I make sure it's not there? Will my approach so far suffice? C) If not, what's a better way? Thanks in advance for any guidance.
Re: forward tuple arg to local variable + dtor
On Saturday, 22 January 2022 at 17:23:12 UTC, Ali Çehreli wrote: On 1/22/22 07:17, vit wrote: > Why local variable of type tuple call destructors immediately after > initialization? I don't even understand where the local variable comes from. If you want a pair of Foo objects, I would use std.typeconst.Tuple. Otherwise I would use AliasSeq as I understand it like the following: alias tup = AliasSeq!(Foo, Foo); static foreach(Type; tup) {{ Type x; writeln("check(", x.i, "): ", cast(void*)&x); }} So, to me, AliasSeq!(Foo, Foo) is just a pair of types. I instantiate an object for each type individually and use it inside. Ali I want implement something like this: ```d import std.stdio : writeln; import std.meta : AliasSeq, staticMap; import core.memory : pureMalloc, pureFree; import core.lifetime : emplace, forward; void main()@safe{ auto rc1 = RcPtr!int.make(1); //ref counted pointer long result = 0; //apply can be @safe apply!((ref int a, ref long b){ rc1 = null; //apply has copy of rc1, a is not dangling reference result = a + b; })(rc1, RcPtr!long.make(2)); assert(result == 3); } //@safe access to data of multiple ref counted objects: public auto apply(alias fn, Args...)(scope auto ref Args args){ Args params = forward!args; //copy lvalue and move rvalue args @property auto ref elm(alias param)()@trusted{ return param.get(); } return fn(staticMap!(elm, params)); } //simple implementation of ref counted pointer struct RcPtr(T){ private Payload* payload; private this(Payload* payload)@safe{ this.payload = payload; } //copy ctor public this(ref typeof(this) rhs){ this.payload = rhs.payload; if(payload) payload.count += 1; } //make data public static auto make(Args...)(auto ref Args args){ Payload* payload = ()@trusted{ return cast(Payload*)pureMalloc(Payload.sizeof); }(); emplace(payload, forward!args); return RcPtr(payload); } public ~this(){ this.opAssign(null); } //release payload void opAssign(typeof(null) nil){ if(payload){ payload.count -= 1; if(payload.count == 0){ destroy(*payload); ()@trusted{ pureFree(payload); }(); payload = null; } } } // ref T get()@system{ assert(payload); return payload.data; } private struct Payload{ int count = 1; T data; this(Args...)(auto ref Args args){ data = T(forward!args); } } } ```
Re: forward tuple arg to local variable + dtor
On 1/22/22 07:17, vit wrote: > Why local variable of type tuple call destructors immediately after > initialization? I don't even understand where the local variable comes from. If you want a pair of Foo objects, I would use std.typeconst.Tuple. Otherwise I would use AliasSeq as I understand it like the following: alias tup = AliasSeq!(Foo, Foo); static foreach(Type; tup) {{ Type x; writeln("check(", x.i, "): ", cast(void*)&x); }} So, to me, AliasSeq!(Foo, Foo) is just a pair of types. I instantiate an object for each type individually and use it inside. Ali
Re: forward tuple arg to local variable + dtor
On Saturday, 22 January 2022 at 14:23:32 UTC, Adam Ruppe wrote: You can't forward to a local variable. Local variables will be a copy of the tuple. forward only actually works if sent *directly* to another function call. There's a bunch of things in D that only work in function parameter lists and not local variables. This is one of them. Thanks, Why local variable of type tuple call destructors immediately after initialization? ```d import std.stdio : writeln; import std.meta : AliasSeq; struct Foo{ int i; this(int i){ this.i = i; writeln("ctor(", i, "): ", cast(void*)&this); } ~this(){ writeln("dtor(", i, "): ", cast(void*)&this); i *= -1; } } void main(){ { AliasSeq!(Foo, Foo) tup; static foreach(alias x; tup) writeln("check(", x.i, "): ", cast(void*)&x); //x is destructed } } ``` Print: ``` dtor(0): 7FFF30D76868 dtor(0): 7FFF30D76858 check(0): 7FFF30D76858 //dangling? check(0): 7FFF30D76868 //dangling? ```
Re: forward tuple arg to local variable + dtor
You can't forward to a local variable. Local variables will be a copy of the tuple. forward only actually works if sent *directly* to another function call. There's a bunch of things in D that only work in function parameter lists and not local variables. This is one of them.
forward tuple arg to local variable + dtor
Hello, Why is tuple variable `params` immediately destructed after its construction? Why is `check(-2)` after `dtor(2)`? Code: ```d import std.stdio : writeln; import core.lifetime : forward, move; struct Foo{ int i; this(int i){ this.i = i; writeln("ctor(", i, "): ", cast(void*)&this); } ~this(){ writeln("dtor(", i, "): ", cast(void*)&this); i *= -1; } } void seq(Args...)(auto ref Args args){ Args params = forward!args; writeln("params initialized"); alias foo = params[0]; writeln("check(", foo.i, "): ", cast(void*)&foo); } void main(){ writeln("Foo(1):"); { auto foo = Foo(1); writeln("check(", foo.i, "): ", cast(void*)&foo); } writeln("\nFoo(2):"); seq(Foo(2)); } ``` Output: ``` Foo(1): ctor(1): 7FFEBCAF0538 check(1): 7FFEBCAF0538 dtor(1): 7FFEBCAF0538 Foo(2): ctor(2): 7FFEBCAF0548 dtor(2): 7FFEBCAF04F0 params initialized check(-2): 7FFEBCAF04F0 dtor(0): 7FFEBCAF0558 ```
Is anyone planning to participate in Google HashCode 2022?
Hello, I'm just trying to see if it's maybe possible to find some teammates here for https://codingcompetitions.withgoogle.com/hashcode ? That said, I have never participated in HashCode before and I'm not exactly committed yet. So I may abandon this idea if it doesn't work out and/or nobody is interested. I have also posted a comment on codeforces: https://codeforces.com/blog/entry/98986?#comment-880127
Re: automate tuple creation
On Saturday, 22 January 2022 at 01:33:16 UTC, Steven Schveighoffer wrote: That second `valuesPerRecord` is not used in the lambda, and also it's not referring to the original element, it's the name of a parameter in the lambda. Are you sure this is doing what you want? -Steve It just worked, so i didn't think about it too much.. but it seems to work either way. And to be honest, the only part of it I understand, is the dice part ;-) In any case I changed it: from: valuesPerRecord => to: i => // void CreateDataFile(const(int) recordsNeeded, const(int) valuesPerRecord, const(string) fname) { auto rnd = Random(unpredictableSeed); auto file = File(fname, "w"); scope(exit) file.close; Appender!string bigString = appender!string; bigString.reserve(recordsNeeded); const int iotaStartNum = 100_000_001; foreach(i, id; iota(iotaStartNum, iotaStartNum + recordsNeeded).enumerate) { bigString ~= id.to!string ~ "," ~ valuesPerRecord.iota.map!(i => rnd.dice(0.6, 1.4)).format!"%(%s,%)" ~ "\n"; } file.write(bigString[]); } // ---