Recent

Author Topic: Can't find unit unixsockets  (Read 1714 times)

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Re: Can't find unit unixsockets
« Reply #15 on: February 17, 2025, 04:51:36 pm »
I told you so, use sockets.
If by sockets, you mean unit sockets, it was pulled in for other types, but did not provide CMSG_LEN and the rest.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #16 on: February 17, 2025, 05:06:04 pm »
I don't like getting involved /but/...

I told you so, use sockets.
If by sockets, you mean unit sockets, it was pulled in for other types, but did not provide CMSG_LEN and the rest.

...and certain people who have been somewhat forward in telling you that you were doing everything wrong could instead have usefully turned their formidable intellects to answering your original question.

Macros, particularly function-like macros that take one or more parameters, are very poorly served by FPC.

However I have to ask here: what are you actually trying to do? I regularly mess around with sockets at a fairly low level (since the sort of thing I do isn't merely passing parameters to a website), but I don't immediately recognise the macros and structures you mention.

Obligatory xkcd https://xkcd.com/1481/

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 16653
  • Kallstadt seems a good place to evict Trump to.
Re: Can't find unit unixsockets
« Reply #17 on: February 17, 2025, 05:24:51 pm »
Mark, the structures are elsewhere in the basic unix units, but may have slightly different names. After all these structures are needed for sockets.
I maintain what I stated and I still haven't seen anything that warrants NOT to mark that unit as deprecated.
But I am sure they don't want the Trumps back...

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #18 on: February 17, 2025, 05:40:44 pm »
Mark, the structures are elsewhere in the basic unix units, but may have slightly different names. After all these structures are needed for sockets.
I maintain what I stated and I still haven't seen anything that warrants NOT to mark that unit as deprecated.

Come on, you don't weasel out of it that easily.

WHERE ARE THEY?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Alexx2000

  • New Member
  • *
  • Posts: 14
Re: Can't find unit unixsockets
« Reply #19 on: February 17, 2025, 07:22:08 pm »
It should be broken, must be broken otherwise and marked as deprecated

The libc unit are deprecated, unixsockets are not deprecated. But it has bugs which we discussed above.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #20 on: February 17, 2025, 07:42:29 pm »
It should be broken, must be broken otherwise and marked as deprecated

The libc unit are deprecated, unixsockets are not deprecated. But it has bugs which we discussed above.

As would be apparent to anybody who took the trouble to read the thread.

In practice, I'm fairly sure that fpSend() (for connected sockets, i.e. TCP) or fpSendTo() (for unconnected sockets, i.e. UDP) would do the trick. Having said that, and emphasising that OP hasn't told us what he's actually trying to do, I do have to say that there's areas in which the network stack (as implemented in FPC's RTL) hasn't had as much love as it deserves: things like SCTP support and a few of the more obscure ways of interacting with Pascal's Input/Output devices come to mind.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Re: Can't find unit unixsockets
« Reply #21 on: February 17, 2025, 10:29:18 pm »
Macros, particularly function-like macros that take one or more parameters, are very poorly served by FPC.
They were there, although as functions. But that too works for me.
However I have to ask here: what are you actually trying to do?
I was porting a C unit which transmits/receives live socket descriptors through datagram sockets. (To be able to pass an opened socket to another process.)
It should be broken, must be broken otherwise and marked as deprecated

The libc unit are deprecated, unixsockets are not deprecated. But it has bugs which we discussed above.
We've already fixed the bugs, or have we? You've fixed the unit, i've fixed the includes and now both unixsockets and my unit compile.
Sure, there is no patch (yet), but all of the fixes are documented here and there are only three small changes.

Should i make a patch?

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #22 on: February 17, 2025, 11:09:15 pm »
They were there, although as functions. But that too works for me.

Yes, but functions aren't macros.

Quote
I was porting a C unit which transmits/receives live socket descriptors through datagram sockets. (To be able to pass an opened socket to another process.)

OK, fpSendTo() works fine with datagrams. For strictly local use consider unix-domain sockets rather than UDP.

Quote
Should i make a patch?

Not necessarily, but you should certainly raise a bug report for those malformed include directives (possibly referencing anything incoherent that Thaddy attempted).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Re: Can't find unit unixsockets
« Reply #23 on: February 17, 2025, 11:27:25 pm »
Yes, but functions aren't macros.
I know, but in this case they were usable as a drop-in replacement.
OK, fpSendTo() works fine with datagrams. For strictly local use consider unix-domain sockets rather than UDP.
But i did use unix domain sockets; they can be datagram ones and AFAIK to pass an FD to another process, one has to use datagram sockets. (Fixme?)
Not necessarily, but you should certainly raise a bug report for those malformed include directives (possibly referencing anything incoherent that Thaddy attempted).
Okay. Where should i do that? On SourceForge, or GitLab, or GitHub, or here in a specific zone/group?

Edit: Okay, i found, that it is GitLab.

Edit: But i cannot log in to my GitLab account, because that stupid CloudFlare botchecker does not let me in. From Chromium, it simply gives back the checkbox each time i check in and from Pale Moon it simply never gives the checkbox. Great...
« Last Edit: February 18, 2025, 12:05:24 am by TCH »

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #24 on: February 18, 2025, 09:19:00 am »
I know, but in this case they were usable as a drop-in replacement.

Yes, it's the only way to do it but there's things that quite simply can't be expressed like that.

Quote
But i did use unix domain sockets; they can be datagram ones and AFAIK to pass an FD to another process, one has to use datagram sockets. (Fixme?)

I don't entirely understand what you're doing with FDs, and it sounds- at the minimum- to be highly OS-specific (i.e. even if it works on Linux it might not work on Berkeley derivatives). But if you can do something with unix domain sockets, then I see no reason why UDP wouldn't work... until somebody tried to use it to send info between different hosts, or potentially different namespaces (i.e. containers etc.).

Quote
Okay. Where should i do that? On SourceForge, or GitLab, or GitHub, or here in a specific zone/group?

Edit: Okay, i found, that it is GitLab.

Edit: But i cannot log in to my GitLab account, because that stupid CloudFlare botchecker does not let me in. From Chromium, it simply gives back the checkbox each time i check in and from Pale Moon it simply never gives the checkbox. Great...

That one I can't help with, hopefully one of the core team will spot it.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Re: Can't find unit unixsockets
« Reply #25 on: February 18, 2025, 02:26:15 pm »
There is a process, which opens a listener socket and waits for incoming connections, then accepts them. Then it passes the socket descriptor of the just connected client to a worker process. That's all. This works on BSD-s too, actually the code i used to build the original C unit is a BSD4.3/BSD4.4 code (with separate branches for them), so it should work on all POSIX systems.
I don't entirely understand what you're doing with FDs, and it sounds- at the minimum- to be highly OS-specific (i.e. even if it works on Linux it might not work on Berkeley derivatives).
But if you can do something with unix domain sockets, then I see no reason why UDP wouldn't work... until somebody tried to use it to send info between different hosts, or potentially different namespaces (i.e. containers etc.).
UDP does work, these are UDP unix domain sockets. This is for incoming FD-s:
Code: Pascal  [Select][+][-]
  1. var
  2.         name: string
  3.         sock: cint;
  4.         sa: sockaddr_un;
  5.  
  6. ...
  7.  
  8.         name := '/tmp/my_socket';
  9.         fpunlink(name);
  10.         sock := fpsocket(PF_UNIX, SOCK_DGRAM, 0);
  11.         fillbyte(sa, sizeof(sockaddr_un), 0);
  12.         sa.sun_family := AF_UNIX;
  13.         sa.sun_path := name;
  14.         fpbind(sock, Psockaddr(@sa), sizeof(sa.sun_family) + length(name));
and this is for sending FD-s:
Code: Pascal  [Select][+][-]
  1. var
  2.         name: string;
  3.         sock: cint;
  4.         sa: sockaddr_un;
  5.  
  6. ...
  7.  
  8.         name := '/tmp/my_socket';
  9.         sock := fpsocket(PF_UNIX, SOCK_DGRAM, 0);
  10.         fillbyte(sa, sizeof(sockaddr_un), 0);
  11.         sa.sun_family := AF_UNIX;
  12.         sa.sun_path := name;
  13.         fpconnect(sock, Psockaddr(@sa), sizeof(sa.sun_family) + length(name));
These are unix domain sockets, but datagram ones. And through these, you can send or receive live descriptors.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #26 on: February 18, 2025, 03:01:23 pm »
I think I've heard of such things, but am still somewhat wary. However

UDP does work, these are UDP unix domain sockets. This is for incoming FD-s:
Code: Pascal  [Select][+][-]
  1. ...
  2.         sock := fpsocket(PF_UNIX, SOCK_DGRAM, 0);
  3. ...

I think you mean that they're /datagram/ UD sockets, UDP looks like

Code: Pascal  [Select][+][-]
  1. ...
  2. dnsClientSocketHandle := fpSocket(PF_INET, SOCK_DGRAM, 0);
  3. ...
  4.  

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Re: Can't find unit unixsockets
« Reply #27 on: February 18, 2025, 03:44:51 pm »
I was not sure. I've misinterpreted some sources and thought UDP sockets are the datagram sockets (never worked with them before), but i realized now, that UDP sockets are network datagram sockets. I used unix domain datagram sockets, not network ones, of course.

I was working with these sources (and some other snippets): passfd.c from Sampo Kellomaki (attached, inlined at the end of the post) and http://web.archive.org/web/20161002061943/http://users.cs.cf.ac.uk/Dave.Marshall/C/node28.html

However, with SOCK_STREAM, i could not pass FD-s. Then i found this source, with portlisten.c: https://www.mail-archive.com/kragen-hacks@canonical.org/msg00002.html and tried SOCK_DGRAM. And with that it worked.

passfd.c:
Code: C  [Select][+][-]
  1. /* passfd.c  -  BSD style file descriptor passing over unix domain sockets
  2.  *
  3.  * Copyright (c) 2000 Sampo Kellomaki <sampo@iki.fi>, All Rights Reserved.
  4.  * This module may be copied under the same terms as the perl itself.
  5.  *
  6.  * See also:
  7.  * recvmsg(2)
  8.  * sendmsg(2)
  9.  * Richard Stevens: Unix Network Programming, Prentice Hall, 1990; chapter 6.10
  10.  * /usr/include/socketbits.h
  11.  * /usr/include/sys/socket.h
  12.  */
  13.  
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <sys/uio.h>
  17. #include <errno.h>
  18.  
  19. /* I test here for __sun for lack of anything better, but I
  20.  * mean Solaris 2.6. The idea of undefining SCM_RIGHTS is
  21.  * to force the headers to behave BSD 4.3 way which I have
  22.  * tested to work.
  23.  *
  24.  * In general, if you have compilation errors, you might consider
  25.  * adding a test for your platform here.
  26.  */
  27. #if defined(__sun)
  28. #undef SCM_RIGHTS
  29. #endif
  30.  
  31. #ifdef SCM_RIGHTS
  32.  
  33. /* It seems various versions of glibc headers (i.e.
  34.  * /usr/include/socketbits.h) miss one or more of these */
  35.  
  36. #ifndef CMSG_DATA
  37. # define CMSG_DATA(cmsg) ((cmsg)->cmsg_data)
  38. #endif
  39.  
  40. #ifndef CMSG_NXTHDR
  41. # define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
  42. #endif
  43.  
  44. #ifndef CMSG_FIRSTHDR
  45. # define CMSG_FIRSTHDR(mhdr) \
  46.   ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr)          \
  47.    ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL)
  48. #endif
  49.  
  50. #ifndef CMSG_ALIGN
  51. # define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
  52.                          & ~(sizeof (size_t) - 1))
  53. #endif
  54.  
  55. #ifndef CMSG_SPACE
  56. # define CMSG_SPACE(len) (CMSG_ALIGN (len) \
  57.                          + CMSG_ALIGN (sizeof (struct cmsghdr)))
  58. #endif
  59.  
  60. #ifndef CMSG_LEN
  61. # define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
  62. #endif
  63.  
  64. union fdmsg {
  65.         struct cmsghdr h;
  66.         char buf[CMSG_SPACE(sizeof(int))];
  67. };
  68. #endif
  69.  
  70. /* Tested to work on perl 5.005_03
  71.  *   Linux-2.2.14 glibc-2.0.7 (libc.so.6) i586  BSD4.4
  72.  *   Linux-2.0.38 glibc-2.0.7 (libc.so.6) i586  BSD4.4
  73.  *   SunOS-5.6, gcc-2.7.2.3, Sparc BSD4.3
  74.  * see also: linux/net/unix/af_unix.c
  75.  */
  76.  
  77. int
  78. sendfd(sock_fd, send_me_fd)
  79.         int sock_fd;
  80.         int send_me_fd;
  81. {
  82.         int ret = 0;
  83.         struct iovec  iov[1];
  84.         struct msghdr msg;
  85.        
  86.         iov[0].iov_base = &ret;  /* Don't send any data. Note: der Mouse
  87.                                   * <mouse@Rodents.Montreal.QC.CA> says
  88.                                   * that might work better if at least one
  89.                                   * byte is sent. */
  90.         iov[0].iov_len  = 1;
  91.        
  92.         msg.msg_iov     = iov;
  93.         msg.msg_iovlen  = 1;
  94.         msg.msg_name    = 0;
  95.         msg.msg_namelen = 0;
  96.  
  97.         {
  98. #ifdef SCM_RIGHTS
  99.                 /* New BSD 4.4 way (ouch, why does this have to be
  100.                  * so convoluted). */
  101.  
  102.                 union  fdmsg  cmsg;
  103.                 struct cmsghdr* h;
  104.  
  105.                 msg.msg_control = cmsg.buf;
  106.                 msg.msg_controllen = sizeof(union fdmsg);
  107.                 msg.msg_flags = 0;
  108.                
  109.                 h = CMSG_FIRSTHDR(&msg);
  110.                 h->cmsg_len   = CMSG_LEN(sizeof(int));
  111.                 h->cmsg_level = SOL_SOCKET;
  112.                 h->cmsg_type  = SCM_RIGHTS;
  113.                 *((int*)CMSG_DATA(h)) = send_me_fd;
  114. #else
  115.                 /* Old BSD 4.3 way. Not tested. */
  116.                 msg.msg_accrights = &send_me_fd;
  117.                 msg.msg_accrightslen = sizeof(send_me_fd);
  118. #endif 
  119.  
  120.                 if (sendmsg(sock_fd, &msg, 0) < 0) {
  121.                         ret = 0;
  122.                 } else {
  123.                         ret = 1;
  124.                 }
  125.         }
  126.         /*fprintf(stderr,"send %d %d %d %d\n",sock_fd, send_me_fd, ret, errno);*/
  127.         return ret;
  128. }
  129.  
  130. int
  131. recvfd(sock_fd)
  132.         int sock_fd;
  133. {
  134.         int count;
  135.         int ret = 0;
  136.         struct iovec  iov[1];
  137.         struct msghdr msg;
  138.        
  139.         iov[0].iov_base = &ret;  /* don't receive any data */
  140.         iov[0].iov_len  = 1;
  141.        
  142.         msg.msg_iov = iov;
  143.         msg.msg_iovlen = 1;
  144.         msg.msg_name = NULL;
  145.         msg.msg_namelen = 0;
  146.  
  147.         {
  148. #ifdef SCM_RIGHTS
  149.                 union fdmsg  cmsg;
  150.                 struct cmsghdr* h;
  151.  
  152.                 msg.msg_control = cmsg.buf;
  153.                 msg.msg_controllen = sizeof(union fdmsg);
  154.                 msg.msg_flags = 0;
  155.                
  156.                 h = CMSG_FIRSTHDR(&msg);
  157.                 h->cmsg_len   = CMSG_LEN(sizeof(int));
  158.                 h->cmsg_level = SOL_SOCKET;  /* Linux does not set these */
  159.                 h->cmsg_type  = SCM_RIGHTS;  /* upon return */
  160.                 *((int*)CMSG_DATA(h)) = -1;
  161.                
  162.                 if ((count = recvmsg(sock_fd, &msg, 0)) < 0) {
  163.                         ret = 0;
  164.                 } else {
  165.                         h = CMSG_FIRSTHDR(&msg);   /* can realloc? */
  166.                         if (   h == NULL
  167.                             || h->cmsg_len    != CMSG_LEN(sizeof(int))
  168.                             || h->cmsg_level  != SOL_SOCKET
  169.                             || h->cmsg_type   != SCM_RIGHTS ) {
  170.                                 /* This should really never happen */
  171.                                 if (h)
  172.                                   fprintf(stderr,
  173.                                     "%s:%d: protocol failure: %d %d %d\n",
  174.                                     __FILE__, __LINE__,
  175.                                     h->cmsg_len,
  176.                                     h->cmsg_level, h->cmsg_type);
  177.                                 else
  178.                                   fprintf(stderr,
  179.                                     "%s:%d: protocol failure: NULL cmsghdr*\n",
  180.                                     __FILE__, __LINE__);
  181.                                 ret = 0;
  182.                         } else {
  183.                                 ret = *((int*)CMSG_DATA(h));
  184.                                 /*fprintf(stderr, "recv ok %d\n", ret);*/
  185.                         }
  186.                 }
  187. #else
  188.                 int receive_fd;
  189.                 msg.msg_accrights = &receive_fd;
  190.                 msg.msg_accrightslen = sizeof(receive_fd);
  191.  
  192.                 if (recvmsg(sock_fd, &msg, 0) < 0) {
  193.                         ret = 0;
  194.                 } else {
  195.                         ret = receive_fd;
  196.                 }
  197. #endif
  198.         }
  199.        
  200.         /*fprintf(stderr, "recv %d %d %d %d\n",sock_fd, ret, errno, count);*/
  201.         return ret;
  202. }
  203.  
  204. /* EOF  -  passfd.c */

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: Can't find unit unixsockets
« Reply #28 on: February 18, 2025, 04:12:38 pm »
Note that you've got PF_something (program family) and then an indication of whether something's a datagram or a stream. You've also separately got AF_something (address family).

