1 /* domsock_create.c
2 ** domsock: unix/local domain sockets
3 ** wcm, 2010.12.30 - 2010.12.30
4 ** ===
5 */
6 
7 /* libc: */
8 
9 /* unix: */
10 #include <unistd.h>
11 #include <errno.h>
12 #include <sys/socket.h>
13 #include <sys/stat.h>
14 #include <sys/un.h>
15 
16 /* lasagna: */
17 #include "buf.h"
18 #include "cstr.h"
19 
20 /* domsock: */
21 #include "domsock.h"
22 
23 int
domsock_create(const char * path,mode_t mode)24 domsock_create(const char *path, mode_t mode)
25 {
26   struct sockaddr_un  sockaddr;
27   mode_t              umask_orig;
28   int                 s;
29   int                 e, terrno;
30 
31   if(sizeof(sockaddr.sun_path) < (cstr_len(path) + 1)){
32       errno = ENAMETOOLONG;
33       return -1;
34   }
35 
36   if((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1){
37       return -1;
38   }
39 
40   unlink(path);
41   buf_zero(&sockaddr, sizeof (sockaddr));
42   sockaddr.sun_family = AF_LOCAL;
43   cstr_copy(sockaddr.sun_path, path);
44   if(bind(s, (const struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1){
45       goto FAIL;
46   }
47 
48   if(mode != 0){
49       umask_orig = umask(0);
50       e = chmod(path, mode);
51       umask(umask_orig);
52       if(e == -1){
53           goto FAIL;
54       }
55   }
56 
57   /* success: */
58   return s;
59 
60 FAIL:
61   terrno = errno;
62   unlink(path);
63   close(s);
64   errno = terrno;
65   return -1;
66 }
67 
68 
69 /* eof: domsock_create.c */
70