Module Name: src Committed By: rillig Date: Sat Feb 13 19:23:11 UTC 2021
Modified Files: src/tests/lib/libcurses/slave: commands.c Log Message: tests/libcurses: protect against short writes The previous code only errored out if a write failed completely. If it was partially written, the program continued without writing the rest of it. Extract the common code into a few functions that write raw data to the parent process. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/tests/lib/libcurses/slave/commands.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/lib/libcurses/slave/commands.c diff -u src/tests/lib/libcurses/slave/commands.c:1.12 src/tests/lib/libcurses/slave/commands.c:1.13 --- src/tests/lib/libcurses/slave/commands.c:1.12 Sat Feb 13 08:14:46 2021 +++ src/tests/lib/libcurses/slave/commands.c Sat Feb 13 19:23:11 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: commands.c,v 1.12 2021/02/13 08:14:46 rillig Exp $ */ +/* $NetBSD: commands.c,v 1.13 2021/02/13 19:23:11 rillig Exp $ */ /*- * Copyright 2009 Brett Lymn <bl...@netbsd.org> @@ -42,8 +42,7 @@ extern int initdone; -static void report_type(data_enum_t); -static void report_message(int, const char *); +static void report_message(data_enum_t, const char *); /* * Match the passed command string and execute the associated test @@ -85,6 +84,29 @@ command_execute(char *func, int nargs, c report_status("UNKNOWN_FUNCTION"); } +static void +write_to_director(const void *mem, size_t size) +{ + ssize_t nwritten = write(to_director, mem, size); + if (nwritten == -1) + err(1, "writing to director failed"); + if ((size_t)nwritten != size) + err(1, "short write to director, expected %zu, got %zd", + size, nwritten); +} + +static void +write_to_director_int(int i) +{ + write_to_director(&i, sizeof i); +} + +static void +write_to_director_type(data_enum_t return_type) +{ + write_to_director_int(return_type); +} + /* * Report an pointer value back to the director */ @@ -121,9 +143,9 @@ void report_return(int status) { if (status == ERR) - report_type(data_err); + write_to_director_type(data_err); else if (status == OK) - report_type(data_ok); + write_to_director_type(data_ok); else if (status == KEY_CODE_YES) report_int(status); else @@ -131,33 +153,13 @@ report_return(int status) } /* - * Report the type back to the director via the command pipe - */ -static void -report_type(data_enum_t return_type) -{ - int type; - - type = return_type; - if (write(to_director, &type, sizeof(int)) < 0) - err(1, "command pipe write for status type failed"); - -} - -/* * Report the number of returns back to the director via the command pipe */ void report_count(int count) { - int type; - - type = data_count; - if (write(to_director, &type, sizeof(int)) < 0) - err(1, "command pipe write for count type failed"); - - if (write(to_director, &count, sizeof(int)) < 0) - err(1, "command pipe write for count"); + write_to_director_type(data_count); + write_to_director_int(count); } /* @@ -183,20 +185,12 @@ report_error(const char *status) * command pipe. */ static void -report_message(int type, const char *status) +report_message(data_enum_t type, const char *status) { - int len; - - len = strlen(status); - - if (write(to_director, &type, sizeof(int)) < 0) - err(1, "command pipe write for message type failed"); - - if (write(to_director, &len, sizeof(int)) < 0) - err(1, "command pipe write for message length failed"); - - if (write(to_director, status, len) < 0) - err(1, "command pipe write of message data failed"); + size_t len = strlen(status); + write_to_director_type(type); + write_to_director_int(len); + write_to_director(status, len); } /* @@ -218,31 +212,17 @@ report_byte(chtype c) void report_nstr(chtype *string) { - int len, type; + size_t size; chtype *p; - len = 0; - p = string; + for (p = string; (*p & __CHARTEXT) != 0; p++) + continue; - while ((*p++ & __CHARTEXT) != 0) { - len++; - } + size = (size_t)(p + 1 - string) * sizeof *p; - len++; /* add in the termination chtype */ - len *= sizeof(chtype); - - type = data_byte; - if (write(to_director, &type, sizeof(int)) < 0) - err(1, "%s: command pipe write for status type failed", - __func__); - - if (write(to_director, &len, sizeof(int)) < 0) - err(1, "%s: command pipe write for status length failed", - __func__); - - if (write(to_director, string, len) < 0) - err(1, "%s: command pipe write of status data failed", - __func__); + write_to_director_type(data_byte); + write_to_director_int(size); + write_to_director(string, size); } /* @@ -251,21 +231,10 @@ report_nstr(chtype *string) void report_cchar(cchar_t c) { - int len, type; - len = sizeof(cchar_t); - type = data_cchar; - - if (write(to_director, &type, sizeof(int)) < 0) - err(1, "%s: command pipe write for status type failed", - __func__); - - if (write(to_director, &len, sizeof(int)) < 0) - err(1, "%s: command pipe write for status length failed", - __func__); - - if (write(to_director, &c, len) < 0) - err(1, "%s: command pipe write of status data failed", - __func__); + + write_to_director_type(data_cchar); + write_to_director_int(sizeof c); + write_to_director(&c, sizeof c); } /* @@ -288,30 +257,17 @@ report_wchar(wchar_t ch) void report_wstr(wchar_t *wstr) { - int len, type; + size_t size; wchar_t *p; - len = 0; - p = wstr; - - while (*p++ != L'\0') - len++; + for (p = wstr; *p != L'\0'; p++) + continue; + size = (size_t)(p + 1 - wstr) * sizeof *p; - len++; /* add in the termination chtype */ - len *= sizeof(wchar_t); - type = data_wchar; - if (write(to_director, &type, sizeof(int)) < 0) - err(1, "%s: command pipe write for status type failed", - __func__); - - if (write(to_director, &len, sizeof(int)) < 0) - err(1, "%s: command pipe write for status length failed", - __func__); - - if (write(to_director, wstr, len) < 0) - err(1, "%s: command pipe write of status data failed", - __func__); + write_to_director_type(data_wchar); + write_to_director_int(size); + write_to_director(wstr, size); } /* @@ -324,8 +280,8 @@ check_arg_count(int nargs, int expected) if (nargs != expected) { report_count(1); report_error("INCORRECT_ARGUMENT_NUMBER"); - return(1); + return 1; } - return(0); + return 0; }