SOCK_DGRAM usually means UDP (on PF_INET) or unix-domain sockets (on PF_UNIX), I'm not sure that SOCK_STREAM on PF_UNIX is a valid comobination.

If you're using PF_INET then you also need AF_INET to specify an IP address... minor variations in there for v6. However like a FIFO a unix-domain socket is named:

Code: Pascal  [Select][+][-]
  1. (* Return true if the parameter is blank, representing an anonymous pipe
  2.   normally set up by the shell.
  3. *)
  4. function isPipe(const name: string): boolean;
  5.  
  6. begin
  7.   result := name = ''
  8. end { isPipe } ;
  9.  
  10.  
  11. (* Return true if the parameter represents a regular file.
  12. *)
  13. function isFile(const name: string): boolean;
  14.  
  15. var
  16.   s: stat;
  17.  
  18. begin
  19.   if name = '' then
  20.     exit(false);
  21.   if fpStat(name, s{%H-}) <> 0 then
  22.     exit(false);
  23.  
  24. (* The low 9 bits of the mode are the usual permissions, the next 3 bits are  *)
  25. (* the sticky, setgid and setuid bits, leaving 4 bits to define the type of   *)
  26. (* object i.e. ordinary file, directory and so on. There might be additional  *)
  27. (* filesystem-specific attribute bits stored elsewhere, e.g. in an extension  *)
  28. (* to the inode structure.                                                    *)
  29.  
  30. // Does this need special handling for symlinks, or are they followed?
  31.  
  32.   result := ((s.st_mode and S_IFMT) = S_IFREG) or ((s.st_mode and S_IFMT) = S_IFCHR)
  33. end { isFile } ;
  34.  
  35.  
  36. (* Return true if the parameter represents a FIFO (named pipe).
  37. *)
  38. function isFifo(const name: string): boolean;
  39.  
  40. var
  41.   s: stat;
  42.  
  43. begin
  44.   if name = '' then
  45.     exit(false);
  46.   if fpStat(name, s{%H-}) <> 0 then
  47.     exit(false);
  48.  
  49. (* The low 9 bits of the mode are the usual permissions, the next 3 bits are  *)
  50. (* the sticky, setgid and setuid bits, leaving 4 bits to define the type of   *)
  51. (* object i.e. ordinary file, directory and so on. There might be additional  *)
  52. (* filesystem-specific attribute bits stored elsewhere, e.g. in an extension  *)
  53. (* to the inode structure.                                                    *)
  54.  
  55. // Does this need special handling for symlinks, or are they followed?
  56.  
  57.   result := (s.st_mode and S_IFMT) = S_IFIFO
  58. end { isFifo } ;
  59.  
  60.  
  61. (* Return true if the parameter represents a unix domain socket.
  62. *)
  63. function isUDSocket(const name: string): boolean;
  64.  
  65. var
  66.   s: stat;
  67.  
  68. begin
  69.   if name = '' then
  70.     exit(false);
  71.   if fpStat(name, s{%H-}) <> 0 then
  72.     exit(false);
  73.  
  74. (* The low 9 bits of the mode are the usual permissions, the next 3 bits are  *)
  75. (* the sticky, setgid and setuid bits, leaving 4 bits to define the type of   *)
  76. (* object i.e. ordinary file, directory and so on. There might be additional  *)
  77. (* filesystem-specific attribute bits stored elsewhere, e.g. in an extension  *)
  78. (* to the inode structure.                                                    *)
  79.  
  80. // Does this need special handling for symlinks, or are they followed?
  81.  
  82.   result := (s.st_mode and S_IFMT) = S_IFSOCK
  83. end { isUDSocket } ;
  84.  
  85.  
  86. (* Reopen something that isn't a unix-domain socket.
  87. *)
  88. procedure reopenFile(var t: Text; const n: string; alreadyClosed: boolean= false);
  89.  
  90. begin
  91.   if not alreadyClosed then
  92.     CloseFile(t);
  93.   AssignFile(t, n);
  94.   Rewrite(t)
  95. end { reopenFile } ;
  96.  
  97.  
  98. (* This is a reimplementation of the standard Connect() since it doesn't
  99.   support a unix-domain address and truncates it if told to cast it to an
  100.   inet domain address structure.
  101.  
  102.   Test using e.g.  $ nc -lkU ~/dsocket  noting the -k to prevent the listener
  103.   terminating when the writer (this program) closes the connection.
  104. *)
  105. Function Connect(Sock:longint;const addr: TUnixSockAddr;var SockIn,SockOut:text):Boolean;
  106.  
  107.  
  108.   Function DoConnect(Sock:longint;const addr: TUnixSockAddr): Boolean;
  109.  
  110.   var
  111.     res: longint;
  112.   begin
  113.     repeat
  114.       res:=fpconnect(Sock,@Addr,SizeOF(TUnixSockAddr)); (* NOTA BENE *)
  115.     until (res<>-1) or (SocketError <> EsockEINTR);
  116.     DoConnect:= res = 0;
  117.   end;
  118.  
  119.  
  120. begin
  121.   Connect:=DoConnect(Sock,addr);
  122.   If Connect then
  123.      Sock2Text(Sock,SockIn,SockOut);
  124. end { Connect } ;
  125.  
  126.  
  127. var
  128.   reopenedInput: Text;                  (* Dummy since only output is used      *)
  129.  
  130.  
  131. (* Reopen a unix-domain socket. This needs special implementation of Connect()
  132.   as above.
  133. *)
  134. procedure reopenUDSocket(var t: Text; const n: string; alreadyClosed: boolean= false);
  135.  
  136. var
  137.   skt: TSocket;
  138.   ipcAddr: TUnixSockAddr;
  139.  
  140. begin
  141.   if not alreadyClosed then
  142.     CloseFile(t);
  143.   skt:= fpSocket(PF_UNIX, SOCK_STREAM, 0);
  144.   if skt < 0 then begin
  145.     if not quiet then
  146.       WriteLn(erroutput, 'Cannot create unix-domain socket handle');
  147.     Halt(9)
  148.   end;
  149.   FillChar(ipcAddr{%H-}, SizeOf(ipcAddr), 0);
  150.   ipcAddr.family:= AF_UNIX;
  151.   StrPCopy(ipcAddr.path, n);
  152.   if not Connect(skt, ipcAddr, reopenedInput, t) then begin
  153.     if not quiet then begin
  154.       Write(erroutput, 'Cannot open unix-domain socket "' + n + '" ');
  155.       if not FileExists(n) then
  156.         WriteLn(erroutput, '(does not exist)')
  157.       else
  158.         WriteLn(erroutput, '(check listener is running)');
  159.       Halt(9)
  160.     end
  161.   end;
  162. {$push }{$I- }
  163.   Reset(reopenedInput);
  164. {$pop        }
  165.   Rewrite(t)
  166. end { reopenUDSocket } ;
  167.  

