@@ -38,52 +38,19 @@ AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
3838 return fdSocket;
3939}
4040
41- static struct sockaddr * safeSockAddrPointerCast (struct sockaddr_un *addr) {
42- // Casting between types like these legacy C library interfaces require
43- // is forbidden in C++.
44- // To maintain backwards compatibility, the implementation of the
45- // bind function contains some hints to the compiler that allow for this
46- // special case.
47- return reinterpret_cast <struct sockaddr *>(addr);
48- }
49-
50- void bind (int fd, const std::string & path)
41+ static void bindConnectProcHelper (
42+ std::string_view operationName, auto && operation,
43+ int fd, const std::string & path)
5144{
52- unlink (path.c_str ());
53-
5445 struct sockaddr_un addr;
5546 addr.sun_family = AF_UNIX;
56- auto psaddr {safeSockAddrPointerCast (&addr)};
57-
58- if (path.size () + 1 >= sizeof (addr.sun_path )) {
59- Pid pid = startProcess ([&] {
60- Path dir = dirOf (path);
61- if (chdir (dir.c_str ()) == -1 )
62- throw SysError (" chdir to '%s' failed" , dir);
63- std::string base (baseNameOf (path));
64- if (base.size () + 1 >= sizeof (addr.sun_path ))
65- throw Error (" socket path '%s' is too long" , base);
66- memcpy (addr.sun_path , base.c_str (), base.size () + 1 );
67- if (bind (fd, psaddr, sizeof (addr)) == -1 )
68- throw SysError (" cannot bind to socket '%s'" , path);
69- _exit (0 );
70- });
71- int status = pid.wait ();
72- if (status != 0 )
73- throw Error (" cannot bind to socket '%s'" , path);
74- } else {
75- memcpy (addr.sun_path , path.c_str (), path.size () + 1 );
76- if (bind (fd, psaddr, sizeof (addr)) == -1 )
77- throw SysError (" cannot bind to socket '%s'" , path);
78- }
79- }
8047
81-
82- void connect ( int fd, const std::string & path)
83- {
84- struct sockaddr_un addr;
85- addr. sun_family = AF_UNIX;
86- auto psaddr { safeSockAddrPointerCast (&addr)} ;
48+ // Casting between types like these legacy C library interfaces
49+ // require is forbidden in C++. To maintain backwards
50+ // compatibility, the implementation of the bind/connect functions
51+ // contains some hints to the compiler that allow for this
52+ // special case.
53+ auto * psaddr = reinterpret_cast < struct sockaddr *> (&addr);
8754
8855 if (path.size () + 1 >= sizeof (addr.sun_path )) {
8956 Pipe pipe;
@@ -98,8 +65,8 @@ void connect(int fd, const std::string & path)
9865 if (base.size () + 1 >= sizeof (addr.sun_path ))
9966 throw Error (" socket path '%s' is too long" , base);
10067 memcpy (addr.sun_path , base.c_str (), base.size () + 1 );
101- if (connect (fd, psaddr, sizeof (addr)) == -1 )
102- throw SysError (" cannot connect to socket at '%s'" , path);
68+ if (operation (fd, psaddr, sizeof (addr)) == -1 )
69+ throw SysError (" cannot %s to socket at '%s'" , operationName , path);
10370 writeFull (pipe.writeSide .get (), " 0\n " );
10471 } catch (SysError & e) {
10572 writeFull (pipe.writeSide .get (), fmt (" %d\n " , e.errNo ));
@@ -110,16 +77,30 @@ void connect(int fd, const std::string & path)
11077 pipe.writeSide .close ();
11178 auto errNo = string2Int<int >(chomp (drainFD (pipe.readSide .get ())));
11279 if (!errNo || *errNo == -1 )
113- throw Error (" cannot connect to socket at '%s'" , path);
80+ throw Error (" cannot %s to socket at '%s'" , operationName , path);
11481 else if (*errNo > 0 ) {
11582 errno = *errNo;
116- throw SysError (" cannot connect to socket at '%s'" , path);
83+ throw SysError (" cannot %s to socket at '%s'" , operationName , path);
11784 }
11885 } else {
11986 memcpy (addr.sun_path , path.c_str (), path.size () + 1 );
120- if (connect (fd, psaddr, sizeof (addr)) == -1 )
121- throw SysError (" cannot connect to socket at '%s'" , path);
87+ if (operation (fd, psaddr, sizeof (addr)) == -1 )
88+ throw SysError (" cannot %s to socket at '%s'" , operationName , path);
12289 }
90+
91+ }
92+
93+ void bind (int fd, const std::string & path)
94+ {
95+ unlink (path.c_str ());
96+
97+ bindConnectProcHelper (" bind" , ::bind, fd, path);
98+ }
99+
100+
101+ void connect (int fd, const std::string & path)
102+ {
103+ bindConnectProcHelper (" connect" , ::connect, fd, path);
123104}
124105
125106}
0 commit comments