summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorNed T. Crigler <crigler@gmail.com>2025-06-19 19:45:22 -0700
committerNed T. Crigler <crigler@gmail.com>2025-06-19 20:30:18 -0700
commitdc84bf8b0f70af92f894209d2cf68eaff55db9f0 (patch)
tree4805f9238336fa21f396beb14fd278a4feac9911 /main.c
parent6e04acf9ed089f065b19ff4e42be97bd17529ff2 (diff)
Always check the return value of the write() system call
dtach was assuming that writes with a small byte count could never fail, and was not handling partial writes for larger byte counts in a few places. This should also suppress unused result warnings from gcc on systems that define _FORTIFY_SOURCE by default.
Diffstat (limited to 'main.c')
-rw-r--r--main.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/main.c b/main.c
index 89e22ce..5d991fa 100644
--- a/main.c
+++ b/main.c
@@ -45,6 +45,49 @@ int redraw_method = REDRAW_UNSPEC;
struct termios orig_term;
int dont_have_tty;
+/* Write buf to fd handling partial writes. Exit on failure. */
+void
+write_buf_or_fail(int fd, const void *buf, size_t count)
+{
+ while (count != 0)
+ {
+ ssize_t ret = write(fd, buf, count);
+
+ if (ret >= 0)
+ {
+ buf = (const char *)buf + ret;
+ count -= ret;
+ }
+ else if (ret < 0 && errno == EINTR)
+ continue;
+ else
+ {
+ printf(EOS "\r\n[write failed]\r\n");
+ exit(1);
+ }
+ }
+}
+
+/* Write pkt to fd. Exit on failure. */
+void
+write_packet_or_fail(int fd, const struct packet *pkt)
+{
+ while (1)
+ {
+ ssize_t ret = write(fd, pkt, sizeof(struct packet));
+
+ if (ret == sizeof(struct packet))
+ return;
+ else if (ret < 0 && errno == EINTR)
+ continue;
+ else
+ {
+ printf(EOS "\r\n[write failed]\r\n");
+ exit(1);
+ }
+ }
+}
+
static void
usage()
{