Hi trev,
Thank you for your reply. I didn't show the code beacuse it is a little bit complicated, but finally at the end it works like simple examples that can be found on the forum:
https://forum.lazarus.freepascal.org/index.php?topic=30135.0https://forum.lazarus.freepascal.org/index.php?topic=43489.0For one way communication you need:
- for server site set:
IPCServer.ServerID:='some_id';
IPCServer.Global:=true;
IPCServer.OnMessage:=@ProcessMessageFromRemote;
IPCServer.StartServer;
and run in some loop:
IPCServer.PeekMessage(PeekingTimeout, true);
- for client site set:
IPCClient.ServerID:='some_id';
if IPCClient.ServerRunning then
IPCClient.Active:=true;
and run:
IPCClient.SendMessage('some_string');
(in my code messages contain streams with packed records)
The issue is not in the code because when both sites are started by the same user the communication works well without issues. Also TSimpleIPCClient and TSimpleIPCServer have no properties or methods that potentially can change someting here.
Socked ports you mentioned is something related to TCP and UDP networking, but has nothing to do with SimpleIPC as this is based on different mechanism described below.
To replicate the issue you can simply compile the example from the second link and test. When you run client and server by the same user the communication will work well. When you run one of the two, client as regular user and server as root (with sodo), the communication will fail.
What I found until now:
1. TSimpleIPCClient and TSimpleIPCServer are based on named pipes. Named pipes are special kind of files (marked by the letter p) used in interprocess communication. These files follow FIFO behavour. They can be created manually with
mkfifo command.
2. When TSimpleIPCServer server is running (Active=true), the FIFO file is created. The location and permissions of the named pipe file depend of the processes owner:
- when both processes are started by the root the named pipe location is:
/private/tmp/<ServerID>. The owner is root, the group is wheel, and the permissions are (probably applied according to users umask excluding execution):
prw-r--r--- when both processes are started by the regular (standard or admin) user, the named pipe location is:
/private/var/folders/xx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/T/<ServerID>. The owner is the user that run the processes, the group is staff, and the permissions are the same:
prw-r--r--3. To find the named pipes you can use
lsof -p <PROCESS PID> command. It will show all files opened by the process, including FIFO files used by named pipes.
So to fix the issue the process started by root need to be some way forced to create its named pipes FIFO files in the the same location as regular users and with permissions that allow others access the files. This is exactly the functionality of the
mkfifo command where you provide permisions (mode) and file path.
Also in my opinion SimpleIPC limitation to single user significantly narrows the scope of applications...
Any idea how to fix this issue?
Best regards,
Inferno