Пример #1
0
wi_boolean_t wi_socket_listen(wi_socket_t *_socket, uint32_t backlog) {
	struct sockaddr		*sa;
	uint32_t			length;
	
	sa		= wi_address_sa(_socket->address);
	length	= wi_address_sa_length(_socket->address);
	
	if(bind(_socket->sd, sa, length) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}

	if(_socket->type == WI_SOCKET_TCP) {
		if(listen(_socket->sd, backlog) < 0) {
			wi_error_set_errno(errno);

			return false;
		}
	}
	
	_socket->direction = WI_SOCKET_READ;
	
	return true;
}
Пример #2
0
wi_boolean_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) {
	struct timeval	tv;
	fd_set			rfds, wfds;
	int				state;
	
	tv = wi_dtotv(timeout);
	
	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	
	if(read)
		FD_SET(sd, &rfds);
	
	if(write)
		FD_SET(sd, &wfds);
	
	state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
	
	if(state < 0)
		wi_error_set_errno(errno);
	else if(state == 0)
		wi_error_set_errno(ETIMEDOUT);
	
	return (state > 0);
}
Пример #3
0
wi_boolean_t wi_switch_user(uid_t uid, gid_t gid) {
    struct passwd   *user;
    
    if(gid != getegid()) {
        user = getpwuid(uid);
        
        if(user) {
            if(initgroups(user->pw_name, gid) < 0) {
                wi_error_set_errno(errno);
                
                return false;
            }
        }
            
        if(setgid(gid) < 0) {
            wi_error_set_errno(errno);
            
            return false;
        }
    }

    if(uid != geteuid()) {
        if(setuid(uid) < 0) {
            wi_error_set_errno(errno);
            
            return false;
        }
    }
    
    return true;
}
Пример #4
0
static wi_integer_t _wi_socket_read_buffer(wi_socket_t *socket, wi_time_interval_t timeout, void *buffer, size_t length) {
	wi_socket_state_t	state;
	wi_integer_t		bytes;
	
#ifdef HAVE_OPENSSL_SSL_H
	if(socket->ssl) {
		if(timeout > 0.0 && SSL_pending(socket->ssl) == 0) {
			state = wi_socket_wait_descriptor(socket->sd, timeout, true, false);
			
			if(state != WI_SOCKET_READY) {
				if(state == WI_SOCKET_TIMEOUT)
					wi_error_set_errno(ETIMEDOUT);
				
				return -1;
			}
		}
		
		ERR_clear_error();
		
		bytes = SSL_read(socket->ssl, buffer, length);
		
		if(bytes <= 0) {
			wi_error_set_openssl_ssl_error_with_result(socket->ssl, bytes);
			
			ERR_clear_error();
		}
		
		return bytes;
	} else {
#endif
		if(timeout > 0.0) {
			state = wi_socket_wait_descriptor(socket->sd, timeout, true, false);
			
			if(state != WI_SOCKET_READY) {
				if(state == WI_SOCKET_TIMEOUT)
					wi_error_set_errno(ETIMEDOUT);
				
				return -1;
			}
		}
		
		bytes = read(socket->sd, buffer, length);
		
		if(bytes <= 0) {
			if(bytes < 0)
				wi_error_set_errno(errno);
			else
				wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
		}
		
		return bytes;
#ifdef HAVE_OPENSSL_SSL_H
	}
#endif
	
	return 0;
}
Пример #5
0
wi_boolean_t wi_thread_create_thread_with_priority(wi_thread_func_t *function, wi_runtime_instance_t *argument, double priority) {
#ifdef WI_PTHREADS
#if defined(HAVE_PTHREAD_ATTR_SETSCHEDPOLICY) && defined(HAVE_SCHED_GET_PRIORITY_MIN) && defined(HAVE_SCHED_GET_PRIORITY_MAX)
	struct sched_param		param;
	int						min, max;
#endif
	pthread_t				thread;
	pthread_attr_t			attr;
	void					**vector;
	int						err;
	
	vector = wi_malloc(2 * sizeof(void *));
	vector[0] = function;
	vector[1] = wi_retain(argument);

	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
#if defined(HAVE_PTHREAD_ATTR_SETSCHEDPOLICY) && defined(HAVE_SCHED_GET_PRIORITY_MIN) && defined(HAVE_SCHED_GET_PRIORITY_MAX)
	min = sched_get_priority_min(SCHED_OTHER);
	max = sched_get_priority_max(SCHED_OTHER);
	
	if(min > 0 && max > 0)
		param.sched_priority = min + ((max - min) * priority);
	else
		param.sched_priority = 0;
	
	pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
	pthread_attr_setschedparam(&attr, &param);
#endif
	
	err = pthread_create(&thread, &attr, _wi_thread_trampoline, vector);
	
	pthread_attr_destroy(&attr);
	
	if(err != 0) {
		wi_error_set_errno(err);
		
		wi_release(vector[1]);
		wi_free(vector);
		
		return false;
	}
	
	return true;
#else
	wi_error_set_errno(WI_ERROR_THREADS_NOTSUPP);
	
	return false;
#endif
}
Пример #6
0
int32_t wi_socket_recvfrom(wi_socket_t *socket, wi_socket_context_t *context, char *buffer, size_t length, wi_address_t **address) {
	struct sockaddr_storage		ss;
	char						*inbuffer = NULL;
	socklen_t					sslength;
	int							bytes;
	
	sslength = sizeof(ss);
	
#ifdef WI_SSL
	if(context && context->priv_rsa) {
		inbuffer = wi_malloc(length);
		bytes = recvfrom(socket->sd, inbuffer, length, 0, (struct sockaddr *) &ss, &sslength);
		
		if(bytes < 0) {
			wi_error_set_errno(errno);
			
			goto end;
		}
		
		bytes = RSA_private_decrypt(bytes, (unsigned char *) inbuffer, (unsigned char *) buffer,
			context->priv_rsa, RSA_PKCS1_OAEP_PADDING);
		
		if(bytes < 0) {
			wi_error_set_ssl_error();

			goto end;
		}
	} else {
#endif
		bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength);

		if(bytes < 0) {
			wi_error_set_errno(errno);
			
			goto end;
		}
#ifdef WI_SSL
	}
