├── README.md ├── TODO ├── addr.go ├── callback.go ├── error.go ├── example ├── gui.go ├── tcp.go ├── timer.go └── udp.go ├── idle.go ├── loop.go ├── memory.go ├── pipe.go ├── process.go ├── tcp.go ├── timer.go └── udp.go /README.md: -------------------------------------------------------------------------------- 1 | # go-uv 2 | 3 | Go binding for libuv 4 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | FINISHED 2 | uv_loop_t* uv_loop_new(void); 3 | void uv_loop_delete(uv_loop_t*); 4 | uv_loop_t* uv_default_loop(void); 5 | int uv_run (uv_loop_t*); 6 | void uv_ref(uv_loop_t*); 7 | void uv_unref(uv_loop_t*); 8 | void uv_update_time(uv_loop_t*); 9 | int64_t uv_now(uv_loop_t*); 10 | uv_err_t uv_last_error(uv_loop_t*); 11 | const char* uv_strerror(uv_err_t err); 12 | const char* uv_err_name(uv_err_t err); 13 | int uv_is_active(uv_handle_t* handle); 14 | void uv_close(uv_handle_t* handle, uv_close_cb close_cb); 15 | int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb); 16 | int uv_accept(uv_stream_t* server, uv_stream_t* client); 17 | int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, 18 | int uv_read_stop(uv_stream_t*); 19 | int uv_write(uv_write_t* req, uv_stream_t* handle, 20 | int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle); 21 | int uv_tcp_nodelay(uv_tcp_t* handle, int enable); 22 | int uv_tcp_keepalive(uv_tcp_t* handle, int enable, 23 | int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); 24 | int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in); 25 | int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6); 26 | int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, 27 | int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle, 28 | int uv_timer_init(uv_loop_t*, uv_timer_t* timer); 29 | int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, 30 | int uv_timer_stop(uv_timer_t* timer); 31 | int uv_timer_again(uv_timer_t* timer); 32 | void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat); 33 | int64_t uv_timer_get_repeat(uv_timer_t* timer); 34 | int uv_udp_init(uv_loop_t*, uv_udp_t* handle); 35 | int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, 36 | int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, 37 | int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, 38 | int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, 39 | int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, 40 | int uv_udp_recv_stop(uv_udp_t* handle); 41 | int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, 42 | struct sockaddr_in uv_ip4_addr(const char* ip, int port); 43 | struct sockaddr_in6 uv_ip6_addr(const char* ip, int port); 44 | int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size); 45 | int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size); 46 | int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, 47 | int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, 48 | int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, 49 | int uv_idle_init(uv_loop_t*, uv_idle_t* idle); 50 | int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb); 51 | int uv_idle_stop(uv_idle_t* idle); 52 | uint64_t uv_get_free_memory(void); 53 | uint64_t uv_get_total_memory(void); 54 | int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc); 55 | void uv_pipe_open(uv_pipe_t*, uv_file file); 56 | int uv_pipe_bind(uv_pipe_t* handle, const char* name); 57 | void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, 58 | 59 | NOT FINISHED 60 | int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb, 61 | int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], 62 | int uv_udp_set_membership(uv_udp_t* handle, 63 | int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); 64 | int uv_tty_set_mode(uv_tty_t*, int mode); 65 | void uv_tty_reset_mode(void); 66 | int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); 67 | uv_handle_type uv_guess_handle(uv_file file); 68 | int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare); 69 | int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb); 70 | int uv_prepare_stop(uv_prepare_t* prepare); 71 | int uv_check_init(uv_loop_t*, uv_check_t* check); 72 | int uv_check_start(uv_check_t* check, uv_check_cb cb); 73 | int uv_check_stop(uv_check_t* check); 74 | int uv_async_init(uv_loop_t*, uv_async_t* async, 75 | int uv_async_send(uv_async_t* async); 76 | int uv_ares_init_options(uv_loop_t*, 77 | void uv_ares_destroy(uv_loop_t*, ares_channel channel); 78 | int uv_getaddrinfo(uv_loop_t*, uv_getaddrinfo_t* handle, 79 | void uv_freeaddrinfo(struct addrinfo* ai); 80 | int uv_spawn(uv_loop_t*, uv_process_t*, 81 | int uv_process_kill(uv_process_t*, int signum); 82 | uv_err_t uv_kill(int pid, int signum); 83 | int uv_queue_work(uv_loop_t* loop, uv_work_t* req, 84 | void uv_fs_req_cleanup(uv_fs_t* req); 85 | int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, 86 | int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, 87 | int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, 88 | int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, 89 | int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, 90 | int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, 91 | int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, 92 | int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, 93 | int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, 94 | int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, 95 | int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, 96 | int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, 97 | int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, 98 | int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, 99 | int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, 100 | int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, 101 | int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, 102 | int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, 103 | int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, 104 | int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, 105 | int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, 106 | int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, 107 | int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, 108 | int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, 109 | int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, 110 | void uv_loadavg(double avg[3]); 111 | int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, 112 | int uv_exepath(char* buffer, size_t* size); 113 | extern uint64_t uv_hrtime(void); 114 | uv_err_t uv_dlopen(const char* filename, uv_lib_t* library); 115 | uv_err_t uv_dlclose(uv_lib_t library); 116 | uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr); 117 | int uv_mutex_init(uv_mutex_t* handle); 118 | void uv_mutex_destroy(uv_mutex_t* handle); 119 | void uv_mutex_lock(uv_mutex_t* handle); 120 | int uv_mutex_trylock(uv_mutex_t* handle); 121 | void uv_mutex_unlock(uv_mutex_t* handle); 122 | int uv_rwlock_init(uv_rwlock_t* rwlock); 123 | void uv_rwlock_destroy(uv_rwlock_t* rwlock); 124 | void uv_rwlock_rdlock(uv_rwlock_t* rwlock); 125 | int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock); 126 | void uv_rwlock_rdunlock(uv_rwlock_t* rwlock); 127 | void uv_rwlock_wrlock(uv_rwlock_t* rwlock); 128 | int uv_rwlock_trywrlock(uv_rwlock_t* rwlock); 129 | void uv_rwlock_wrunlock(uv_rwlock_t* rwlock); 130 | int uv_thread_create(uv_thread_t *tid, 131 | int uv_thread_join(uv_thread_t *tid); 132 | 133 | PENDING 134 | uv_buf_t uv_buf_init(char* base, size_t len); 135 | size_t uv_strlcpy(char* dst, const char* src, size_t size); 136 | size_t uv_strlcat(char* dst, const char* src, size_t size); 137 | -------------------------------------------------------------------------------- /addr.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | #include 6 | */ 7 | import "C" 8 | import "unsafe" 9 | import "errors" 10 | 11 | type SockaddrIn interface { 12 | Name() (string, error) 13 | } 14 | 15 | type Sockaddr struct { 16 | sa C.struct_sockaddr 17 | } 18 | 19 | type SockaddrIn4 struct { 20 | sa C.struct_sockaddr_in 21 | } 22 | 23 | type SockaddrIn6 struct { 24 | sa C.struct_sockaddr_in6 25 | } 26 | 27 | func Ip4Addr(host string, port uint16) (SockaddrIn, error) { 28 | phost := C.CString(host) 29 | defer C.free(unsafe.Pointer(phost)) 30 | var addr C.struct_sockaddr_in 31 | addr = C.uv_ip4_addr(phost, C.int(port)) 32 | return &SockaddrIn4 {addr}, nil 33 | } 34 | 35 | func Ip6Addr(host string, port uint16) (SockaddrIn, error) { 36 | phost := C.CString(host) 37 | defer C.free(unsafe.Pointer(phost)) 38 | var addr C.struct_sockaddr_in6 39 | addr = C.uv_ip6_addr(phost, C.int(port)) 40 | return &SockaddrIn6 {addr}, nil 41 | } 42 | 43 | func (sa *SockaddrIn4) Name() (name string, err error) { 44 | b := make([]byte, 256) 45 | r := C.uv_ip4_name(&sa.sa, (*C.char)(unsafe.Pointer(&b[0])), C.size_t(len(b))); 46 | if r != 0 { 47 | var error C.uv_err_t 48 | error.code = C.uv_err_code(r) 49 | return "", errors.New(C.GoString(C.uv_strerror(error))) 50 | } 51 | return string(b), nil 52 | } 53 | 54 | func (sa *SockaddrIn6) Name() (name string, err error) { 55 | b := make([]byte, 256) 56 | r := C.uv_ip6_name(&sa.sa, (*C.char)(unsafe.Pointer(&b[0])), C.size_t(len(b))); 57 | if r != 0 { 58 | var error C.uv_err_t 59 | error.code = C.uv_err_code(r) 60 | return "", errors.New(C.GoString(C.uv_strerror(error))) 61 | } 62 | return string(b), nil 63 | } 64 | -------------------------------------------------------------------------------- /callback.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | #include 6 | 7 | extern void __uv_connect_cb(uv_connect_t* req, int status); 8 | extern void __uv_connection_cb(uv_stream_t* stream, int status); 9 | extern void __uv_write_cb(uv_write_t* req, int status); 10 | extern void __uv_read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf); 11 | extern void __uv_udp_recv_cb(uv_udp_t* handle, ssize_t nread, uv_buf_t buf, struct sockaddr* addr, unsigned flags); 12 | extern void __uv_udp_send_cb(uv_udp_send_t* req, int status); 13 | extern void __uv_timer_cb(uv_timer_t* timer, int status); 14 | extern void __uv_idle_cb(uv_idle_t* handle, int status); 15 | extern void __uv_close_cb(uv_handle_t* handle); 16 | extern void __uv_shutdown_cb(uv_shutdown_t* req, int status); 17 | extern void __uv_exit_cb(uv_process_t* process, int exit_status, int term_signal); 18 | 19 | static uv_buf_t _uv_alloc_cb(uv_handle_t* handle, size_t suggested_size) { 20 | return uv_buf_init(malloc(suggested_size), suggested_size); 21 | } 22 | 23 | static int _uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], int bufcnt, struct sockaddr_in addr) { 24 | return uv_udp_send(req, handle, bufs, bufcnt, addr, __uv_udp_send_cb); 25 | } 26 | 27 | static int _uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], int bufcnt, struct sockaddr_in6 addr) { 28 | return uv_udp_send6(req, handle, bufs, bufcnt, addr, __uv_udp_send_cb); 29 | } 30 | 31 | static int _uv_udp_recv_start(uv_udp_t* udp) { 32 | return uv_udp_recv_start(udp, _uv_alloc_cb, __uv_udp_recv_cb); 33 | } 34 | 35 | static int _uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, struct sockaddr_in address) { 36 | return uv_tcp_connect(req, handle, address, __uv_connect_cb); 37 | } 38 | 39 | static int _uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle, struct sockaddr_in6 address) { 40 | return uv_tcp_connect6(req, handle, address, __uv_connect_cb); 41 | } 42 | 43 | static void _uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name) { 44 | uv_pipe_connect(req, handle, name, __uv_connect_cb); 45 | } 46 | 47 | static int _uv_listen(uv_stream_t* stream, int backlog) { 48 | return uv_listen(stream, backlog, __uv_connection_cb); 49 | } 50 | 51 | static int _uv_read_start(uv_stream_t* stream) { 52 | return uv_read_start(stream, _uv_alloc_cb, __uv_read_cb); 53 | } 54 | 55 | static int _uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt) { 56 | return uv_write(req, handle, bufs, bufcnt, __uv_write_cb); 57 | } 58 | 59 | static void _uv_close(uv_handle_t* handle) { 60 | uv_close(handle, __uv_close_cb); 61 | } 62 | 63 | static int _uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle) { 64 | return uv_shutdown(req, handle, __uv_shutdown_cb); 65 | } 66 | 67 | static int _uv_timer_start(uv_timer_t* timer, int64_t timeout, int64_t repeat) { 68 | return uv_timer_start(timer, __uv_timer_cb, timeout, repeat); 69 | } 70 | 71 | static int _uv_idle_start(uv_idle_t* idle) { 72 | return uv_idle_start(idle, __uv_idle_cb); 73 | } 74 | 75 | static int _uv_spawn(uv_loop_t* loop, uv_process_t* process, uv_process_options_t options) { 76 | options.exit_cb = __uv_exit_cb; 77 | return uv_spawn(loop, process, options); 78 | } 79 | 80 | #define UV_SIZEOF_SOCKADDR_IN ((int)sizeof(struct sockaddr_in)) 81 | 82 | #cgo darwin LDFLAGS: -luv 83 | #cgo linux LDFLAGS: -ldl -luv -lpthread -lrt -lm 84 | #cgo windows LDFLAGS: -luv.dll -lws2_32 -lws2_32 -lpsapi -liphlpapi 85 | */ 86 | import "C" 87 | import "unsafe" 88 | 89 | type Request struct { 90 | r *C.uv_req_t 91 | Handle *Handle 92 | } 93 | 94 | type Handle struct { 95 | h *C.uv_handle_t 96 | Data interface{} 97 | } 98 | 99 | type callback_info struct { 100 | connection_cb func(*Handle, int) 101 | connect_cb func(*Request, int) 102 | read_cb func(*Handle, []byte) 103 | udp_recv_cb func(*Handle, []byte, SockaddrIn, uint) 104 | write_cb func(*Request, int) 105 | udp_send_cb func(*Request, int) 106 | close_cb func(*Handle) 107 | shutdown_cb func(*Request, int) 108 | timer_cb func(*Handle, int) 109 | idle_cb func(*Handle, int) 110 | exit_cb func(*Handle, int, int) 111 | data interface{} 112 | } 113 | 114 | func (handle *Handle) Close(cb func(*Handle)) { 115 | cbi := (*callback_info)(handle.h.data) 116 | cbi.close_cb = cb 117 | uv_close(handle.h) 118 | } 119 | 120 | func (handle *Handle) IsActive() bool { 121 | return uv_is_active(handle.h) 122 | } 123 | 124 | func uv_tcp_bind(tcp *C.uv_tcp_t, sa C.struct_sockaddr_in) int { 125 | return int(C.uv_tcp_bind(tcp, sa)) 126 | } 127 | 128 | func uv_tcp_bind6(tcp *C.uv_tcp_t, sa C.struct_sockaddr_in6) int { 129 | return int(C.uv_tcp_bind6(tcp, sa)) 130 | } 131 | 132 | func uv_tcp_connect(tcp *C.uv_tcp_t, sa4 C.struct_sockaddr_in) int { 133 | var req C.uv_connect_t 134 | return int(C._uv_tcp_connect(&req, tcp, sa4)) 135 | } 136 | 137 | func uv_tcp_connect6(tcp *C.uv_tcp_t, sa6 C.struct_sockaddr_in6) int { 138 | var req C.uv_connect_t 139 | return int(C._uv_tcp_connect6(&req, tcp, sa6)) 140 | } 141 | 142 | func uv_pipe_connect(pipe *C.uv_pipe_t, name string) { 143 | pname := C.CString(name) 144 | defer C.free(unsafe.Pointer(pname)) 145 | var req C.uv_connect_t 146 | C._uv_pipe_connect(&req, pipe, pname) 147 | } 148 | 149 | func uv_pipe_bind(pipe *C.uv_pipe_t, name string) int { 150 | pname := C.CString(name) 151 | defer C.free(unsafe.Pointer(pname)) 152 | return int(C.uv_pipe_bind(pipe, pname)) 153 | } 154 | 155 | func uv_close(handle *C.uv_handle_t) { 156 | C._uv_close(handle) 157 | } 158 | 159 | func uv_is_active(handle *C.uv_handle_t) bool { 160 | if C.uv_is_active(handle) != 0 { 161 | return true 162 | } 163 | return false 164 | } 165 | 166 | func uv_listen(stream *C.uv_stream_t, backlog int) int { 167 | return int(C._uv_listen(stream, C.int(backlog))) 168 | } 169 | 170 | func uv_accept(stream *C.uv_stream_t, client *C.uv_stream_t) int { 171 | return int(C.uv_accept(stream, client)) 172 | } 173 | 174 | func uv_shutdown(stream *C.uv_stream_t) int { 175 | var req C.uv_shutdown_t 176 | return int(C._uv_shutdown(&req, stream)) 177 | } 178 | 179 | func uv_write(stream *C.uv_stream_t, buf *C.uv_buf_t, bufcnt int) int { 180 | var req C.uv_write_t 181 | return int(C._uv_write(&req, stream, buf, C.int(bufcnt))) 182 | } 183 | 184 | func uv_udp_bind(udp *C.uv_udp_t, sa4 C.struct_sockaddr_in, flags uint) int { 185 | return int(C.uv_udp_bind(udp, sa4, C.uint(flags))) 186 | } 187 | 188 | func uv_udp_bind6(udp *C.uv_udp_t, sa6 C.struct_sockaddr_in6, flags uint) int { 189 | return int(C.uv_udp_bind6(udp, sa6, C.uint(flags))) 190 | } 191 | 192 | func uv_udp_send(udp *C.uv_udp_t, buf *C.uv_buf_t, bufcnt int, sa4 C.struct_sockaddr_in) int { 193 | var req C.uv_udp_send_t 194 | return int(C._uv_udp_send(&req, udp, buf, C.int(bufcnt), sa4)) 195 | } 196 | 197 | func uv_udp_send6(udp *C.uv_udp_t, buf *C.uv_buf_t, bufcnt int, sa6 C.struct_sockaddr_in6) int { 198 | var req C.uv_udp_send_t 199 | return int(C._uv_udp_send6(&req, udp, buf, C.int(bufcnt), sa6)) 200 | } 201 | 202 | func uv_read_start(stream *C.uv_stream_t) int { 203 | return int(C._uv_read_start(stream)) 204 | } 205 | 206 | func uv_read_stop(stream *C.uv_stream_t) int { 207 | return int(C.uv_read_stop(stream)) 208 | } 209 | 210 | func uv_udp_recv_start(udp *C.uv_udp_t) int { 211 | return int(C._uv_udp_recv_start(udp)) 212 | } 213 | 214 | func uv_udp_recv_stop(udp *C.uv_udp_t) int { 215 | return int(C.uv_udp_recv_stop(udp)) 216 | } 217 | 218 | func uv_buf_init(b []byte) C.uv_buf_t { 219 | return C.uv_buf_init((*C.char)(unsafe.Pointer(&b[0])), C.uint(len(b))) 220 | } 221 | 222 | func uv_tcp_nodelay(tcp *C.uv_tcp_t, enable bool) int { 223 | var v C.int 224 | if enable { 225 | v = 1 226 | } 227 | return int(C.uv_tcp_nodelay(tcp, v)) 228 | } 229 | 230 | func uv_tcp_keepalive(tcp *C.uv_tcp_t, enable bool, delay uint) int { 231 | var v C.int 232 | if enable { 233 | v = 1 234 | } 235 | return int(C.uv_tcp_keepalive(tcp, v, C.uint(delay))) 236 | } 237 | 238 | func uv_tcp_simultaneous_accepts(tcp *C.uv_tcp_t, enable bool) int { 239 | var v C.int 240 | if enable { 241 | v = 1 242 | } 243 | return int(C.uv_tcp_simultaneous_accepts(tcp, v)) 244 | } 245 | 246 | func uv_tcp_getsockname(tcp *C.uv_tcp_t, sa *C.struct_sockaddr) int { 247 | l := C.UV_SIZEOF_SOCKADDR_IN 248 | return int(C.uv_tcp_getsockname(tcp, sa, (*C.int)(unsafe.Pointer(&l)))) 249 | } 250 | 251 | func uv_tcp_getpeername(tcp *C.uv_tcp_t, sa *C.struct_sockaddr) int { 252 | l := C.UV_SIZEOF_SOCKADDR_IN 253 | return int(C.uv_tcp_getpeername(tcp, sa, (*C.int)(unsafe.Pointer(&l)))) 254 | } 255 | 256 | func uv_udp_getsockname(udp *C.uv_udp_t, sa *C.struct_sockaddr) int { 257 | l := C.UV_SIZEOF_SOCKADDR_IN 258 | return int(C.uv_udp_getsockname(udp, sa, (*C.int)(unsafe.Pointer(&l)))) 259 | } 260 | 261 | func uv_timer_start(timer *C.uv_timer_t, timeout int64, repeat int64) int { 262 | return int(C._uv_timer_start(timer, C.int64_t(timeout), C.int64_t(repeat))) 263 | } 264 | 265 | func uv_idle_start(idle *C.uv_idle_t) int { 266 | return int(C._uv_idle_start(idle)) 267 | } 268 | 269 | func uv_spawn(loop *C.uv_loop_t, process *C.uv_process_t, options C.uv_process_options_t) int { 270 | return int(C._uv_spawn(loop, process, options)) 271 | } 272 | 273 | //export __uv_connect_cb 274 | func __uv_connect_cb(c *C.uv_connect_t, status C.int) { 275 | cbi := (*callback_info)(c.handle.data) 276 | if cbi.connect_cb != nil { 277 | cbi.connect_cb(&Request{ 278 | (*C.uv_req_t)(unsafe.Pointer(c)), 279 | &Handle{ 280 | (*C.uv_handle_t)(unsafe.Pointer(c.handle)), 281 | cbi.data}}, int(status)) 282 | } 283 | } 284 | 285 | //export __uv_connection_cb 286 | func __uv_connection_cb(s *C.uv_stream_t, status C.int) { 287 | cbi := (*callback_info)(s.data) 288 | if cbi.connection_cb != nil { 289 | cbi.connection_cb(&Handle{(*C.uv_handle_t)(unsafe.Pointer(s)), cbi.data}, int(status)) 290 | } 291 | } 292 | 293 | //export __uv_read_cb 294 | func __uv_read_cb(s *C.uv_stream_t, nread C.ssize_t, buf C.uv_buf_t) { 295 | cbi := (*callback_info)(s.data) 296 | if cbi.read_cb != nil { 297 | n_read := int(nread) 298 | if n_read < 0 { 299 | cbi.read_cb(&Handle{(*C.uv_handle_t)(unsafe.Pointer(s)), cbi.data}, nil) 300 | } else { 301 | cbi.read_cb(&Handle{(*C.uv_handle_t)(unsafe.Pointer(s)), cbi.data}, (*[1 << 30]byte)(unsafe.Pointer(buf.base))[0:n_read]) 302 | } 303 | } 304 | } 305 | 306 | //export __uv_write_cb 307 | func __uv_write_cb(w *C.uv_write_t, status C.int) { 308 | cbi := (*callback_info)(w.handle.data) 309 | if cbi.write_cb != nil { 310 | cbi.write_cb(&Request{ 311 | (*C.uv_req_t)(unsafe.Pointer(w)), 312 | &Handle{ 313 | (*C.uv_handle_t)(unsafe.Pointer(w.handle)), 314 | cbi.data}}, int(status)) 315 | } 316 | } 317 | 318 | //export __uv_close_cb 319 | func __uv_close_cb(h *C.uv_handle_t) { 320 | cbi := (*callback_info)(h.data) 321 | if cbi.close_cb != nil { 322 | cbi.close_cb(&Handle{h, cbi.data}) 323 | } 324 | } 325 | 326 | //export __uv_shutdown_cb 327 | func __uv_shutdown_cb(s *C.uv_shutdown_t, status C.int) { 328 | cbi := (*callback_info)(s.handle.data) 329 | if cbi.shutdown_cb != nil { 330 | cbi.shutdown_cb(&Request{ 331 | (*C.uv_req_t)(unsafe.Pointer(s)), 332 | &Handle{ 333 | (*C.uv_handle_t)(unsafe.Pointer(s.handle)), 334 | cbi.data}}, int(status)) 335 | } 336 | } 337 | 338 | //export __uv_udp_recv_cb 339 | func __uv_udp_recv_cb(u *C.uv_udp_t, nread C.ssize_t, buf C.uv_buf_t, sa *C.struct_sockaddr, flags C.uint) { 340 | cbi := (*callback_info)(u.data) 341 | if cbi.udp_recv_cb != nil { 342 | psa := &SockaddrIn4{*(*C.struct_sockaddr_in)(unsafe.Pointer(sa))} 343 | n_read := int(nread) 344 | if n_read < 0 { 345 | cbi.udp_recv_cb(&Handle{ 346 | (*C.uv_handle_t)(unsafe.Pointer(u)), cbi.data}, nil, psa, uint(flags)) 347 | } else { 348 | cbi.udp_recv_cb(&Handle{ 349 | (*C.uv_handle_t)(unsafe.Pointer(u)), cbi.data}, (*[1 << 30]byte)(unsafe.Pointer(buf.base))[0:n_read], psa, uint(flags)) 350 | } 351 | } 352 | } 353 | 354 | //export __uv_udp_send_cb 355 | func __uv_udp_send_cb(us *C.uv_udp_send_t, status C.int) { 356 | cbi := (*callback_info)(us.handle.data) 357 | if cbi.udp_send_cb != nil { 358 | cbi.udp_send_cb(&Request{ 359 | (*C.uv_req_t)(unsafe.Pointer(us)), 360 | &Handle{ 361 | (*C.uv_handle_t)(unsafe.Pointer(us.handle)), 362 | cbi.data}}, int(status)) 363 | } 364 | } 365 | 366 | //export __uv_timer_cb 367 | func __uv_timer_cb(t *C.uv_timer_t, status C.int) { 368 | cbi := (*callback_info)(t.data) 369 | if cbi.timer_cb != nil { 370 | cbi.timer_cb(&Handle{ 371 | (*C.uv_handle_t)(unsafe.Pointer(t)), cbi.data}, int(status)) 372 | } 373 | } 374 | 375 | //export __uv_idle_cb 376 | func __uv_idle_cb(i *C.uv_idle_t, status C.int) { 377 | cbi := (*callback_info)(i.data) 378 | if cbi.idle_cb != nil { 379 | cbi.idle_cb(&Handle{ 380 | (*C.uv_handle_t)(unsafe.Pointer(i)), cbi.data}, int(status)) 381 | } 382 | } 383 | 384 | //export __uv_exit_cb 385 | func __uv_exit_cb(pc *C.uv_process_t, exit_status C.int, term_signal C.int) { 386 | cbi := (*callback_info)(pc.data) 387 | if cbi.exit_cb != nil { 388 | cbi.exit_cb(&Handle{ 389 | (*C.uv_handle_t)(unsafe.Pointer(pc)), cbi.data}, int(exit_status), int(term_signal)) 390 | } 391 | } 392 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | 8 | type Error struct { 9 | e int 10 | } 11 | 12 | func (err *Error) String() string { 13 | var error C.uv_err_t 14 | error.code = C.uv_err_code(err.e) 15 | return C.GoString(C.uv_strerror(error)) 16 | } 17 | 18 | func (err *Error) Error() string { 19 | return err.String() 20 | } 21 | 22 | func (err *Error) Name() string { 23 | var error C.uv_err_t 24 | error.code = C.uv_err_code(err.e) 25 | return C.GoString(C.uv_err_name(error)) 26 | } 27 | -------------------------------------------------------------------------------- /example/gui.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mattn/go-uv" 6 | "github.com/mattn/go-gtk/gtk" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | gtk.Init(nil) 12 | window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL) 13 | window.SetTitle("Clock") 14 | vbox := gtk.NewVBox(false, 1) 15 | label := gtk.NewLabel("") 16 | vbox.Add(label) 17 | window.Add(vbox) 18 | window.SetDefaultSize(300, 20) 19 | window.ShowAll() 20 | 21 | timer, _ := uv.TimerInit(nil) 22 | timer.Start(func(h *uv.Handle, status int) { 23 | label.SetLabel(fmt.Sprintf("%v", time.Now())) 24 | }, 1000, 1000) 25 | 26 | idle, _ := uv.IdleInit(nil) 27 | idle.Start(func(h *uv.Handle, status int) { 28 | gtk.MainIterationDo(false) 29 | }) 30 | 31 | window.Connect("destroy", func() { 32 | timer.Close(nil) 33 | idle.Close(nil) 34 | }) 35 | 36 | uv.DefaultLoop().Run() 37 | } 38 | -------------------------------------------------------------------------------- /example/tcp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/mattn/go-uv" 5 | "log" 6 | ) 7 | 8 | func main() { 9 | tcp, _ := uv.TcpInit(nil) 10 | addr, err := uv.Ip4Addr("0.0.0.0", 8888) 11 | if err != nil { 12 | log.Fatal(err) 13 | } 14 | err = tcp.Bind(addr) 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | tcp.Listen(10, func(h *uv.Handle, status int) { 19 | client, _ := tcp.Accept() 20 | log.Println("server: accept") 21 | line := "" 22 | client.ReadStart(func(h *uv.Handle, data []byte) { 23 | if data == nil { 24 | log.Println("client: closed") 25 | client.Close(nil) 26 | return 27 | } 28 | s := string(data) 29 | print(s) 30 | line += s 31 | if s[len(s)-1] == '\n' { 32 | client.Write([]byte(line), func(r *uv.Request, status int) { 33 | log.Println("client: written") 34 | }) 35 | } 36 | }) 37 | }) 38 | 39 | uv.DefaultLoop().Run() 40 | } 41 | -------------------------------------------------------------------------------- /example/timer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/mattn/go-uv" 5 | "log" 6 | ) 7 | 8 | func main() { 9 | timer, _ := uv.TimerInit(nil) 10 | timer.Start(func(h *uv.Handle, status int) { 11 | log.Println("tick") 12 | }, 1000, 1000) 13 | 14 | uv.Run() 15 | } 16 | -------------------------------------------------------------------------------- /example/udp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/mattn/go-uv" 5 | "log" 6 | ) 7 | 8 | func main() { 9 | udp, _ := uv.UdpInit(nil) 10 | addr, err := uv.Ip4Addr("0.0.0.0", 8888) 11 | if err != nil { 12 | log.Fatal(err) 13 | } 14 | err = udp.Bind(addr, 0) 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | log.Println("udp: start") 19 | udp.RecvStart(func(h *uv.Handle, data []byte, sa uv.SockaddrIn, flags uint) { 20 | log.Println("udp: read", string(data)) 21 | udp.Send(data, sa, func(r *uv.Request, status int) { 22 | log.Println("udp: written") 23 | }) 24 | udp.Close(func(h *uv.Handle) { 25 | log.Println("udp: closed") 26 | }) 27 | }) 28 | 29 | uv.DefaultLoop().Run() 30 | } 31 | -------------------------------------------------------------------------------- /idle.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | import "unsafe" 8 | 9 | type Idle struct { 10 | i *C.uv_idle_t 11 | l *C.uv_loop_t 12 | Handle 13 | } 14 | 15 | func IdleInit(loop *Loop) (idle *Idle, err error) { 16 | var i C.uv_idle_t 17 | 18 | if loop == nil { 19 | loop = DefaultLoop() 20 | } 21 | r := C.uv_idle_init(loop.l, &i) 22 | if r != 0 { 23 | return nil, &Error{int(r)} 24 | } 25 | i.data = unsafe.Pointer(&callback_info{}) 26 | return &Idle{&i, loop.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(&i)), i.data}}, nil 27 | } 28 | 29 | func (idle *Idle) GetLoop() *Loop { 30 | return &Loop{idle.l} 31 | } 32 | 33 | func (idle *Idle) Start(cb func(*Handle, int)) (err error) { 34 | cbi := (*callback_info)(idle.i.data) 35 | cbi.idle_cb = cb 36 | r := uv_idle_start(idle.i) 37 | if r != 0 { 38 | return &Error{r} 39 | } 40 | return nil 41 | } 42 | 43 | func (idle *Idle) Stop() (err error) { 44 | r := C.uv_idle_stop(idle.i) 45 | if r != 0 { 46 | return &Error{int(r)} 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /loop.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | 8 | type Loop struct { 9 | l *C.uv_loop_t 10 | } 11 | 12 | func Run() { 13 | DefaultLoop().Run() 14 | } 15 | 16 | func DefaultLoop() *Loop { 17 | return &Loop{C.uv_default_loop()} 18 | } 19 | 20 | func LoopNew() *Loop { 21 | return &Loop{C.uv_loop_new()} 22 | } 23 | 24 | func (loop *Loop) Delete() { 25 | C.uv_loop_delete(loop.l) 26 | } 27 | 28 | func (loop *Loop) Run() { 29 | C.uv_run(loop.l, C.UV_RUN_DEFAULT) 30 | } 31 | 32 | func (loop *Loop) RunOnce() { 33 | C.uv_run(loop.l, C.UV_RUN_ONCE) 34 | } 35 | 36 | func (loop *Loop) UpdateTime() { 37 | C.uv_update_time(loop.l) 38 | } 39 | 40 | func (loop *Loop) Now() int64 { 41 | return int64(C.uv_now(loop.l)) 42 | } 43 | -------------------------------------------------------------------------------- /memory.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | 8 | func GetFreeMemory() uint64 { 9 | return uint64(C.uv_get_free_memory()) 10 | } 11 | 12 | func GetTotalMemory() uint64 { 13 | return uint64(C.uv_get_total_memory()) 14 | } 15 | -------------------------------------------------------------------------------- /pipe.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | import "unsafe" 8 | 9 | type Pipe struct { 10 | p *C.uv_pipe_t 11 | l *C.uv_loop_t 12 | Handle 13 | } 14 | 15 | func PipeInit(loop *Loop, ipc int) (pipe *Pipe, err error) { 16 | var p C.uv_pipe_t 17 | 18 | if loop == nil { 19 | loop = DefaultLoop() 20 | } 21 | r := C.uv_pipe_init(loop.l, &p, C.int(ipc)) 22 | if r != 0 { 23 | return nil, &Error{int(r)} 24 | } 25 | p.data = unsafe.Pointer(&callback_info{}) 26 | return &Pipe{&p, loop.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(&p)), p.data}}, nil 27 | } 28 | 29 | func (pipe *Pipe) GetLoop() *Loop { 30 | return &Loop{pipe.l} 31 | } 32 | 33 | func (pipe *Pipe) Open(name string) (err error) { 34 | r := uv_pipe_bind(pipe.p, name) 35 | if r != 0 { 36 | return &Error{r} 37 | } 38 | return nil 39 | } 40 | 41 | func (pipe *Pipe) Bind(name string) (err error) { 42 | r := uv_pipe_bind(pipe.p, name) 43 | if r != 0 { 44 | return &Error{r} 45 | } 46 | return nil 47 | } 48 | 49 | func (pipe *Pipe) Listen(backlog int, cb func(*Handle, int)) (err error) { 50 | cbi := (*callback_info)(pipe.p.data) 51 | cbi.connection_cb = cb 52 | r := uv_listen((*C.uv_stream_t)(unsafe.Pointer(pipe.p)), backlog) 53 | if r != 0 { 54 | return &Error{r} 55 | } 56 | return nil 57 | } 58 | 59 | func (pipe *Pipe) Connect(name string, cb func(*Request, int)) (err error) { 60 | cbi := (*callback_info)(pipe.p.data) 61 | cbi.connect_cb = cb 62 | uv_pipe_connect(pipe.p, name) 63 | // TODO: error 64 | return nil 65 | } 66 | 67 | func (pipe *Pipe) Accept() (client *Pipe, err error) { 68 | c, err := PipeInit(pipe.GetLoop(), 0) 69 | if err != nil { 70 | return nil, err 71 | } 72 | r := uv_accept((*C.uv_stream_t)(unsafe.Pointer(pipe.p)), (*C.uv_stream_t)(unsafe.Pointer(c.p))) 73 | if r != 0 { 74 | return nil, &Error{r} 75 | } 76 | return &Pipe{c.p, pipe.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(c.p)), c.p.data}}, nil 77 | } 78 | 79 | func (pipe *Pipe) ReadStart(cb func(*Handle, []byte)) (err error) { 80 | cbi := (*callback_info)(pipe.p.data) 81 | cbi.read_cb = cb 82 | r := uv_read_start((*C.uv_stream_t)(unsafe.Pointer(pipe.p))) 83 | if r != 0 { 84 | return &Error{r} 85 | } 86 | return nil 87 | } 88 | 89 | func (pipe *Pipe) ReadStop() (err error) { 90 | r := uv_read_stop((*C.uv_stream_t)(unsafe.Pointer(pipe.p))) 91 | if r != 0 { 92 | return &Error{r} 93 | } 94 | return nil 95 | } 96 | 97 | func (pipe *Pipe) Write(b []byte, cb func(*Request, int)) (err error) { 98 | cbi := (*callback_info)(pipe.p.data) 99 | cbi.write_cb = cb 100 | buf := C.uv_buf_init((*C.char)(unsafe.Pointer(&b[0])), C.uint(len(b))) 101 | r := uv_write((*C.uv_stream_t)(unsafe.Pointer(pipe.p)), &buf, 1) 102 | if r != 0 { 103 | return &Error{r} 104 | } 105 | return nil 106 | } 107 | 108 | func (pipe *Pipe) Shutdown(cb func(*Request, int)) { 109 | cbi := (*callback_info)(pipe.p.data) 110 | cbi.shutdown_cb = cb 111 | uv_shutdown((*C.uv_stream_t)(unsafe.Pointer(pipe.p))) 112 | } 113 | -------------------------------------------------------------------------------- /process.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | #include 6 | */ 7 | import "C" 8 | import "unsafe" 9 | 10 | type ProcessOptions struct { 11 | Exit_cb func(*Handle, int, int) 12 | File string 13 | Args []string 14 | Env []string 15 | Cwd string 16 | } 17 | 18 | func Spawn(loop *Loop, options ProcessOptions) (err error) { 19 | if loop == nil { 20 | loop = DefaultLoop() 21 | } 22 | 23 | var opt C.uv_process_options_t 24 | defer func() { 25 | /* 26 | C.free(unsafe.Pointer(opt.file)) 27 | if len(options.Args) > 0 { 28 | for n := 0; n < len(options.Args); n++ { 29 | C.free(unsafe.Pointer(((*[1<<24]*C.char)(unsafe.Pointer(&opt.args)))[n])) 30 | } 31 | C.free(unsafe.Pointer(opt.args)) 32 | } 33 | if len(options.Env) > 0 { 34 | for n := 0; n < len(options.Env); n++ { 35 | C.free(unsafe.Pointer(((*[1<<24]*C.char)(unsafe.Pointer(&opt.env)))[n])) 36 | } 37 | C.free(unsafe.Pointer(opt.env)) 38 | } 39 | C.free(unsafe.Pointer(opt.cwd)) 40 | */ 41 | }() 42 | if len(options.File) > 0 { 43 | opt.file = C.CString(options.File) 44 | } 45 | if len(options.Args) > 0 { 46 | opt.args = (**C.char)(C.malloc(C.size_t(4 * (len(options.Args)+1)))) 47 | for n := 0; n < len(options.Args); n++ { 48 | ((*[1<<24]*C.char)(unsafe.Pointer(&opt.args)))[n] = C.CString(options.Args[n]) 49 | } 50 | ((*[1<<24]*C.char)(unsafe.Pointer(&opt.args)))[len(options.Args)] = nil 51 | } 52 | if len(options.Env) > 0 { 53 | opt.env = (**C.char)(C.malloc(C.size_t(4 * (len(options.Env)+1)))) 54 | for n := 0; n < len(options.Args); n++ { 55 | ((*[1<<24]*C.char)(unsafe.Pointer(&opt.env)))[n] = C.CString(options.Args[n]) 56 | } 57 | ((*[1<<24]*C.char)(unsafe.Pointer(&opt.env)))[len(options.Args)] = nil 58 | } 59 | if len(options.Cwd) > 0 { 60 | opt.cwd = C.CString(options.Cwd) 61 | } 62 | // TODO: uv_stdio_container_t 63 | 64 | var p C.uv_process_t 65 | p.data = unsafe.Pointer(&callback_info{exit_cb: options.Exit_cb}) 66 | r := uv_spawn(loop.l, &p, opt) 67 | if r != 0 { 68 | return &Error{r} 69 | } 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /tcp.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | import "unsafe" 8 | 9 | type Tcp struct { 10 | t *C.uv_tcp_t 11 | l *C.uv_loop_t 12 | Handle 13 | } 14 | 15 | func TcpInit(loop *Loop) (tcp *Tcp, err error) { 16 | var t C.uv_tcp_t 17 | 18 | if loop == nil { 19 | loop = DefaultLoop() 20 | } 21 | r := C.uv_tcp_init(loop.l, &t) 22 | if r != 0 { 23 | return nil, &Error{int(r)} 24 | } 25 | t.data = unsafe.Pointer(&callback_info{}) 26 | return &Tcp{&t, loop.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(&t)), t.data}}, nil 27 | } 28 | 29 | func (tcp *Tcp) GetLoop() *Loop { 30 | return &Loop{tcp.l} 31 | } 32 | 33 | func (tcp *Tcp) Bind(sa SockaddrIn) (err error) { 34 | var r int 35 | sa4, is_v4 := sa.(*SockaddrIn4) 36 | if is_v4 { 37 | r = uv_tcp_bind(tcp.t, sa4.sa) 38 | } else { 39 | sa6, _ := sa.(*SockaddrIn6) 40 | r = uv_tcp_bind6(tcp.t, sa6.sa) 41 | } 42 | if r != 0 { 43 | return &Error{r} 44 | } 45 | return nil 46 | } 47 | 48 | func (tcp *Tcp) Nodelay(enable bool) (err error) { 49 | r := uv_tcp_nodelay(tcp.t, enable) 50 | if r != 0 { 51 | return &Error{r} 52 | } 53 | return nil 54 | } 55 | 56 | func (tcp *Tcp) Keepalive(enable bool, delay uint) (err error) { 57 | r := uv_tcp_keepalive(tcp.t, enable, delay) 58 | if r != 0 { 59 | return &Error{r} 60 | } 61 | return nil 62 | } 63 | 64 | func (tcp *Tcp) SimultaneousAccepts(enable bool) (err error) { 65 | var v C.int 66 | if enable { 67 | v = 1 68 | } 69 | r := C.uv_tcp_simultaneous_accepts(tcp.t, v) 70 | if r != 0 { 71 | return &Error{int(r)} 72 | } 73 | return nil 74 | } 75 | 76 | func (tcp *Tcp) Connect(sa SockaddrIn, cb func(*Request, int)) (err error) { 77 | cbi := (*callback_info)(tcp.t.data) 78 | cbi.connect_cb = cb 79 | var r int 80 | sa4, is_v4 := sa.(*SockaddrIn4) 81 | if is_v4 { 82 | r = uv_tcp_connect(tcp.t, sa4.sa) 83 | } else { 84 | sa6, is_v6 := sa.(*SockaddrIn6) 85 | if is_v6 { 86 | r = uv_tcp_connect6(tcp.t, sa6.sa) 87 | } 88 | } 89 | if r != 0 { 90 | return &Error{r} 91 | } 92 | return nil 93 | } 94 | 95 | func (tcp *Tcp) Listen(backlog int, cb func(*Handle, int)) (err error) { 96 | cbi := (*callback_info)(tcp.t.data) 97 | cbi.connection_cb = cb 98 | r := uv_listen((*C.uv_stream_t)(unsafe.Pointer(tcp.t)), backlog) 99 | if r != 0 { 100 | return &Error{r} 101 | } 102 | return nil 103 | } 104 | 105 | func (tcp *Tcp) Accept() (client *Tcp, err error) { 106 | c, err := TcpInit(tcp.GetLoop()) 107 | if err != nil { 108 | return nil, err 109 | } 110 | r := uv_accept((*C.uv_stream_t)(unsafe.Pointer(tcp.t)), (*C.uv_stream_t)(unsafe.Pointer(c.t))) 111 | if r != 0 { 112 | return nil, &Error{r} 113 | } 114 | return &Tcp{c.t, tcp.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(c.t)), c.t.data}}, nil 115 | } 116 | 117 | func (tcp *Tcp) ReadStart(cb func(*Handle, []byte)) (err error) { 118 | cbi := (*callback_info)(tcp.t.data) 119 | cbi.read_cb = cb 120 | r := uv_read_start((*C.uv_stream_t)(unsafe.Pointer(tcp.t))) 121 | if r != 0 { 122 | return &Error{r} 123 | } 124 | return nil 125 | } 126 | 127 | func (tcp *Tcp) ReadStop() (err error) { 128 | r := uv_read_stop((*C.uv_stream_t)(unsafe.Pointer(tcp.t))) 129 | if r != 0 { 130 | return &Error{r} 131 | } 132 | return nil 133 | } 134 | 135 | func (tcp *Tcp) Write(b []byte, cb func(*Request, int)) (err error) { 136 | cbi := (*callback_info)(tcp.t.data) 137 | cbi.write_cb = cb 138 | buf := uv_buf_init(b) 139 | r := uv_write((*C.uv_stream_t)(unsafe.Pointer(tcp.t)), &buf, 1) 140 | if r != 0 { 141 | return &Error{r} 142 | } 143 | return nil 144 | } 145 | 146 | func (tcp *Tcp) Shutdown(cb func(*Request, int)) (err error) { 147 | cbi := (*callback_info)(tcp.t.data) 148 | cbi.shutdown_cb = cb 149 | r := uv_shutdown((*C.uv_stream_t)(unsafe.Pointer(tcp.t))) 150 | if r != 0 { 151 | return &Error{r} 152 | } 153 | return nil 154 | } 155 | 156 | func (tcp *Tcp) GetSockname() (sa *Sockaddr, err error) { 157 | var csa C.struct_sockaddr 158 | r := uv_tcp_getsockname(tcp.t, &csa) 159 | if r != 0 { 160 | return nil, &Error{r} 161 | } 162 | return &Sockaddr{csa}, nil 163 | } 164 | 165 | func (tcp *Tcp) GetPeername() (sa *Sockaddr, err error) { 166 | var csa C.struct_sockaddr 167 | r := uv_tcp_getpeername(tcp.t, &csa) 168 | if r != 0 { 169 | return nil, &Error{r} 170 | } 171 | return &Sockaddr{csa}, nil 172 | } 173 | -------------------------------------------------------------------------------- /timer.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | import "unsafe" 8 | 9 | type Timer struct { 10 | t *C.uv_timer_t 11 | l *C.uv_loop_t 12 | Handle 13 | } 14 | 15 | func TimerInit(loop *Loop) (timer *Timer, err error) { 16 | var t C.uv_timer_t 17 | 18 | if loop == nil { 19 | loop = DefaultLoop() 20 | } 21 | r := C.uv_timer_init(loop.l, &t) 22 | if r != 0 { 23 | return nil, &Error{int(r)} 24 | } 25 | t.data = unsafe.Pointer(&callback_info{}) 26 | return &Timer{&t, loop.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(&t)), t.data}}, nil 27 | } 28 | 29 | func (timer *Timer) GetLoop() *Loop { 30 | return &Loop{timer.l} 31 | } 32 | 33 | func (timer *Timer) Start(cb func(*Handle, int), timeout int64, repeat int64) (err error) { 34 | cbi := (*callback_info)(timer.t.data) 35 | cbi.timer_cb = cb 36 | r := uv_timer_start(timer.t, timeout, repeat) 37 | if r != 0 { 38 | return &Error{r} 39 | } 40 | return nil 41 | } 42 | 43 | func (timer *Timer) Stop() (err error) { 44 | r := C.uv_timer_stop(timer.t) 45 | if r != 0 { 46 | return &Error{int(r)} 47 | } 48 | return nil 49 | } 50 | 51 | func (timer *Timer) Again() (err error) { 52 | r := C.uv_timer_again(timer.t) 53 | if r != 0 { 54 | return &Error{int(r)} 55 | } 56 | return nil 57 | } 58 | 59 | func (timer *Timer) SetRepeat(repeat uint64) { 60 | C.uv_timer_set_repeat(timer.t, C.uint64_t(repeat)) 61 | } 62 | 63 | func (timer *Timer) GetRepeat() int64 { 64 | return int64(C.uv_timer_get_repeat(timer.t)) 65 | } 66 | -------------------------------------------------------------------------------- /udp.go: -------------------------------------------------------------------------------- 1 | package uv 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | import "unsafe" 8 | 9 | type Udp struct { 10 | u *C.uv_udp_t 11 | l *C.uv_loop_t 12 | Handle 13 | } 14 | 15 | func UdpInit(loop *Loop) (udp *Udp, err error) { 16 | var u C.uv_udp_t 17 | 18 | if loop == nil { 19 | loop = DefaultLoop() 20 | } 21 | r := C.uv_udp_init(loop.l, &u) 22 | if r != 0 { 23 | return nil, &Error{int(r)} 24 | } 25 | u.data = unsafe.Pointer(&callback_info{}) 26 | return &Udp{&u, loop.l, Handle{(*C.uv_handle_t)(unsafe.Pointer(&u)), u.data}}, nil 27 | } 28 | 29 | func (udp *Udp) GetLoop() *Loop { 30 | return &Loop{udp.l} 31 | } 32 | 33 | func (udp *Udp) Bind(sa SockaddrIn, flags uint) (err error) { 34 | var r int 35 | sa4, is_v4 := sa.(*SockaddrIn4) 36 | if is_v4 { 37 | r = uv_udp_bind(udp.u, sa4.sa, flags) 38 | } else { 39 | sa6, is_v6 := sa.(*SockaddrIn6) 40 | if is_v6 { 41 | r = uv_udp_bind6(udp.u, sa6.sa, flags) 42 | } 43 | } 44 | if r != 0 { 45 | return &Error{r} 46 | } 47 | return nil 48 | } 49 | 50 | func (udp *Udp) RecvStart(cb func(*Handle, []byte, SockaddrIn, uint)) (err error) { 51 | cbi := (*callback_info)(udp.u.data) 52 | cbi.udp_recv_cb = cb 53 | r := uv_udp_recv_start(udp.u) 54 | if r != 0 { 55 | return &Error{r} 56 | } 57 | return nil 58 | } 59 | 60 | func (udp *Udp) RecvStop() (err error) { 61 | r := uv_udp_recv_stop(udp.u) 62 | if r != 0 { 63 | return &Error{r} 64 | } 65 | return nil 66 | } 67 | 68 | func (udp *Udp) Send(b []byte, sa SockaddrIn, cb func(*Request, int)) (err error) { 69 | cbi := (*callback_info)(udp.u.data) 70 | cbi.udp_send_cb = cb 71 | buf := C.uv_buf_init((*C.char)(unsafe.Pointer(&b[0])), C.uint(len(b))) 72 | var r int 73 | sa4, is_v4 := sa.(*SockaddrIn4) 74 | if is_v4 { 75 | r = uv_udp_send(udp.u, &buf, 1, sa4.sa) 76 | } else { 77 | sa6, is_v6 := sa.(*SockaddrIn6) 78 | if is_v6 { 79 | r = uv_udp_send6(udp.u, &buf, 1, sa6.sa) 80 | } 81 | } 82 | if r != 0 { 83 | return &Error{r} 84 | } 85 | return nil 86 | } 87 | 88 | func (udp *Udp) Shutdown(cb func(*Request, int)) { 89 | cbi := (*callback_info)(udp.u.data) 90 | cbi.shutdown_cb = cb 91 | uv_shutdown((*C.uv_stream_t)(unsafe.Pointer(udp.u))) 92 | } 93 | 94 | func (udp *Udp) GetSockname() (sa *Sockaddr, err error) { 95 | var csa C.struct_sockaddr 96 | r := uv_udp_getsockname(udp.u, &csa) 97 | if r != 0 { 98 | return nil, &Error{r} 99 | } 100 | return &Sockaddr{csa}, nil 101 | } 102 | --------------------------------------------------------------------------------