Re: How to do IPC using Unix Domain Socket?

2019-10-10 Thread Hossain Adnan via Digitalmars-d-learn

On Thursday, 10 October 2019 at 12:30:25 UTC, Hossain Adnan wrote:

Here I have a program that wants to

1. detect whether if it's the only instance
1.1. it does that by trying to create a Unix Domain Socket
and trying to binding it to a specific address.

2. if a duplicate program is not running, establish an UDS
and then listen to the socket.

2.1. if any message comes through that socket, the program 
will log the incoming message
2.2. otherwise it should keep listening to the socket 
forever


3. if there's a duplicate program it should send a message and 
then exit.


Here's what I have:

import std.socket, std.experimental.logger;

immutable string socketAddress = "\0/tmp/com.localserver.myapp";

void main()
{
	auto socket = new 
std.socket.Socket(std.socket.AddressFamily.UNIX,

std.socket.SocketType.STREAM);
auto addr = new std.socket.UnixAddress(socketAddress);

auto isUnique = () {
bool result;

scope (success)
log("returns: ", result);

try
{
socket.bind(addr);
result = true;
}
catch (std.socket.SocketOSException e)
result = false;

// else throw error
return result;
}();

if (isUnique)
{
log("Unique instance detected. Listening...");
// works upto now
char[] buffer = [];
while (1)
{
socket.listen(0);
socket.receive(buffer);
if (buffer != []) {
log("Received message: ", buffer);
}
buffer = [];
}
}
else
{
log("Duplicate instance detected.");
socket.connect(addr);
import std.stdio;
stdout.write("Enter your message:\t");
socket.send(readln());
log("Message has been sent. Exiting.");
}
}


The documentation does not seem very friendly to those who does 
not have any experience in socket programming.


Consulted stackoverflow and came up with this:

import std.socket, std.experimental.logger;

class UDSIPC
{
private:
	static immutable string socketAddress = 
"\0/tmp/com.localserver.myapp";

static immutable size_t messageBufferSize = 64;
	static immutable string socketAddressName = 
"\0/tmp/com.localserver.myapp";

Socket socket;
UnixAddress uaddr;

public:
this(in string socketAddressName = socketAddressName)
{
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
uaddr = new UnixAddress(socketAddress);
}

bool getUniqueness()
{
bool result;

scope (success)
log("returns: ", result);

try
{
socket.bind(uaddr);
result = true;
}
catch (SocketOSException e)
result = false;

// else throw error
return result;
}

string getMessage()
{
socket.listen(0);
auto receiverSocket = socket.accept();
char[messageBufferSize] buffer;
auto amount = receiverSocket.receive(buffer);
import std.string;
return format!"%s"(buffer[0 .. amount]);
}

void sendMessage(in string message)
{
socket.connect(uaddr);
socket.send(message);
}

}

void main()
{
auto ipc = new UDSIPC();

if (ipc.getUniqueness())
{
while (true)
{
log(ipc.getMessage());
}
}
else
{
import std.stdio, std.string;
ipc.sendMessage(readln().chomp());
}
}



Re: How to do IPC using Unix Domain Socket?

2019-10-10 Thread Hossain Adnan via Digitalmars-d-learn

On Thursday, 10 October 2019 at 12:30:25 UTC, Hossain Adnan wrote:

Here I have a program that wants to

1. detect whether if it's the only instance
1.1. it does that by trying to create a Unix Domain Socket
and trying to binding it to a specific address.

[...]


If it helps explaining better, similar rust code is here:
https://gitlab.com/snippets/1893594


How to do IPC using Unix Domain Socket?

2019-10-10 Thread Hossain Adnan via Digitalmars-d-learn

Here I have a program that wants to

1. detect whether if it's the only instance
1.1. it does that by trying to create a Unix Domain Socket
and trying to binding it to a specific address.

2. if a duplicate program is not running, establish an UDS
and then listen to the socket.

2.1. if any message comes through that socket, the program 
will log the incoming message

2.2. otherwise it should keep listening to the socket forever

3. if there's a duplicate program it should send a message and 
then exit.