#endif

end:
	*address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;

	if(inbuffer)
		wi_free(inbuffer);

	return bytes;
}
Пример #7
0
int wi_log_syslog_facility_with_name(wi_string_t *name) {
#if HAVE_SYSLOG_FACILITYNAMES
	const char		*cstring;
	int				i;
	
	cstring = wi_string_cstring(name);
	
	for(i = 0; facilitynames[i].c_name != NULL; i++) {
		if(strcmp(cstring, facilitynames[i].c_name) == 0)
			break;
	}

	if(!facilitynames[i].c_name) {
		wi_error_set_libwired_error(WI_ERROR_LOG_NOSUCHFACILITY);
		
		return -1;
	}

	return facilitynames[i].c_val;
#else
	wi_error_set_errno(ENOTSUP);
	
	return -1;
#endif
}
Пример #8
0
wi_file_t * wi_file_init_with_path(wi_file_t *file, wi_string_t *path, wi_file_mode_t mode) {
	int		flags;

	if(mode & WI_FILE_WRITING)	
		flags = O_CREAT;
	else
		flags = 0;
	
	if((mode & WI_FILE_READING) && (mode & WI_FILE_WRITING))
		flags |= O_RDWR;
	else if(mode & WI_FILE_READING)
		flags |= O_RDONLY;
	else if(mode & WI_FILE_WRITING)
		flags |= O_WRONLY;
	
	if(mode & WI_FILE_WRITING) {
		if(mode & WI_FILE_UPDATING)
			flags |= O_APPEND;
		else
			flags |= O_TRUNC;
	}
		
	file->fd = open(wi_string_cstring(path), flags, 0666);
	
	if(file->fd < 0) {
		wi_error_set_errno(errno);

		wi_release(file);
		
		return NULL;
	}
	
	return file;
}
Пример #9
0
wi_array_t * wi_file_directory_contents_at_path(wi_string_t *path) {
	wi_array_t		*contents;
	wi_string_t		*name;
	DIR				*dir;
	struct dirent	de, *dep;
	
	dir = opendir(wi_string_cstring(path));
	
	if(!dir) {
		wi_error_set_errno(errno);
		
		return NULL;
	}
	
	contents = wi_array_init_with_capacity(wi_array_alloc(), 100);
	
	while(readdir_r(dir, &de, &dep) == 0 && dep) {
		if(strcmp(dep->d_name, ".") != 0 && strcmp(dep->d_name, "..") != 0) {
			name = wi_string_init_with_cstring(wi_string_alloc(), dep->d_name);
			wi_array_add_data(contents, name);
			wi_release(name);
		}
	}

	closedir(dir);
	
	return wi_autorelease(contents);
}
Пример #10
0
wi_socket_t * wi_socket_init_with_address(wi_socket_t *_socket, wi_address_t *address, wi_socket_type_t type) {
	_socket->address	= wi_copy(address);
	_socket->close		= true;
	_socket->buffer		= wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
	_socket->type		= type;

	_socket->sd			= socket(wi_address_family(_socket->address), _socket->type, 0);
	
	if(_socket->sd < 0) {
		wi_error_set_errno(errno);
		
		wi_release(_socket);
		
		return NULL;
	}
	
	if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
		wi_release(_socket);
		
		return NULL;
	}
	
