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