...and that you might need to remove the names from the filesystem when your program finishes, or take special precautions when it starts and finds that the name already exists.

Updated: C&P more example code so that it includes reworked Connect() etc.

MarkMLl
« Last Edit: February 19, 2025, 04:28:30 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Re: Can't find unit unixsockets
« Reply #29 on: February 18, 2025, 07:57:09 pm »
Note that you've got PF_something (program family) and then an indication of whether something's a datagram or a stream.
I think you meant protocol family.
SOCK_DGRAM usually means UDP (on PF_INET) or unix-domain sockets (on PF_UNIX), I'm not sure that SOCK_STREAM on PF_UNIX is a valid comobination.
It is not? This SO-topic says, it is:
Quote
The main difference is that one is connection based (STREAM) and the other is connection-less (DGRAM) - the difference between stream and packet oriented communication is usually much less important.

With SOCK_STREAM you still get all the connection handling, i.e. listen/accept and you can tell if a connection is closed by the other side.
Of course, he might be wrong, i am not an expert on sockets.
If you're using PF_INET then you also need AF_INET to specify an IP address...
Yep, i know, but this was IPC, not network.
...and that you might need to remove the names from the filesystem when your program finishes, or take special precautions when it starts and finds that the name already exists.
Yes, i did: i do fpunlink(name) before the fpsocket call.

Edit: Forgot to thank you for your pipe code; thanks. :)
« Last Edit: February 19, 2025, 02:58:47 am by TCH »

 

TinyPortal © 2005-2018