Added SILC Thread Queue API
[silc.git] / lib / silcutil / beos / silcbeossockconn.c
1 /*
2
3   silcbeossockconn.c 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2002 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 /* On BONE we can use Unix code */
22 #ifdef SILC_BEOS_BONE
23 #include "../unix/silcunixsockconn.c"
24 #else
25 #include "silc.h"
26
27 /* Writes data from encrypted buffer to the socket connection. If the
28    data cannot be written at once, it will be written later with a timeout. 
29    The data is written from the data section of the buffer, not from head
30    or tail section. This automatically pulls the data section towards end
31    after writing the data. */
32
33 int silc_socket_write(SilcSocketConnection sock)
34 {
35   int ret = 0;
36   SilcBuffer src = sock->outbuf;
37
38   if (SILC_IS_DISABLED(sock))
39     return -1;
40
41   SILC_LOG_DEBUG(("Writing data to socket %d", sock->sock));
42
43   if (src->len > 0) {
44     ret = send(sock->sock, src->data, src->len, 0);
45     if (ret == -1) {
46       if (errno == EWOULDBLOCK) {
47         SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
48         return -2;
49       }
50       SILC_LOG_ERROR(("Cannot write to socket: %d", sock->sock));
51       sock->sock_error = errno;
52       return -1;
53     }
54
55     if (ret < src->len) {
56       SILC_LOG_DEBUG(("Wrote data %d of %d bytes, will write rest later",
57                       ret, src->len));
58       silc_buffer_pull(src, ret);
59       return -2;
60     }
61
62     silc_buffer_pull(src, ret);
63   }
64
65   SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
66
67   return ret;
68 }
69
70 /* Reads data from the socket connection into the incoming data buffer.
71    It reads as much as possible from the socket connection. This returns
72    amount of bytes read or -1 on error or -2 on case where all of the
73    data could not be read at once. */
74
75 int silc_socket_read(SilcSocketConnection sock)
76 {
77   int len = 0;
78   unsigned char buf[SILC_SOCKET_READ_SIZE];
79
80   if (SILC_IS_DISABLED(sock))
81     return -1;
82
83   SILC_LOG_DEBUG(("Reading data from socket %d", sock->sock));
84
85   /* Read the data from the socket. */
86   len = recv(sock->sock, buf, sizeof(buf), 0);
87   if (len == -1) {
88     if (errno == EWOULDBLOCK || errno == EINTR) {
89       SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
90       return -2;
91     }
92     SILC_LOG_ERROR(("Cannot read from socket: %d", sock->sock));
93     sock->sock_error = errno;
94     return -1;
95   }
96
97   if (!len)
98     return 0;
99
100   /* Insert the data to the buffer. */
101
102   if (!sock->inbuf)
103     sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE);
104   
105   /* If the data does not fit to the buffer reallocate it */
106   if ((sock->inbuf->end - sock->inbuf->tail) < len)
107     sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen + 
108                                       (len * 2));
109   silc_buffer_put_tail(sock->inbuf, buf, len);
110   silc_buffer_pull_tail(sock->inbuf, len);
111
112   SILC_LOG_DEBUG(("Read %d bytes", len));
113
114   return len;
115 }
116
117 /* Returns human readable socket error message */
118
119 SilcBool silc_socket_get_error(SilcSocketConnection sock, char *error,
120                            SilcUInt32 error_len)
121 {
122   char *err;
123
124   if (!sock->sock_error)
125     return FALSE;
126
127   err = strerror(sock->sock_error);
128   if (strlen(err) > error_len)
129     return FALSE;
130
131   memset(error, 0, error_len);
132   memcpy(error, err, strlen(err));
133   return TRUE;
134 }
135
136 #endif /* SILC_BEOS_BONE */