void __cdecl SocketPosixC__SendTo(int fd, const EndPoint* ep, const void* pb, INTEGER n) { INTEGER len = { 0 }; SockAddrIn name = { 0 }; ZERO_MEMORY(name); while (n > 0) { EndPointToAddress(ep, &name); len = sendto(fd, pb, n, 0, (struct sockaddr *)&name, sizeof(name)); CommonWrite(fd, len, (char**)&pb, &n); } }
void __cdecl SocketPosixC__OtherEnd(int fd, EndPoint* ep) { SockAddrIn addr; socklen_t len = sizeof(addr); ZERO_MEMORY(addr); if (getpeername(fd, (struct sockaddr *)&addr, &len) < 0) { IOError(Unexpected); return; } AddressToEndPoint(&addr, ep); }
void __cdecl SocketPosixC__Peek(int fd, EndPoint* ep) { SockAddrIn name; socklen_t len = sizeof(name); ZERO_MEMORY(name); if (recvfrom(fd, NULL, 0, MSG_PEEK, (struct sockaddr *)&name, &len) < 0) { IOError(Unexpected); return; } AddressToEndPoint(&name, ep); }
int __cdecl SocketPosixC__Accept(int server, EndPoint* ep) { SockAddrIn name; int client = { 0 }; while (1) { socklen_t len = sizeof(name); ZERO_MEMORY(name); client = accept(server, (struct sockaddr *)&name, &len); if (client >= 0) { InitStream(client); AddressToEndPoint(&name, ep); return client; } switch (GetSocketError()) { case EMFILE: case ENFILE: IOError(NoResources); return -1; case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif /* nope, not yet */ break; default: IOError(Unexpected); return -1; } SchedulerPosix__IOAlertWait(server, TRUE); } }
void __cdecl SocketPosixC__ThisEnd(int fd, EndPoint* ep) { if (memcmp(ep, &NullAddress, sizeof(NullAddress)) == 0) { GetHostAddr(&ep->address); } if (ep->port == NullPort) { SockAddrIn name; socklen_t len = sizeof(name); ZERO_MEMORY(name); if (getsockname(fd, (struct sockaddr *)&name, &len) != 0) { IOError(Unexpected); return; } ep->port = ntohs(name.sin_port); } }
INTEGER __cdecl SocketPosixC__ReceiveFrom(int fd, EndPoint* ep, ADDRESS b, INTEGER nb, int/*boolean*/ mayBlock) { SockAddrIn name; ZERO_MEMORY(name); while (1) { socklen_t nameLen = sizeof(name); INTEGER len = recvfrom(fd, b, nb, 0, (struct sockaddr *)&name, &nameLen); if (len >= 0) { AddressToEndPoint(&name, ep); return len; } if (CommonRead(fd, GetSocketError(), mayBlock, &len)) return len; } }
void __cdecl SocketPosixC__Bind(int fd, EndPoint* ep) { SockAddrIn name; ZERO_MEMORY(name); SetAddress(ep, &name); if (bind(fd, (struct sockaddr *)&name, sizeof(name)) == -1) { Exception e = Unexpected; switch (GetSocketError()) { #ifdef _WIN32 case WSAEADDRINUSE: #else case EADDRINUSE: #endif e = PortBusy; break; } IOError(e); } }
void __cdecl SocketPosixC__Connect(int fd, EndPoint* ep) { SockAddrIn name; int error; ZERO_MEMORY(name); EndPointToAddress(ep, &name); InitStream(fd); while (1) { if (connect(fd, (struct sockaddr *)&name, sizeof(name)) == 0) break; error = GetSocketError(); #if REFETCH_ERROR switch (error) { case EINVAL: /* hack to try to get real GetSocketError(), hidden due to NBIO bug in connect */ case EBADF: /* we'll try the same for EBADF, which we've seen on Alpha */ error = RefetchError(fd); } #endif if (CommonError(error)) return; switch (error) { #ifdef _WIN32 case WSAEISCONN: #else case EISCONN: #endif return; #ifdef _WIN32 case WSAEADDRNOTAVAIL: case WSAECONNREFUSED: case WSAEINVAL: case WSAECONNRESET: case WSAEBADF: #else case EADDRNOTAVAIL: case ECONNREFUSED: case EINVAL: case ECONNRESET: case EBADF: #endif IOError(Refused); return; #ifdef _WIN32 case WSAEWOULDBLOCK: case WSAEAGAIN: case WSAEINPROGRESS: case WSAEALREADY: #else case EWOULDBLOCK: #if EWOULDBLOCK != EAGAIN case EAGAIN: #endif case EINPROGRESS: case EALREADY: #endif /* nope, not yet */ break; default: IOError(Unexpected); return; } #ifndef _WIN32 SchedulerPosix__IOAlertWait(fd, FALSE); #endif } }
/* returns TME_FALSE if no more blocks are available */ uint32 normal_lut_w_insert(uint8 *key, TME_DATA *data, MEM_TYPE *mem_ex, struct time_conv *time_ref) { uint32 i; uint32 tocs=0; uint32 *key32=(uint32*) key; uint32 shrinked_key=0; uint32 index; RECORD *records=(RECORD*)data->lut_base_address; uint8 *offset; uint32 key_len=data->key_len; /*the key is shrinked into a 32-bit value */ for (i=0; i<key_len;i++) shrinked_key^=key32[i]; /*the first index in the table is calculated*/ index=shrinked_key % data->lut_entries; while (tocs<=data->filled_entries) { if (records[index].block==0) { /*creation of a new entry*/ if (data->filled_blocks==data->shared_memory_blocks) { /*no more free blocks*/ GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); data->last_found=NULL; return TME_FALSE; } /*offset=absolute pointer to the block associated*/ /*with the newly created entry*/ offset=data->shared_memory_base_address+ data->block_size*data->filled_blocks; /*copy the key in the block*/ COPY_MEMORY(offset,key32,key_len*4); GET_TIME((struct timeval *)(offset+4*key_len),time_ref); /*assign the block relative offset to the entry, in NBO*/ SW_ULONG_ASSIGN(&records[index].block,offset-mem_ex->buffer); data->filled_blocks++; /*assign the exec function ID to the entry, in NBO*/ SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec); data->filled_entries++; data->last_found=(uint8*)&records[index]; return TME_TRUE; } /*offset contains the absolute pointer to the block*/ /*associated with the current entry */ offset=mem_ex->buffer+SW_ULONG_AT(&records[index].block,0); for (i=0; (i<key_len) && (key32[i]==ULONG_AT(offset,i*4)); i++); if (i==key_len) { /*key in the block matches the one provided, right entry*/ GET_TIME((struct timeval *)(offset+4*key_len),time_ref); data->last_found=(uint8*)&records[index]; return TME_TRUE; } else { /* wrong entry, rehashing */ if (IS_DELETABLE(offset+key_len*4,data)) { ZERO_MEMORY(offset,data->block_size); COPY_MEMORY(offset,key32,key_len*4); SW_ULONG_ASSIGN(&records[index].exec_fcn,data->default_exec); GET_TIME((struct timeval*)(offset+key_len*4),time_ref); data->last_found=(uint8*)&records[index]; return TME_TRUE; } else { index=(index+data->rehashing_value) % data->lut_entries; tocs++; } } } /* nothing found, last found= out of lut */ GET_TIME((struct timeval *)(data->shared_memory_base_address+4*key_len),time_ref); data->last_found=NULL; return TME_FALSE; }