1 /*******************************************************************************
2 
3     Contains the Unix Socket class.
4 
5     Copyright:
6         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
7         All rights reserved.
8 
9     License:
10         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
11         Alternatively, this file may be distributed under the terms of the Tango
12         3-Clause BSD License (see LICENSE_BSD.txt for details).
13 
14 *******************************************************************************/
15 
16 module ocean.sys.socket.UnixSocket;
17 
18 import ocean.core.Enforce;
19 import ocean.meta.types.Qualifiers;
20 import ocean.stdc.posix.sys.socket;
21 import ocean.stdc.posix.sys.un;
22 import ocean.sys.socket.model.ISocket;
23 import ocean.text.convert.Formatter;
24 
25 import core.sys.posix.unistd;
26 
27 
28 /*******************************************************************************
29 
30     Unix Socket class.
31 
32 *******************************************************************************/
33 
34 public class UnixSocket : ISocket
35 {
36     import ocean.sys.CloseOnExec;
37 
38     /***************************************************************************
39 
40         Path to the unix domain socket.
41 
42     ***************************************************************************/
43 
44     private char[UNIX_PATH_MAX] path;
45 
46 
47     /***************************************************************************
48 
49         Number of valid characters in path.
50 
51     ***************************************************************************/
52 
53     private size_t path_len = 0;
54 
55 
56     /***************************************************************************
57 
58         Constructor.
59 
60     ***************************************************************************/
61 
62     public this ()
63     {
64         super(sockaddr_un.sizeof);
65     }
66 
67 
68     /***************************************************************************
69 
70         Creates a socket endpoint for communication and sets this.fd to the
71         corresponding file descriptor.
72 
73         Params:
74             type = desired socket type, which specifies the communication
75                    semantics. Defaults to SOCK_STREAM.
76 
77                    For Unix Sockets the valid types are:
78 
79                      - SOCK_STREAM, for a stream-oriented socket.
80 
81                      - SOCK_DGRAM, for a datagram-oriented socket that preserves
82                        message boundaries (as on most UNIX implemen‐tations,
83                        UNIX domain datagram sockets are always reliable and don't
84                        reorder datagrams).
85 
86                      - SOCK_SEQPACKET (since Linux 2.6.4), for a connection-oriented
87                        socket that preserves message boundaries and delivers messages
88                        in the order that they were sent.
89 
90         Returns:
91             The socket descriptor or -1 on error.
92             See the ISocket socket() implementation for details.
93 
94     ***************************************************************************/
95 
96     public int socket ( int type = SOCK_STREAM )
97     {
98         return super.socket(
99             AF_UNIX, setCloExec(type, SocketFlags.SOCK_CLOEXEC), 0
100         );
101     }
102 
103 
104     /***************************************************************************
105 
106         Assigns a local address to this socket.
107         socket() must have been called previously.
108 
109         address = The LocalAddress instance to use. Must be non-null.
110 
111         Returns:
112             0 on success or -1 on failure.
113             On failure errno is set appropriately.
114             See the ISocket bind() implementation for details.
115 
116     ***************************************************************************/
117 
118     public int bind ( sockaddr_un* address )
119     {
120         auto path = address.sun_path;
121         this.path_len = path.length;
122         this.path[0 .. this.path_len] = path;
123 
124         // note: cast due to that bind accepts generic `sockaddr*` pointer`
125         return super.bind(cast(sockaddr*)address);
126     }
127 
128     /***************************************************************************
129 
130         Connects this socket the specified address and port.
131         socket() must have been called previously.
132 
133         address = The LocalAddress instance to use. Must be non-null.
134 
135     ***************************************************************************/
136 
137     public int connect ( sockaddr_un* address )
138     {
139         auto path = address.sun_path;
140         this.path_len = path.length;
141         this.path[0 .. this.path_len] = path;
142 
143         // note: cast due to that connect accepts generic `sockaddr*` pointer`
144         return super.connect(cast(sockaddr*)address);
145     }
146 
147     /**************************************************************************
148 
149         Formats information about the socket into the provided buffer.
150 
151         Params:
152             buf      = buffer to format into
153             io_error = true if an I/O error has been reported
154 
155      **************************************************************************/
156 
157     override public void formatInfo ( ref char[] buf, bool io_error )
158     {
159         sformat(buf, "fd={}, unix_path={}, ioerr={}",
160             this.fileHandle, this.path[0 .. this.path_len], io_error);
161     }
162 }