Here's what I have:

import std.socket, std.experimental.logger;

immutable string socketAddress = "\0/tmp/com.localserver.myapp";

void main()
{
	auto socket = new 
std.socket.Socket(std.socket.AddressFamily.UNIX,

std.socket.SocketType.STREAM);
auto addr = new std.socket.UnixAddress(socketAddress);

auto isUnique = () {
bool result;

scope (success)
log("returns: ", result);

try
{
socket.bind(addr);
result = true;
}
catch (std.socket.SocketOSException e)
result = false;

// else throw error
return result;
}();

if (isUnique)
{
log("Unique instance detected. Listening...");
// works upto now
char[] buffer = [];
while (1)
{
socket.listen(0);
socket.receive(buffer);
if (buffer != []) {
log("Received message: ", buffer);
}
buffer = [];
}
}
else
{
log("Duplicate instance detected.");
socket.connect(addr);
import std.stdio;
stdout.write("Enter your message:\t");
socket.send(readln());
log("Message has been sent. Exiting.");
}
}


The documentation does not seem very friendly to those who does 
not have any experience in socket programming.




Re: How to use Dbus to detect application uniqueness in D?

2019-09-28 Thread Hossain Adnan via Digitalmars-d-learn

On Saturday, 28 September 2019 at 13:37:12 UTC, Kagamin wrote:

https://ddbus.dpldocs.info/ddbus.bus.requestName.html


It requires a Connection type which I cannot find in the API.


Re: Packaging and Distributing Dlang Applications with GtkD Dependency?

2019-09-27 Thread Hossain Adnan via Digitalmars-d-learn
On Wednesday, 25 September 2019 at 11:46:04 UTC, Ron Tarrant 
wrote:

Hi y'all,

I've been Googling how to do this, but coming up with nothing 
definitive. Are there any articles for how to do this for:



Linux?


For Linux there are 3 new options:

1. Appimages (https://appimage.org/): This is very similar to 
Window's msi installer. You can host the app installer binary in 
bintray or in your website.


2. Flatpaks (https://flatpak.org/): Flatpak is quickly becoming 
more and more popular as it provides higher level customization 
for desktop applications in Linux. The flatpak API is not trivial 
but there are tutorials available to use flatpak and meson. A 
well known Linux application named Tilix 
(https://github.com/gnunn1/tilix) has a flatpak repo 
(https://github.com/gnunn1/tilix/tree/master/experimental/flatpak).


3. Snap (https://snapcraft.io/): Backed by Cannonical, snap 
provides a really easy way to distribute applications in Linux. I 
personally think Snaps are easier to create although I haven't 
invested time in distributing an app using snap. DMD, Dub and LDC 
are also shipped with it.


There are tutorials for using all of those three online, but not 
specific to Dlang. But if you use the Meson build system there 
are plenty of tutorials available.








How to use Dbus to detect application uniqueness in D?

2019-09-27 Thread Hossain Adnan via Digitalmars-d-learn
Hi I need to detect application uniqueness using dbus. I have a 
working code in Rust:


fn run_as_unique_instance() {
println!("First instance detected. Doing work...");
loop {}
}

fn run_as_nonunique_instance() {
println!("Another instance is already running. Quiting...");
std::process::exit(0);
}

fn main() {
let session =
dbus::blocking::Connection::new_session().expect("Cannot 
setup a new dbus session");


match session.request_name("com.localserver.app.bus", false, 
false, false) {

Ok(dbus::blocking::stdintf::org_freedesktop_dbus::RequestNameReply::PrimaryOwner) => {

run_as_unique_instance()
}
Ok(_) => run_as_nonunique_instance(), // 
RequestNameReply::InQueue

Err(_) => panic!("Error in session name request."),
}
}


This creates a new session in dbus and then requests name. If the 
response is "PrimaryOwner" it means the application is unique. 
However I can't find the similar symbols in ddbus.


https://ddbus.dpldocs.info/search-results.html#!session
https://ddbus.dpldocs.info/search-results.html#!Connection

Returns nothing.