* @brief Create a passive UNIX socket * * Creating a DGRAM server socket is the same as creating one * using `create_unix_dgram_socket()` but with latter you may * also not bind to anywhere. * * @param path Path to bind the socket to * @param socktype `LIBSOCKET_STREAM` or `LIBSOCKET_DGRAM` * @param flags Flags for `socket(2)`. * * @retval >0 Success; returned value is a file descriptor
| 304 | * @retval <0 An error occurred. |
| 305 | */ |
| 306 | int create_unix_server_socket(const char* path, int socktype, int flags) { |
| 307 | struct sockaddr_un saddr; |
| 308 | int sfd, type, retval; |
| 309 | |
| 310 | if (path == NULL) return -1; |
| 311 | |
| 312 | if (strlen(path) > (sizeof(saddr.sun_path) - 1)) { |
| 313 | #ifdef VERBOSE |
| 314 | debug_write("create_unix_server_socket: Path too long\n"); |
| 315 | #endif |
| 316 | return -1; |
| 317 | } |
| 318 | |
| 319 | switch (socktype) { |
| 320 | case LIBSOCKET_STREAM: |
| 321 | type = SOCK_STREAM; |
| 322 | break; |
| 323 | case LIBSOCKET_DGRAM: |
| 324 | type = SOCK_DGRAM; |
| 325 | break; |
| 326 | default: |
| 327 | return -1; |
| 328 | } |
| 329 | |
| 330 | if (-1 == check_error(sfd = socket(AF_UNIX, type | flags, 0))) return -1; |
| 331 | |
| 332 | if ((retval = unlink(path)) == -1 && |
| 333 | errno != ENOENT) // If there's another error than "doesn't exist" |
| 334 | { |
| 335 | check_error(retval); |
| 336 | return -1; |
| 337 | } |
| 338 | |
| 339 | memset(&saddr, 0, sizeof(struct sockaddr_un)); |
| 340 | |
| 341 | saddr.sun_family = AF_UNIX; |
| 342 | |
| 343 | strncpy(saddr.sun_path, path, sizeof(saddr.sun_path) - 1); |
| 344 | |
| 345 | if (-1 == |
| 346 | check_error(bind(sfd, (struct sockaddr*)&saddr, |
| 347 | sizeof(saddr.sun_family) + strlen(saddr.sun_path)))) |
| 348 | return -1; |
| 349 | |
| 350 | if (type == SOCK_STREAM) { |
| 351 | if (-1 == check_error(listen(sfd, LIBSOCKET_BACKLOG))) return -1; |
| 352 | } |
| 353 | |
| 354 | return sfd; |
| 355 | } |
| 356 | |
| 357 | /** |
| 358 | * @brief Accept connections on a passive UNIX socket |