#ifdef SO_REUSEPORT
	if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEPORT, 1)) {
		wi_release(_socket);
		
		return NULL;
	}
#endif

	return _socket;
}
Пример #11
0
wi_socket_state_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) {
	struct timeval	tv;
	fd_set			rfds, wfds;
	int				state;
	
	tv = wi_dtotv(timeout);
	
	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	
	WI_ASSERT(sd >= 0, "%d should be positive", sd);
	WI_ASSERT(sd < (int) FD_SETSIZE, "%d should be less than %d", sd, FD_SETSIZE);
	WI_ASSERT(read || write, "read and write can't both be false");
	
	if(read)
		FD_SET(sd, &rfds);
	
	if(write)
		FD_SET(sd, &wfds);
	
	state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
	
	if(state < 0) {
		wi_error_set_errno(errno);
		
		return WI_SOCKET_ERROR;
	}
	
	if(state == 0)
		return WI_SOCKET_TIMEOUT;
	
	return WI_SOCKET_READY;
}
Пример #12
0
wi_socket_state_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) {
	struct timeval	tv;
	fd_set			rfds, wfds;
	int				state;
	
	tv = wi_dtotv(timeout);
	
	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	
	if(read)
		FD_SET(sd, &rfds);
	
	if(write)
		FD_SET(sd, &wfds);
	
	state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
	
	if(state < 0) {
		wi_error_set_errno(errno);
		
		return WI_SOCKET_ERROR;
	}
	
	if(state == 0)
		return WI_SOCKET_TIMEOUT;
	
	return WI_SOCKET_READY;
}
Пример #13
0
wi_boolean_t wi_file_copy(wi_string_t *frompath, wi_string_t *topath) {
	struct stat		sb;
	int				err;
	wi_boolean_t	result;
	
	if(!wi_file_lstat(frompath, &sb))
		return false;
	
	if(wi_file_lstat(topath, &sb))
		return false;
	
	if(S_ISDIR(sb.st_mode))
		result = _wi_file_copy_directory(frompath, topath);
	else
		result = _wi_file_copy_file(frompath, topath);
	
	if(!result) {
		err = errno;
		
		wi_file_delete(topath);

		wi_error_set_errno(err);
	}
	
	return result;
}
Пример #14
0
wi_x509_t * wi_x509_init_with_pem_file(wi_x509_t *x509, wi_string_t *path) {
	FILE		*fp;
	
	fp = fopen(wi_string_cstring(path), "r");
	
	if(!fp) {
		wi_error_set_errno(errno);
		
		wi_release(x509);
		
		return NULL;
	}
	
	x509->x509 = PEM_read_X509(fp, NULL, NULL, NULL);
	
	fclose(fp);
	
	if(!x509->x509) {
		wi_error_set_openssl_error();
		
		wi_release(x509);
		
		return NULL;
	}
	
	return x509;
}
Пример #15
0
wi_rsa_t * wi_rsa_init_with_pem_file(wi_rsa_t *rsa, wi_string_t *path) {
	FILE		*fp;
	
	fp = fopen(wi_string_cstring(path), "r");
	
	if(!fp) {
		wi_error_set_errno(errno);
		
		wi_release(rsa);
		
		return NULL;
	}
	
	rsa->rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
	
	fclose(fp);
	
	if(!rsa->rsa) {
		wi_error_set_openssl_error();
		
		wi_release(rsa);
		
		return NULL;
	}
	
	return rsa;
}
Пример #16
0
wi_socket_t * wi_socket_accept(wi_socket_t *accept_socket, wi_time_interval_t timeout, wi_address_t **address) {
	wi_socket_t					*socket;
	struct sockaddr_storage		ss;
	socklen_t					length;
	int							sd, err = 0;
	
	length = sizeof(ss);
	sd = accept(accept_socket->sd, (struct sockaddr *) &ss, &length);
	
	if(sd < 0)
		err = errno;

	*address = (length > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;

	if(sd < 0) {
		wi_error_set_errno(err);
		
		return NULL;
	}

	socket = wi_socket_init_with_descriptor(wi_socket_alloc(), sd);

	socket->close		= true;
	socket->address		= wi_retain(*address);
	socket->type		= accept_socket->type;
	socket->direction	= WI_SOCKET_READ;
	socket->interactive	= accept_socket->interactive;
	
	return wi_autorelease(socket);
}
Пример #17
0
wi_integer_t wi_file_write_bytes(wi_file_t *file, const void *buffer, wi_uinteger_t length) {
    wi_uinteger_t   offset;
    wi_integer_t    bytes;
    
    _WI_FILE_ASSERT_OPEN(file);
    
    offset = 0;
    
    while(offset < length) {
        bytes = write(file->fd, buffer + offset, length - offset);
        
        if(bytes > 0) {
            offset += bytes;
            file->offset += bytes;
        } else {
            if(bytes == 0) {
                return offset;
            } else {
                if(errno == EINTR) {
                    continue;
                } else {
                    wi_error_set_errno(errno);
                    
                    return -1;
                }
            }
        }
    }
    
    return offset;
}
Пример #18
0
wi_boolean_t wi_data_write_to_file(wi_data_t *data, wi_string_t *path) {
	FILE			*fp;
	wi_string_t		*fullpath;
	
	fullpath = wi_string_by_appending_string(path, WI_STR("~"));
	
	fp = fopen(wi_string_cstring(fullpath), "w");

	if(!fp) {
		wi_error_set_errno(errno);

		return false;
	}
	
	fwrite(data->bytes, 1, data->length, fp);
	fclose(fp);
	
	if(!wi_fs_rename_path(fullpath, path)) {
		wi_fs_delete_path(fullpath);
		
		return false;
	}
	
	return true;
}
Пример #19
0
int32_t wi_socket_write_buffer(wi_socket_t *socket, wi_time_interval_t timeout, const void *buffer, size_t length) {
	int		bytes;
	
	if(timeout > 0.0) {
		if(wi_socket_wait_descriptor(socket->sd, timeout, false, true) <= 0)
			return -1;
	}

#ifdef WI_SSL
	if(socket->ssl) {
		bytes = SSL_write(socket->ssl, buffer, length);

		if(bytes < 0) {
			wi_error_set_ssl_error();

			socket->broken = true;
		}
	} else {
#endif
		bytes = write(socket->sd, buffer, length);
		
		if(bytes < 0)
			wi_error_set_errno(errno);
#ifdef WI_SSL
	}
#endif
	
	return bytes;
}
Пример #20
0
wi_boolean_t wi_socket_context_set_ssl_privkey(wi_socket_context_t *context, wi_string_t *path) {
#ifdef WI_SSL
	FILE		*fp;
	
	fp = fopen(wi_string_cstring(path), "r");
	
	if(!fp) {
		wi_error_set_errno(errno);
		
		return false;
	}
		
	context->priv_rsa = PEM_read_RSAPrivateKey(fp, NULL, 0, NULL);
	
	if(!context->priv_rsa)
		wi_error_set_ssl_error();
	
	fclose(fp);
	
	return (context->priv_rsa != NULL);
#else
	wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
	
	return false;
#endif
}
Пример #21
0
void wi_error_set_openssl_ssl_error_with_result(void *ssl, int result) {
	wi_string_t		*string;
	int				code;
	
	code = SSL_get_error(ssl, result);
	
	if(code == SSL_ERROR_SYSCALL) {
		if(ERR_peek_error() == 0) {
			if(result == 0)
				wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
			else
				wi_error_set_errno(errno);
		} else {
			wi_error_set_openssl_error();
		}
	}
	else if(code == SSL_ERROR_SSL) {
		wi_error_set_openssl_error();
	} else {
		switch(code) {
			case SSL_ERROR_NONE:
				string = WI_STR("SSL: No error");
				break;

			case SSL_ERROR_ZERO_RETURN:
				string = WI_STR("SSL: Zero return");
				break;
				
			case SSL_ERROR_WANT_READ:
				string = WI_STR("SSL: Want read");
				break;
				
			case SSL_ERROR_WANT_WRITE:
				string = WI_STR("SSL: Want write");
				break;
				
			case SSL_ERROR_WANT_CONNECT:
				string = WI_STR("SSL: Want connect");
				break;
				
			case SSL_ERROR_WANT_ACCEPT:
				string = WI_STR("SSL: Want accept");
				break;
				
			case SSL_ERROR_WANT_X509_LOOKUP:
				string = WI_STR("SSL: Want X509 lookup");
				break;
			
			default:
				string = NULL;
				break;
		}
		
		wi_error_set_error_with_string(WI_ERROR_DOMAIN_OPENSSL_SSL, code, string);
	}
	
	ERR_clear_error();
}
Пример #22
0
void wi_error_set_openssl_ssl_error_with_result(void *ssl, int result) {
	wi_error_t		*error;
	int				code;
	
	code = SSL_get_error(ssl, result);
	
	if(code == SSL_ERROR_SYSCALL) {
		if(ERR_peek_error() == 0) {
			if(result == 0)
				wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
			else
				wi_error_set_errno(errno);
		} else {
			wi_error_set_openssl_error();
		}
	}
	else if(code == SSL_ERROR_SSL) {
		wi_error_set_openssl_error();
	} else {
		error = _wi_error_get_error();
		error->domain = WI_ERROR_DOMAIN_OPENSSL_SSL;
		error->code = code;

		wi_release(error->string);

		switch(error->code) {
			case SSL_ERROR_NONE:
				error->string = wi_retain(WI_STR("SSL: No error"));
				break;

			case SSL_ERROR_ZERO_RETURN:
				error->string = wi_retain(WI_STR("SSL: Zero return"));
				break;
				
			case SSL_ERROR_WANT_READ:
				error->string = wi_retain(WI_STR("SSL: Want read"));
				break;
				
			case SSL_ERROR_WANT_WRITE:
				error->string = wi_retain(WI_STR("SSL: Want write"));
				break;
				
			case SSL_ERROR_WANT_CONNECT:
				error->string = wi_retain(WI_STR("SSL: Want connect"));
				break;
				
			case SSL_ERROR_WANT_ACCEPT:
				error->string = wi_retain(WI_STR("SSL: Want accept"));
				break;
				
			case SSL_ERROR_WANT_X509_LOOKUP:
				error->string = wi_retain(WI_STR("SSL: Want X509 lookup"));
				break;
		}
	}
	
	ERR_clear_error();
}
Пример #23
0
wi_boolean_t wi_file_statfs(wi_string_t *path, wi_file_statfs_t *sfp) {
#ifdef HAVE_STATVFS
	struct statvfs		sfvb;

	if(statvfs(wi_string_cstring(path), &sfvb) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}

	sfp->f_bsize	= sfvb.f_bsize;
	sfp->f_frsize	= sfvb.f_frsize;
	sfp->f_blocks	= sfvb.f_blocks;
	sfp->f_bfree	= sfvb.f_bfree;
	sfp->f_bavail	= sfvb.f_bavail;
	sfp->f_files	= sfvb.f_files;
	sfp->f_ffree	= sfvb.f_ffree;
	sfp->f_favail	= sfvb.f_favail;
	sfp->f_fsid		= sfvb.f_fsid;
	sfp->f_flag		= sfvb.f_flag;
	sfp->f_namemax	= sfvb.f_namemax;
#else
	struct statfs		sfb;

	if(statfs(wi_string_cstring(path), &sfb) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}

	sfp->f_bsize	= sfb.f_iosize;
	sfp->f_frsize	= sfb.f_bsize;
	sfp->f_blocks	= sfb.f_blocks;
	sfp->f_bfree	= sfb.f_bfree;
	sfp->f_bavail	= sfb.f_bavail;
	sfp->f_files	= sfb.f_files;
	sfp->f_ffree	= sfb.f_ffree;
	sfp->f_favail	= sfb.f_ffree;
	sfp->f_fsid		= sfb.f_fsid.val[0];
	sfp->f_flag		= 0;
	sfp->f_namemax	= 0;
#endif
	
	return true;
}
Пример #24
0
wi_boolean_t wi_file_lstat(wi_string_t *path, struct stat *sp) {
	if(lstat(wi_string_cstring(path), sp) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}
Пример #25
0
static wi_boolean_t _wi_file_delete_file(wi_string_t *path) {
	if(unlink(wi_string_cstring(path)) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}
Пример #26
0
wi_boolean_t wi_file_clear(wi_string_t *path) {
	if(truncate(wi_string_cstring(path), 0) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}
Пример #27
0
wi_boolean_t wi_file_rename(wi_string_t *path, wi_string_t *newpath) {
	if(rename(wi_string_cstring(path), wi_string_cstring(newpath)) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}
Пример #28
0
wi_boolean_t wi_process_set_hostname(wi_process_t *process, wi_string_t *hostname) {
	if(sethostname((char *) wi_string_cstring(hostname), (int)wi_string_length(hostname))) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}
Пример #29
0
wi_boolean_t wi_file_create_directory(wi_string_t *path, mode_t mode) {
	if(mkdir(wi_string_cstring(path), mode) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}
Пример #30
0
static wi_boolean_t _wi_socket_set_option_int(wi_socket_t *socket, int level, int name, int option) {
	if(setsockopt(socket->sd, level, name, &option, sizeof(option)) < 0) {
		wi_error_set_errno(errno);
		
		return false;
	}
	
	return true;
}