mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-09 02:29:07 +08:00
95 lines
2.7 KiB
C
95 lines
2.7 KiB
C
/*************************************************************************\
|
|
* Copyright (C) Michael Kerrisk, 2018. *
|
|
* *
|
|
* This program is free software. You may use, modify, and redistribute it *
|
|
* under the terms of the GNU Lesser General Public License as published *
|
|
* by the Free Software Foundation, either version 3 or (at your option) *
|
|
* any later version. This program is distributed without any warranty. *
|
|
* See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. *
|
|
\*************************************************************************/
|
|
|
|
/* Solution for Exercise 59-3:b */
|
|
|
|
/* unix_sockets.c
|
|
|
|
A package of useful routines for UNIX domain sockets.
|
|
*/
|
|
#include "unix_sockets.h" /* Declares functions defined here */
|
|
#include "af_unix_hdr.h"
|
|
|
|
/* Build a UNIX domain socket address structure for 'path', returning
|
|
it in 'addr'. Returns -1 on success, or 0 on error. */
|
|
|
|
int
|
|
unixBuildAddress(const char *path, struct sockaddr_un *addr)
|
|
{
|
|
if (addr == NULL || path == NULL) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
memset(addr, 0, sizeof(struct sockaddr_un));
|
|
addr->sun_family = AF_UNIX;
|
|
if (strlen(path) < sizeof(addr->sun_path)) {
|
|
strncpy(addr->sun_path, path, sizeof(addr->sun_path) - 1);
|
|
return 0;
|
|
} else {
|
|
errno = ENAMETOOLONG;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* Create a UNIX domain socket of type 'type' and connect it
|
|
to the remote address specified by the 'path'.
|
|
Return the socket descriptor on success, or -1 on error */
|
|
|
|
int
|
|
unixConnect(const char *path, int type)
|
|
{
|
|
int sd, savedErrno;
|
|
struct sockaddr_un addr;
|
|
|
|
if (unixBuildAddress(path, &addr) == -1)
|
|
return -1;
|
|
|
|
sd = socket(AF_UNIX, type, 0);
|
|
if (sd == -1)
|
|
return -1;
|
|
|
|
if (connect(sd, (struct sockaddr *) &addr,
|
|
sizeof(struct sockaddr_un)) == -1) {
|
|
savedErrno = errno;
|
|
close(sd); /* Might change 'errno' */
|
|
errno = savedErrno;
|
|
return -1;
|
|
}
|
|
|
|
return sd;
|
|
}
|
|
|
|
/* Create a UNIX domain socket and bind it to 'path'.
|
|
Return the socket descriptor on success, or -1 on error. */
|
|
|
|
int
|
|
unixBind(const char *path, int type)
|
|
{
|
|
int sd, savedErrno;
|
|
struct sockaddr_un addr;
|
|
|
|
if (unixBuildAddress(path, &addr) == -1)
|
|
return -1;
|
|
|
|
sd = socket(AF_UNIX, type, 0);
|
|
if (sd == -1)
|
|
return -1;
|
|
|
|
if (bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1) {
|
|
savedErrno = errno;
|
|
close(sd); /* Might change 'errno' */
|
|
errno = savedErrno;
|
|
return -1;
|
|
}
|
|
|
|
return sd;
|
|
}
|