Added Lock class
[fmail.git] / src / posixsocket.cpp
blobac4d9ebe148349d5350ac98164ebdc64e5f505a1
1 /*
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.
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <malloc.h>
25 #include <sys/types.h>
26 #include <sys/uio.h>
27 #include <unistd.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <sys/socket.h>
31 #include <sys/time.h>
32 #include <sys/ioctl.h>
33 #include <poll.h>
34 #include <fcntl.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
41 * */
42 class PosixSocket : public Socket{
43 private:
44 int sock;
45 int sock_port;
46 struct sockaddr_in *sock_addr;
47 struct pollfd sock_poll;
48 public:
49 PosixSocket(int socktype, int options){
50 int family;
51 int flags;
53 if (socktype == SOCKET_INET){
54 family = AF_INET;
55 }else if (socktype == SOCKET_UNIX){
56 family = AF_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;
62 sock_poll.fd = sock;
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){
71 sock = s;
72 sock_addr = addr;
75 void setPort(int port){
76 sock_port = port;
77 sock_addr->sin_port = htons(port);
80 int getPort(){
81 return sock_port;
84 void setAddress(char *addr){
85 inet_pton(AF_INET, addr, &(sock_addr->sin_addr));
88 char *getAddress(){
89 char *addr;
90 addr = (char*)malloc(sizeof(char) * 17);
91 inet_ntop(AF_INET, &(sock_addr->sin_addr), addr, 17);
92 return addr;
95 int Connect(){
96 int slen, r;
98 slen = sizeof(struct sockaddr_in);
100 r = connect(sock, (struct sockaddr*)(sock_addr), slen);
101 return r;
104 int Bind(){
105 int slen;
107 slen = sizeof(struct sockaddr_in);
109 return bind(sock, (struct sockaddr*)sock_addr, slen);
112 int Listen(int queue){
113 int r;
114 r = listen(sock, queue);
115 return r;
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);
126 Socket *Accept(){
127 int client_socket;
128 struct sockaddr_in *client;
129 socklen_t clen;
130 Socket *s;
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)
138 return NULL;
139 s = new PosixSocket(client_socket, client);
141 return s;
144 int Close(){
145 return close(sock);
148 int Poll(int ms, int mode){
149 int ret;
151 ret = 0;
153 if (mode | SOCKET_POLL_READ)
154 sock_poll.events |= POLLIN;
155 if (mode | SOCKET_POLL_WRITE)
156 sock_poll.events |= POLLOUT;
158 poll(&sock_poll, 1, ms);
160 if (sock_poll.revents & POLLIN)
161 ret |= SOCKET_POLL_READ;
162 if (sock_poll.revents & POLLOUT)
163 ret |= SOCKET_POLL_WRITE;
165 return ret;
169 Socket *Socket::CreateSocket(int socktype, int options){
170 return new PosixSocket(socktype, options);