2 libfmail: Socket abstraction, Posix Implementation
4 Copyright (C) 2007 Carlos Daniel Ruvalcaba Valenzuela <clsdaniel@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <sys/types.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <sys/socket.h>
32 #include <sys/ioctl.h>
36 #include <libfmail/socket.h>
38 /* TODO: Add proper Unix socket support
39 * TODO: Add better Poll implementation
40 * TODO: Add proper NONBLOCK implementation
42 class PosixSocket
: public Socket
{
46 struct sockaddr_in
* sock_addr
;
47 struct pollfd sock_poll
;
49 PosixSocket(int socktype
, int options
){
53 if (socktype
== SOCKET_INET
){
55 } else if (socktype
== SOCKET_UNIX
){
59 sock
= socket(family
, SOCK_STREAM
, 0);
60 sock_addr
= (struct sockaddr_in
*)malloc(sizeof(struct sockaddr_in
));
61 memset(sock_addr
, 0, sizeof(*sock_addr
));
62 sock_addr
->sin_family
= family
;
65 if (options
| SOCKET_NONBLOCK
){
66 flags
= fcntl(sock
, F_GETFL
, 0);
67 fcntl(sock
, F_SETFL
, flags
|O_NONBLOCK
);
71 PosixSocket(int s
, struct sockaddr_in
* addr
){
80 void setPort(int port
){
82 sock_addr
->sin_port
= htons(port
);
89 void setAddress(const char * addr
){
91 sock_addr
->sin_addr
.s_addr
= htonl(INADDR_ANY
);
93 inet_pton(AF_INET
, addr
, &(sock_addr
->sin_addr
));
99 addr
= (char *)malloc(sizeof(char) * 17);
102 inet_ntop(AF_INET
, &(sock_addr
->sin_addr
), addr
, 17);
109 slen
= sizeof(struct sockaddr_in
);
110 return connect(sock
, (struct sockaddr
*)(sock_addr
), slen
);
116 slen
= sizeof(struct sockaddr_in
);
117 return bind(sock
, (struct sockaddr
*)sock_addr
, slen
);
120 int Listen(int queue
){
121 return listen(sock
, queue
);
124 int Write(const char * buffer
, int len
){
125 return write(sock
, buffer
, len
);
128 int Read(char * buffer
, int len
){
129 return read(sock
, buffer
, len
);
134 struct sockaddr_in
* client
;
138 client
= (struct sockaddr_in
*)malloc(sizeof(struct sockaddr_in
));
141 clen
= sizeof(struct sockaddr_in
);
143 client_socket
= accept(sock
, (struct sockaddr
*)client
, &clen
);
145 if (client_socket
== -1)
147 s
= new PosixSocket(client_socket
, client
);
155 int Poll(int ms
, int mode
){
160 sock_poll
.events
= 0;
162 if (mode
& SOCKET_POLL_READ
)
163 sock_poll
.events
|= POLLIN
;
164 if (mode
& SOCKET_POLL_WRITE
)
165 sock_poll
.events
|= POLLOUT
;
166 if (mode
& SOCKET_POLL_ERROR
)
167 sock_poll
.events
|= POLLERR
;
169 ret
= poll(&sock_poll
, 1, ms
);
171 ret
|= SOCKET_POLL_ERROR
;
175 if (sock_poll
.revents
& POLLIN
)
176 ret
|= SOCKET_POLL_READ
;
177 if (sock_poll
.revents
& POLLOUT
)
178 ret
|= SOCKET_POLL_WRITE
;
179 if (sock_poll
.revents
& POLLERR
)
180 ret
|= SOCKET_POLL_ERROR
;
186 Socket
* Socket::CreateSocket(int socktype
, int options
){
187 return new PosixSocket(socktype
, options
);