1 /************************************************
2
3 unixserver.c -
4
5 created at: Thu Mar 31 12:21:29 JST 1994
6
7 Copyright (C) 1993-2007 Yukihiro Matsumoto
8
9 ************************************************/
10
11 #include "rubysocket.h"
12
13 #ifdef HAVE_SYS_UN_H
14 /*
15 * call-seq:
16 * UNIXServer.new(path) => unixserver
17 *
18 * Creates a new UNIX server socket bound to _path_.
19 *
20 * require 'socket'
21 *
22 * serv = UNIXServer.new("/tmp/sock")
23 * s = serv.accept
24 * p s.read
25 */
26 static VALUE
unix_svr_init(VALUE sock,VALUE path)27 unix_svr_init(VALUE sock, VALUE path)
28 {
29 return rsock_init_unixsock(sock, path, 1);
30 }
31
32 /*
33 * call-seq:
34 * unixserver.accept => unixsocket
35 *
36 * Accepts an incoming connection.
37 * It returns a new UNIXSocket object.
38 *
39 * UNIXServer.open("/tmp/sock") {|serv|
40 * UNIXSocket.open("/tmp/sock") {|c|
41 * s = serv.accept
42 * s.puts "hi"
43 * s.close
44 * p c.read #=> "hi\n"
45 * }
46 * }
47 *
48 */
49 static VALUE
unix_accept(VALUE sock)50 unix_accept(VALUE sock)
51 {
52 rb_io_t *fptr;
53 struct sockaddr_un from;
54 socklen_t fromlen;
55
56 GetOpenFile(sock, fptr);
57 fromlen = (socklen_t)sizeof(struct sockaddr_un);
58 return rsock_s_accept(rb_cUNIXSocket, fptr->fd,
59 (struct sockaddr*)&from, &fromlen);
60 }
61
62 /* :nodoc: */
63 static VALUE
unix_accept_nonblock(VALUE sock,VALUE ex)64 unix_accept_nonblock(VALUE sock, VALUE ex)
65 {
66 rb_io_t *fptr;
67 struct sockaddr_un from;
68 socklen_t fromlen;
69
70 GetOpenFile(sock, fptr);
71 fromlen = (socklen_t)sizeof(from);
72 return rsock_s_accept_nonblock(rb_cUNIXSocket, ex, fptr,
73 (struct sockaddr *)&from, &fromlen);
74 }
75
76 /*
77 * call-seq:
78 * unixserver.sysaccept => file_descriptor
79 *
80 * Accepts a new connection.
81 * It returns the new file descriptor which is an integer.
82 *
83 * UNIXServer.open("/tmp/sock") {|serv|
84 * UNIXSocket.open("/tmp/sock") {|c|
85 * fd = serv.sysaccept
86 * s = IO.new(fd)
87 * s.puts "hi"
88 * s.close
89 * p c.read #=> "hi\n"
90 * }
91 * }
92 *
93 */
94 static VALUE
unix_sysaccept(VALUE sock)95 unix_sysaccept(VALUE sock)
96 {
97 rb_io_t *fptr;
98 struct sockaddr_un from;
99 socklen_t fromlen;
100
101 GetOpenFile(sock, fptr);
102 fromlen = (socklen_t)sizeof(struct sockaddr_un);
103 return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen);
104 }
105
106 #endif
107
108 void
rsock_init_unixserver(void)109 rsock_init_unixserver(void)
110 {
111 #ifdef HAVE_SYS_UN_H
112 /*
113 * Document-class: UNIXServer < UNIXSocket
114 *
115 * UNIXServer represents a UNIX domain stream server socket.
116 *
117 */
118 rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
119 rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1);
120 rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0);
121
122 rb_define_private_method(rb_cUNIXServer,
123 "__accept_nonblock", unix_accept_nonblock, 1);
124
125 rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0);
126 rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */
127 #endif
128 }
129