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 sock_addr
->sin_family
= family
;
64 if (options
| SOCKET_NONBLOCK
){
65 flags
= fcntl(sock
, F_GETFL
, 0);
66 fcntl(sock
, F_SETFL
, flags
|O_NONBLOCK
);
70 PosixSocket(int s
, struct sockaddr_in
*addr
){
75 void setPort(int port
){
77 sock_addr
->sin_port
= htons(port
);
84 void setAddress(char *addr
){
85 inet_pton(AF_INET
, addr
, &(sock_addr
->sin_addr
));
90 addr
= (char*)malloc(sizeof(char) * 17);
91 inet_ntop(AF_INET
, &(sock_addr
->sin_addr
), addr
, 17);
98 slen
= sizeof(struct sockaddr_in
);
100 r
= connect(sock
, (struct sockaddr
*)(sock_addr
), slen
);
107 slen
= sizeof(struct sockaddr_in
);
109 return bind(sock
, (struct sockaddr
*)sock_addr
, slen
);
112 int Listen(int queue
){
114 r
= listen(sock
, queue
);
118 int Write(const char *buffer
, int len
){
119 return write(sock
, buffer
, len
);
122 int Read(char *buffer
, int len
){
123 return read(sock
, buffer
, len
);
128 struct sockaddr_in
*client
;
132 client
= (struct sockaddr_in
*)malloc(sizeof(struct sockaddr_in
));
133 clen
= sizeof(struct sockaddr_in
);
135 client_socket
= accept(sock
, (struct sockaddr
*)client
, &clen
);
137 if (client_socket
== -1)
139 s
= new PosixSocket(client_socket
, client
);
148 int Poll(int ms
, int mode
){
153 sock_poll
.events
= 0;
155 if (mode
| SOCKET_POLL_READ
)
156 sock_poll
.events
|= POLLIN
;
157 if (mode
| SOCKET_POLL_WRITE
)
158 sock_poll
.events
|= POLLOUT
;
160 poll(&sock_poll
, 1, ms
);
162 if (sock_poll
.revents
& POLLIN
)
163 ret
|= SOCKET_POLL_READ
;
164 if (sock_poll
.revents
& POLLOUT
)
165 ret
|= SOCKET_POLL_WRITE
;
171 Socket
*Socket::CreateSocket(int socktype
, int options
){
172 return new PosixSocket(socktype
, options
);