3 static void client_sigwinch_handler(int sig
) {
4 client
.need_resize
= true;
7 static ssize_t
write_all(int fd
, const char *buf
, size_t len
) {
10 ssize_t res
= write(fd
, buf
, len
);
12 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EINTR
)
24 static ssize_t
read_all(int fd
, char *buf
, size_t len
) {
27 ssize_t res
= read(fd
, buf
, len
);
29 if (errno
== EWOULDBLOCK
)
31 if (errno
== EAGAIN
|| errno
== EINTR
)
43 static bool client_send_packet(Packet
*pkt
) {
44 print_packet("client-send:", pkt
);
45 size_t size
= packet_size(pkt
);
46 if (write_all(server
.socket
, (char *)pkt
, size
) != size
) {
48 server
.running
= false;
54 static bool client_recv_packet(Packet
*pkt
) {
55 ssize_t len
= read_all(server
.socket
, (char*)pkt
, packet_header_size());
56 if (len
<= 0 || len
!= packet_header_size() || pkt
->len
== 0)
58 len
= read_all(server
.socket
, pkt
->u
.msg
, pkt
->len
);
59 print_packet("client-recv:", pkt
);
60 if (len
<= 0 || len
!= pkt
->len
)
64 debug("FAILED here\n");
65 server
.running
= false;
69 static void client_clear_screen() {
74 static void client_show_cursor() {
79 static void client_restore_terminal() {
81 tcsetattr(0, TCSADRAIN
, &orig_term
);
85 static int client_mainloop() {
86 client
.need_resize
= true;
87 while (server
.running
) {
90 FD_SET(STDIN_FILENO
, &fds
);
91 FD_SET(server
.socket
, &fds
);
93 if (client
.need_resize
) {
95 if (ioctl(0, TIOCGWINSZ
, &ws
) != -1) {
101 if (client_send_packet(&pkt
))
102 client
.need_resize
= false;
106 if (select(server
.socket
+ 1, &fds
, NULL
, NULL
, NULL
) == -1) {
109 die("client-mainloop");
112 if (FD_ISSET(server
.socket
, &fds
)) {
114 if (client_recv_packet(&pkt
)) {
117 write_all(STDOUT_FILENO
, pkt
.u
.msg
, pkt
.len
);
125 if (FD_ISSET(STDIN_FILENO
, &fds
)) {
126 Packet pkt
= { .type
= MSG_CONTENT
};
127 ssize_t len
= read(STDIN_FILENO
, pkt
.u
.msg
, sizeof(pkt
.u
.msg
));
128 if (len
== -1 && errno
!= EAGAIN
&& errno
!= EINTR
)
131 debug("client-stdin: %c", pkt
.u
.msg
[0]);
133 if (pkt
.u
.msg
[0] == KEY_REDRAW
) {
134 client
.need_resize
= true;
135 } else if (pkt
.u
.msg
[0] == KEY_DETACH
) {
136 pkt
.type
= MSG_DETACH
;
138 client_send_packet(&pkt
);
141 client_send_packet(&pkt
);