Re: How to get an IP address from network interfaces
On Friday, 22 April 2022 at 05:28:52 UTC, dangbinghoo wrote: On Thursday, 21 April 2022 at 07:38:04 UTC, Alexander Zhirov wrote: [...] ```d struct ifreq { private union ifr_ifrn_ { char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */ } ifr_ifrn_ ifr_ifrn; [...] it's actually POSIX C API binding for D. you should get similar code in C when searching StackOverflow. the only thing to do this is just to look at /usr/include/dlang for POSIX API already complete binding from the official. if something is missing, you just do-it-yourself in your code.
Re: How to get an IP address from network interfaces
On Thursday, 21 April 2022 at 07:38:04 UTC, Alexander Zhirov wrote: On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote: On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov wrote: I want to get the IP address of the network interface. There is both a wireless interface and a wired one. Is it possible, knowing the name of the network interface, to get its IP address? ```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, ) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, ) < 0) { nIP = 0; } else { nIP = *cast(uint*)(_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*))).idup; } } ``` Gives a lot of errors when compiling ```d app.d(19): Error: function `std.stdio.makeGlobal!"core.stdc.stdio.stderr".makeGlobal` at /usr/include/dlang/dmd/std/stdio.d(5198) conflicts with variable `core.stdc.stdio.stderr` at /usr/include/dlang/dmd/core/stdc/stdio.d(927) app.d(19): Error: function `core.stdc.stdio.fprintf(shared(_IO_FILE)* stream, scope const(char*) format, scope const ...)` is not callable using argument types `(void, string, int)` app.d(19):cannot pass argument `makeGlobal(StdFileHandle _iob)()` of type `void` to parameter `shared(_IO_FILE)* stream` app.d(23): Error: undefined identifier `ifreq` app.d(26): Error: undefined identifier `string` in package `std` app.d(39): Error: undefined identifier `macaddr` app.d(48): Error: undefined identifier `fromStringz` ``` ```d struct ifreq { private union ifr_ifrn_ { char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */ } ifr_ifrn_ ifr_ifrn; private union ifr_ifru_ { sockaddr ifru_addr; sockaddr ifru_dstaddr; sockaddr ifru_broadaddr; sockaddr ifru_netmask; sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; ifmap ifru_map; byte[IFNAMSIZ] ifru_slave; /* Just fits the size */ byte[IFNAMSIZ] ifru_newname; byte * ifru_data; } ifr_ifru_ ifr_ifru; // NOTE: alias will not work : alias ifr_ifrn.ifrn_name ifr_name; @property ref ifr_name() { return ifr_ifrn.ifrn_name; } /* interface name */ @property ref ifr_hwaddr() { return ifr_ifru.ifru_hwaddr; } /* MAC address */ @property ref ifr_addr() { return ifr_ifru.ifru_addr; } /* address */ @property ref ifr_dstaddr() { return ifr_ifru.ifru_dstaddr; } /* other end of p-p lnk */ @property ref ifr_broadaddr() { return ifr_ifru.ifru_broadaddr; } /* broadcast address */ @property ref ifr_netmask() { return ifr_ifru.ifru_netmask; } /* interface net mask */ @property ref ifr_flags() { return ifr_ifru.ifru_flags; } /* flags */ @property ref ifr_metric() { return ifr_ifru.ifru_ivalue; } /* metric */ @property ref ifr_mtu() { return ifr_ifru.ifru_mtu; } /* mtu */ @property ref ifr_map() { return ifr_ifru.ifru_map; } /* device map */ @property ref ifr_slave() { return ifr_ifru.ifru_slave; } /* slave device */ @property ref ifr_data() { return ifr_ifru.ifru_data; } /* for use by interface */ @property ref ifr_ifindex() { return ifr_ifru.ifru_ivalue; } /* interface index */ @property ref ifr_bandwidth() { return ifr_ifru.ifru_ivalue; } /* link bandwidth */ @property ref ifr_qlen() { return ifr_ifru.ifru_ivalue; } /* queue length */ @property ref ifr_newname() { return ifr_ifru.ifru_newname; } /* New name */ } ```
Re: Infinite fibonacci sequence, lazy take first 42 values
On Thursday, 21 April 2022 at 04:36:13 UTC, Salih Dincer wrote: My favorite is the struct range. Because it is more understandable and personalized. Moreover, you can limit it without using ```take()```. And it's inherently lazy, so no extra processing/calculation other than what's requested.
Re: What is the difference between a static assert and a unit test?
On 4/21/22 6:26 PM, Alain De Vos wrote: I don't know when to use a static assert and when to use a unit test ? An assert in general is something that must be true for the program to be valid. A normal assert is some runtime condition that must be true or the program will be terminated. A static assert is some compile-time condition that must be true or the compilation will be terminated. A unittest is a completely different thing -- this is testing generally a piece of your program (like a function), to ensure that given known inputs it returns known results. A unittest uses asserts to test that the results are valid. -Steve
Re: Understanding alias template parameters
On Thu, Apr 21, 2022 at 09:02:47PM +, JG via Digitalmars-d-learn wrote: > Hi, > > Could someone possibly help me to understand why the commented line > doesn't compile? > > > ```d > import std; > > struct MapResult(R,F) > { > R r; > const F f; > auto empty() { return r.empty; } > auto front() { return f(r.front); } > void popFront() { r.popFront; } > auto save() { return typeof(this)(r.save,f); } > } > > auto myMap(alias f, R)(R r) { > return MapResult!(R,typeof(f))(r,f); > } > > > void main() > { >int function(int) f = x=>2*x; >iota(10).myMap!f.writeln; >//iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this compile? > > } > ``` Check the compiler's error message carefully: /tmp/test.d(6): Error: variable `test.MapResult!(Result, void).MapResult.f` variables cannot be of type `void` ^^^ The error comes from line 6, which is: >const F f; A lambda literal like `x=>2*x` is a template, so you cannot store it in a variable. You need to either explicitly wrap it in a delegate, or forward the alias to your struct as a template parameter, e.g.: struct MapResult(alias f, R) { ... // remove the line `const F f;` } auto myMap(alias f, R)(R r) { return MapResult!(f, R)(r); } T -- Truth, Sir, is a cow which will give [skeptics] no more milk, and so they are gone to milk the bull. -- Sam. Johnson
Re: Understanding alias template parameters
On Thursday, 21 April 2022 at 21:38:14 UTC, Ali Çehreli wrote: ```d auto myMap(alias f, R)(R r) { pragma(msg, typeof(f)); return MapResult!(R, f)(r); } ``` It looks delicious when the convenience function works magic with Voldemort: ```d import std.range, std.stdio; auto myMap(alias f, R)(R r) { struct Map { auto empty() { return r.empty; } auto front() { return f(r.front); } void popFront() { r.popFront; } } return Map(); } void main() { // with convenience function: alias func = (int x) => 2 * x; auto range = 1.iota(11); range.myMap!func.writeln; range.myMap!(x => 2 * x).writeln; // with only struct: struct MapResult(alias range, alias f) { auto empty() { return range.empty; } auto front() { return f(range.front); } void popFront() { range.popFront; } } MapResult!(range, func) mp; foreach(result; mp) result.writeln; } /* OUTPUT: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 2 4 6 8 10 12 14 16 18 20 */ ``` SDB@79
Re: What is the difference between a static assert and a unit test?
On Thursday, 21 April 2022 at 22:26:57 UTC, Alain De Vos wrote: I don't know when to use a static assert and when to use a unit test ? There is `assert()`, `static assert()` and `unittest`. `static assert()` is used while compiling, to find errors or circumstances that can lead to errors in runtime or just show type incompatibilities. `assert()` is used at runtime to allow some checks before processing data. It is evaluated at runtime and removed from code in release mode. Except `assert(0)` which will always emit an `AssertError` and will be never removed. `unittest` is a just block that will be only compiled/executed when the `-unittest` switch will be applied to compiler command line. That's it.
What is the difference between a static assert and a unit test?
I don't know when to use a static assert and when to use a unit test ?
Re: Understanding alias template parameters
On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote: Hi, Could someone possibly help me to understand why the commented line doesn't compile? ```d import std; struct MapResult(R,F) { R r; const F f; auto empty() { return r.empty; } auto front() { return f(r.front); } void popFront() { r.popFront; } auto save() { return typeof(this)(r.save,f); } } auto myMap(alias f, R)(R r) { return MapResult!(R,typeof(f))(r,f); } void main() { int function(int) f = x=>2*x; iota(10).myMap!f.writeln; //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this compile? } ``` When you write a lambda without type annotations, like `x => 2*x`, the compiler interprets it as a function template. So in this case, it's the same as if you'd written ```d T func(T)(T x) { return 2*x; } iota(10).myMap!func.writeln; ``` The problem is, you can't store a template in a variable: ```d auto f = func; // doesn't work - func does not have a value ``` So, when you try to create a `MapResult` with the template `x => 2*x` as one of its member variables, it doesn't work. By the way, you may have noticed that the error message you got says something about variables of type `void` not being allowed. That's because of [a long-standing bug][1] that causes `typeof` returns `void` when applied to a template. However, that bug is not the cause of the error here--even if it were fixed, your code still would not work. [1]: https://issues.dlang.org/show_bug.cgi?id=7947
Re: Understanding alias template parameters
On 4/21/22 14:02, JG wrote: > Could someone possibly help me to understand why the commented line > doesn't compile? iota(10).myMap!(x=>2*x).writeln; It is because x=>2*x is just a template. I don't know why the compiler chooses 'void' for typeof(f) but apparently that's how it represents the types of function templates. One way of changing the code is to use the following but it does not really fit because of course you may want types other than 'int': (int x) => 2 * x // Now the type is known The more logical thing to do is to stay with alias template parameters for MapResult as well. I am not sure why you need the member 'f' so I commented it out but now it compiles after some trivial changes: import std; struct MapResult(R, alias f) // <== HERE { R r; // const F f; auto empty() { return r.empty; } auto front() { return f(r.front); } void popFront() { r.popFront; } auto save() { return typeof(this)(r.save); } } auto myMap(alias f, R)(R r) { pragma(msg, typeof(f)); return MapResult!(R, f)(r); } void main() { int function(int) f = x=>2*x; iota(10).myMap!f.writeln; iota(10).myMap!(x=>2*x).writeln; } Ali
Understanding alias template parameters
Hi, Could someone possibly help me to understand why the commented line doesn't compile? ```d import std; struct MapResult(R,F) { R r; const F f; auto empty() { return r.empty; } auto front() { return f(r.front); } void popFront() { r.popFront; } auto save() { return typeof(this)(r.save,f); } } auto myMap(alias f, R)(R r) { return MapResult!(R,typeof(f))(r,f); } void main() { int function(int) f = x=>2*x; iota(10).myMap!f.writeln; //iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this compile? } ``` (I do know that Phobos's map works differently with better performance).
Re: How to use Vector Extensions in an opBinary
On Sunday, 17 April 2022 at 11:16:25 UTC, HuskyNator wrote: As a small disclaimer; I don't know to what extent the compiler already automates these kind of operations, and mostly want to use this as a learning experience. For your particular case, it is very likely LDC and GDC will be able to optimize your loops using SIMD.
Re: How to use Vector Extensions in an opBinary
On Thursday, 21 April 2022 at 15:31:04 UTC, HuskyNator wrote: On Sunday, 17 April 2022 at 17:04:57 UTC, Bastiaan Veelo wrote: You might want to have a look at https://code.dlang.org/packages/intel-intrinsics — Bastiaan. This does not discuss core.simd or __vector type, or did I miss/mininterpret something? It wraps `core.simd` with an eye on portability. I haven’t used it myself, but my impression is that if you’re interested in `core.simd`, intel-intrinsics may be a better option. I think there is also better documentation. There is a video of a DConf presentation that you may want to watch. — Bastiaan.
Re: dub import local D package
On Thursday, 21 April 2022 at 03:59:26 UTC, Steven Schveighoffer wrote: OK, so reviewing with that in mind, it looks like you're trying to import `myPackage.modules.mymodule`, but the file `../myPackageName/source/myPackageName/modules/mymodule.d` doesn't exist. Is there one too many "myPackageName" packages here? Yes, looks like that it works if I change to `import modules.mymodule;`.
Re: Cannot always deduce template arguments when using implicitly cast array literals
On Friday, 23 July 2021 at 13:53:27 UTC, Rekel wrote: As one can see, implicitly casting array literals in templates works fine in the case of bar, as does explicit use of templates in the case of foo, but for some reason foo does not manage to deduce its arguments like bar does. Interestingly enough, I ran into the same issue recently, but with a much simpler piece of code: ```d module app; import std.stdio; struct One(T, uint L) { T[L] array; bool opEquals(T2)(const T2[L] rhs) const { return true; } } struct Two(T, uint L) { T[L][L] array; bool opEquals(T2)(const T2[L][L] rhs) const { return true; } } void foo() { auto a = One!(float, 2)([1, 2]); int[2] b = [1, 2]; writeln(a == b); // True writeln(a.array == b); // True writeln(a == [1, 2]); // True writeln(a.array == [1, 2]); // True } void bar() { auto a = Two!(float, 2)([[1, 2], [3, 4]]); int[2][2] b = [[1, 2], [3, 4]]; writeln(a == b); // True writeln(a.array == b); // True writeln(a == [[1, 2], [3, 4]]); // cannot deduce function from argument types `!()(int[][])` writeln(a.array == [[1, 2], [3, 4]]); // True } void main(){ foo(); bar(); } ``` I'd love to know if there's any plans on changing/fixing this. I haven't been able to find any mention of it apart from in this thread. Kind regards, ~ HN (/Rekel: name change & account loss. It'd be nice if the forum supported editing & profiles (including posts/comments or at least login credential retrieval (like https://code.dlang.org/ does))
Re: How to use Vector Extensions in an opBinary
On Sunday, 17 April 2022 at 17:04:57 UTC, Bastiaan Veelo wrote: On Sunday, 17 April 2022 at 11:16:25 UTC, HuskyNator wrote: I recently found out there is [support for vector extensions](https://dlang.org/spec/simd.html) But I have found I don't really understand how to use it, not even mentioning the more complex stuff. I couldn't find any good examples either. You might want to have a look at https://code.dlang.org/packages/intel-intrinsics — Bastiaan. This does not discuss core.simd or __vector type, or did I miss/mininterpret something?
Re: Infinite fibonacci sequence, lazy take first 42 values
On Thu, Apr 21, 2022 at 02:11:03AM +, Alain De Vos via Digitalmars-d-learn wrote: > Following java program creates an infinite fibonacci sequence (stream) > an takes the first 42 values of it. [...] > How would this program look converted to dlang ? > Maybe there are multiple solutions ? Code: --- void main() { import std; writeln(recurrence!((a,n) => a[n-1] + a[n-2])(1, 1).take(42)); } --- Output: --- [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296] --- T -- "Computer Science is no more about computers than astronomy is about telescopes." -- E.W. Dijkstra
Re: stack frame & dangling pointer weirdness
On Thu, Apr 21, 2022 at 11:25:29AM +, Alain De Vos via Digitalmars-d-learn wrote: > On Thursday, 21 April 2022 at 06:57:41 UTC, drug wrote: > > On 21.04.2022 08:49, Alain De Vos wrote: > > > Following program: > > > ``` > > > import std.stdio; > > > > > > void main() @trusted > > > { [...] > > > } > > > ``` [...] > How can i force an error to be thrown when doing something "bad" ? Use @safe instead of @trusted. T -- No! I'm not in denial!
Re: unexpected noreturn behavior
On Thursday, 21 April 2022 at 12:54:12 UTC, Dennis wrote: On Thursday, 21 April 2022 at 12:41:08 UTC, WebFreak001 wrote: which I think is a little bug-prone, but at least that would solve my issues. What issue do you have with it returning `true`? Presumably the problem is that if you write something like `assert(0).match!();`, you get a spew of compiler errors, on account of the fact that `match` assumes anything that satisfies `isSumType` has properties like `Types` and `get!T`.
Re: unexpected noreturn behavior
On Thursday, 21 April 2022 at 12:41:08 UTC, WebFreak001 wrote: which I think is a little bug-prone, but at least that would solve my issues. What issue do you have with it returning `true`? Note that this compiles: ```D @safe: import std.sumtype; void main() { SumType!(int, string) s = assert(0); } ```
Re: unexpected noreturn behavior
Could we add a check for this in DScanner? Otherwise I'm not sure how else we are going to find all of these instances and fix them.
Re: unexpected noreturn behavior
On Thursday, 21 April 2022 at 12:28:37 UTC, rikki cattermole wrote: noreturn is the bottom type which can implicitly convert to any type, including void. A value of type noreturn will never be produced and the compiler can optimize such code accordingly. https://dlang.org/spec/type.html#noreturn ok so I guess all the `isSomething(T)` functions must be written like this then: ```d enum isSomething(T) = !is(immutable T == immutable noreturn) && is(T : Something!Other, Other...); ``` which I think is a little bug-prone, but at least that would solve my issues.
Re: unexpected noreturn behavior
noreturn is the bottom type which can implicitly convert to any type, including void. A value of type noreturn will never be produced and the compiler can optimize such code accordingly. https://dlang.org/spec/type.html#noreturn
unexpected noreturn behavior
What would you expect for this code? ```d struct Something(Types...) {} enum isSomethingExact(T) = is(T == Something!Types, Types...); enum isSomething(T) = is(T : Something!Types, Types...); pragma(msg, isSomethingExact!noreturn); pragma(msg, isSomething!noreturn); ``` This currently outputs `false`, `true` which breaks my code because more concretely `isSumType!(typeof(someMethod()))` returns true. I can add a check for noreturn before that, but it seems a little weird that noreturn returns true for isSomething!T and functions like that in phobos.
Re: stack frame & dangling pointer weirdness
On 21.04.22 13:25, Alain De Vos wrote: How can i force an error to be thrown when doing something "bad" ? Use @safe.
Re: stack frame & dangling pointer weirdness
On Thursday, 21 April 2022 at 06:57:41 UTC, drug wrote: On 21.04.2022 08:49, Alain De Vos wrote: Following program: ``` import std.stdio; void main() @trusted { int *p=null; void myfun(){ int x=2; p= writeln(p); writeln(x); } myfun(); *p=16; writeln(p); writeln(*p); } ``` outputs : 7FFFDFAC 2 7FFFDFAC 32767 I don't understand why. Would it be possible to explain ? Like others have said `writeln` overwrites the memory. You can check it by commenting `writeln(p);` out - then you get: ```d 7FFF23725D1C 2 16 ``` No error was thrown during execution. Should an error be thrown or is this optional by the operating system ? How can i force an error to be thrown when doing something "bad" ?
Re: Infinite fibonacci sequence, lazy take first 42 values
On Thursday, 21 April 2022 at 05:00:53 UTC, Alain De Vos wrote: This example limits the maximum value returned by the fibonacci function. f(n) < limit But it does not allow to return the n-th element of a fibonacci function. You are free to use ```take():``` ```d struct FibonacciRange(long l) { /*...*/ } enum limit = long.max; void main() { FibonacciRange!limit fibs; auto fibFirst90 = fibs.take(90); auto total = fibFirst90.sum; total.writeln; // "7540113804746346428" == fib(92)-1 auto fibInfinite = recurrence!("a[n-1] + a[n-2]")(1L, 1L); assert(fibInfinite.take(92).array[$-1]-1 == total); } ``` SDB@79
Re: How to get an IP address from network interfaces
On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote: On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov wrote: I want to get the IP address of the network interface. There is both a wireless interface and a wired one. Is it possible, knowing the name of the network interface, to get its IP address? ```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, ) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, ) < 0) { nIP = 0; } else { nIP = *cast(uint*)(_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*))).idup; } } ``` Gives a lot of errors when compiling ```d app.d(19): Error: function `std.stdio.makeGlobal!"core.stdc.stdio.stderr".makeGlobal` at /usr/include/dlang/dmd/std/stdio.d(5198) conflicts with variable `core.stdc.stdio.stderr` at /usr/include/dlang/dmd/core/stdc/stdio.d(927) app.d(19): Error: function `core.stdc.stdio.fprintf(shared(_IO_FILE)* stream, scope const(char*) format, scope const ...)` is not callable using argument types `(void, string, int)` app.d(19):cannot pass argument `makeGlobal(StdFileHandle _iob)()` of type `void` to parameter `shared(_IO_FILE)* stream` app.d(23): Error: undefined identifier `ifreq` app.d(26): Error: undefined identifier `string` in package `std` app.d(39): Error: undefined identifier `macaddr` app.d(48): Error: undefined identifier `fromStringz` ```
Re: How to get an IP address from network interfaces
On Thursday, 21 April 2022 at 07:20:30 UTC, dangbinghoo wrote: On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov wrote: I want to get the IP address of the network interface. There is both a wireless interface and a wired one. Is it possible, knowing the name of the network interface, to get its IP address? ```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, ) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, ) < 0) { nIP = 0; } else { nIP = *cast(uint*)(_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*))).idup; } } ``` PS: ```d //handle binding to net/if.h struct ifmap { c_ulong mem_start; c_ulong mem_end; ushort base_addr; ubyte irq; ubyte dma; ubyte port; /* 3 bytes spare */ } struct ifreq { private union ifr_ifrn_ { char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */ } ifr_ifrn_ ifr_ifrn; private union ifr_ifru_ { sockaddr ifru_addr; sockaddr ifru_dstaddr; sockaddr ifru_broadaddr; sockaddr ifru_netmask; sockaddr ifru_hwaddr; short ifru_flags; int ifru_ivalue; int ifru_mtu; ifmap ifru_map; byte[IFNAMSIZ] ifru_slave; /* Just fits the size */ byte[IFNAMSIZ] ifru_newname; byte * ifru_data; } ifr_ifru_ ifr_ifru; // NOTE: alias will not work : alias ifr_ifrn.ifrn_name ifr_name; @property ref ifr_name() { return ifr_ifrn.ifrn_name; } /* interface name */ @property ref ifr_hwaddr() { return ifr_ifru.ifru_hwaddr; } /* MAC address */ @property ref ifr_addr() { return ifr_ifru.ifru_addr; } /* address */ @property ref ifr_dstaddr() { return ifr_ifru.ifru_dstaddr; } /* other end of p-p lnk */ @property ref ifr_broadaddr() { return ifr_ifru.ifru_broadaddr; } /* broadcast address */ @property ref ifr_netmask() { return ifr_ifru.ifru_netmask; } /* interface net mask */ @property ref ifr_flags() { return ifr_ifru.ifru_flags; } /* flags */ @property ref ifr_metric() { return ifr_ifru.ifru_ivalue; } /* metric */ @property ref ifr_mtu() { return ifr_ifru.ifru_mtu; } /* mtu */ @property ref ifr_map() { return ifr_ifru.ifru_map; } /* device map */ @property ref ifr_slave() { return ifr_ifru.ifru_slave; } /* slave device */ @property ref ifr_data() { return ifr_ifru.ifru_data; } /* for use by interface */ @property ref ifr_ifindex() { return ifr_ifru.ifru_ivalue; } /* interface index */ @property ref ifr_bandwidth() { return ifr_ifru.ifru_ivalue; } /* link bandwidth */ @property ref ifr_qlen() { return ifr_ifru.ifru_ivalue; } /* queue length */ @property ref ifr_newname() { return ifr_ifru.ifru_newname; } /* New name */ } ```
Re: How to get an IP address from network interfaces
On Thursday, 21 April 2022 at 07:04:18 UTC, Alexander Zhirov wrote: I want to get the IP address of the network interface. There is both a wireless interface and a wired one. Is it possible, knowing the name of the network interface, to get its IP address? ```d import core.sys.posix.sys.ioctl; import core.sys.posix.arpa.inet; import core.stdc.string; import core.stdc.stdio; import core.stdc.errno; import core.sys.posix.stdio; import core.sys.posix.unistd; string ip; int get(string if_name) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return -1; } ifreq ifr; uint nIP, nNetmask, nBroadIP; strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name)); try { if (ioctl(s, SIOCGIFHWADDR, ) < 0) { return -2; } } catch (Exception e) { writeln("Error operation on netif " ~ if_name); return -2; } memcpy(macaddr.ptr, cast(char *)ifr.ifr_hwaddr.sa_data.ptr, 6); if (ioctl(s, SIOCGIFADDR, ) < 0) { nIP = 0; } else { nIP = *cast(uint*)(_broadaddr.sa_data[2]); ip = fromStringz(inet_ntoa(*cast(in_addr*))).idup; } } ```
How to get an IP address from network interfaces
I want to get the IP address of the network interface. There is both a wireless interface and a wired one. Is it possible, knowing the name of the network interface, to get its IP address?
Re: stack frame & dangling pointer weirdness
On Thursday, 21 April 2022 at 05:49:12 UTC, Alain De Vos wrote: Following program: ``` import std.stdio; void main() @trusted { int *p=null; void myfun(){ int x=2; p= writeln(p); writeln(x); } myfun(); *p=16; writeln(p); writeln(*p); } ``` outputs : 7FFFDFAC 2 7FFFDFAC 32767 I don't understand why. Would it be possible to explain ? See my comment for some ELI5 of what's going on. Of course it's a bit more complicated than that, but I hope it gets the point across. ``` void main() @trusted { int *p=null; // P is null obviously void myfun(){ int x=2; p= // Sets the address of p to the address of x, which is on the stack of myfun writeln(p); // Writes the address of p writeln(x); // Writes the value of x (same as value of p) } myfun(); // We call myfun // Any memory that was in the stack of myfun is invalid here, returning to the stack of main. *p=16; // Sets the value of p to 16, but p points to the address of an invalid memory location, since x was on the stack within myfun and thus isn't valid outside of myfun writeln(p); // Writes the address of p, which is the same since the address of p was stored on the stack of main writeln(*p); // Attempts to write the value of p, which points to an "invalid" memory address, or at least it's now something completely different than it was before, considering the stack of myfun is gone, so it writes out a garbage value } ```
Re: stack frame & dangling pointer weirdness
On Thursday, 21 April 2022 at 05:49:12 UTC, Alain De Vos wrote: Following program: ``` import std.stdio; void main() @trusted { int *p=null; void myfun(){ int x=2; p= writeln(p); writeln(x); } myfun(); *p=16; writeln(p); writeln(*p); } ``` outputs : 7FFFDFAC 2 7FFFDFAC 32767 I don't understand why. Would it be possible to explain ? When you pass a pointer to writeln conceptually it gets copied, the address that is, but the memory the address points to is in no man's land because it was in an old stack frame. As such, this memory gets "overwritten" (at this point it's invalid anyway) when you call writeln, so when you dereference it you get something from the old stack of writeln rather than 16.
Re: stack frame & dangling pointer weirdness
On 21.04.22 07:49, Alain De Vos wrote: int *p=null; void myfun(){ int x=2; p= writeln(p); writeln(x); } myfun(); *p=16; writeln(p); writeln(*p); `p` is no longer valid after `myfun` returns. Dereferencing it is an error. The two `writeln` calls in `main` re-use the memory that `p` points to for their own purposes.