diff options
-rw-r--r-- | src/clinet.c | 1 | ||||
-rw-r--r-- | src/dotd.c | 4 | ||||
-rw-r--r-- | src/emaillog.c | 38 | ||||
-rw-r--r-- | src/hosts.c | 8 | ||||
-rw-r--r-- | src/mon.c | 5 | ||||
-rw-r--r-- | src/netutil.c | 12 | ||||
-rw-r--r-- | src/serve.c | 10 | ||||
-rw-r--r-- | src/snprintf.c | 36 | ||||
-rw-r--r-- | src/snprintf.h | 2 | ||||
-rw-r--r-- | src/srvnet.c | 3 | ||||
-rw-r--r-- | src/srvrpc.c | 2 | ||||
-rw-r--r-- | src/stats.c | 9 | ||||
-rw-r--r-- | src/trace.c | 6 | ||||
-rw-r--r-- | src/util.c | 24 |
14 files changed, 113 insertions, 47 deletions
diff --git a/src/clinet.c b/src/clinet.c index 4e4767e..010a884 100644 --- a/src/clinet.c +++ b/src/clinet.c @@ -92,6 +92,7 @@ int dcc_connect_by_addr(struct sockaddr *sa, size_t salen, int tries = 3; dcc_sockaddr_to_string(sa, salen, &s); + if (s == NULL) return EXIT_OUT_OF_MEMORY; rs_trace("started connecting to %s", s); @@ -272,9 +272,9 @@ int dcc_get_dotd_info(char **argv, char **dotd_fname, } else { /* There is no extension (or name ends with a "."). */ if (tmp_dotd_fname[strlen(tmp_dotd_fname) - 1] == '.') - asprintf(dotd_fname, "%s%s", tmp_dotd_fname, "d"); + checked_asprintf(dotd_fname, "%s%s", tmp_dotd_fname, "d"); else - asprintf(dotd_fname, "%s%s", tmp_dotd_fname, ".d"); + checked_asprintf(dotd_fname, "%s%s", tmp_dotd_fname, ".d"); if (*dotd_fname == NULL) { return EXIT_OUT_OF_MEMORY; } diff --git a/src/emaillog.c b/src/emaillog.c index 9e68a0b..e106529 100644 --- a/src/emaillog.c +++ b/src/emaillog.c @@ -35,6 +35,7 @@ #include "trace.h" #include "bulk.h" #include "snprintf.h" +#include "exitcode.h" /* if never_send_email is true, we won't send email even if should_send_email is true */ @@ -84,21 +85,33 @@ int dcc_add_file_to_log_email(const char *description, char end[] = "\nEND "; int in_fd = 0; off_t fsize; + int ret; if (never_send_email) return 0; - if (dcc_open_read(fname, &in_fd, &fsize)) - return 1; + ret = dcc_open_read(fname, &in_fd, &fsize); + if (ret != 0) return ret; - write(email_fileno, begin, strlen(begin)); - write(email_fileno, description, strlen(description)); - write(email_fileno, "\n", 1); + ret = write(email_fileno, begin, strlen(begin)); + if (ret != (ssize_t) strlen(begin)) return EXIT_IO_ERROR; - dcc_pump_readwrite(email_fileno, in_fd, fsize); + ret = write(email_fileno, description, strlen(description)); + if (ret != (ssize_t) strlen(description)) return EXIT_IO_ERROR; - write(email_fileno, end, strlen(end)); - write(email_fileno, description, strlen(description)); - write(email_fileno, "\n", 1); + ret = write(email_fileno, "\n", 1); + if (ret != 1) return EXIT_IO_ERROR; + + ret = dcc_pump_readwrite(email_fileno, in_fd, fsize); + if (ret != 0) return ret; + + ret = write(email_fileno, end, strlen(end)); + if (ret != (ssize_t) strlen(end)) return EXIT_IO_ERROR; + + ret = write(email_fileno, description, strlen(description)); + if (ret != (ssize_t) strlen(description)) return EXIT_IO_ERROR; + + ret = write(email_fileno, "\n", 1); + if (ret != 1) return EXIT_IO_ERROR; close(in_fd); @@ -113,12 +126,17 @@ void dcc_maybe_send_email(void) { whom_to_blame = dcc_emaillog_whom_to_blame; } char *cant_send_message_to; + int ret; if (should_send_email == 0) return; if (never_send_email) return; rs_log_warning(will_send_message_format, whom_to_blame); - asprintf(&cant_send_message_to, cant_send_message_format, whom_to_blame); + ret = asprintf(&cant_send_message_to, cant_send_message_format, whom_to_blame); + if (ret == -1) { + fprintf(stderr, "error sending email: asprintf() failed"); + return; + } if (email_fileno < 0) { errno = email_errno; diff --git a/src/hosts.c b/src/hosts.c index 5fa1395..aaf4fd9 100644 --- a/src/hosts.c +++ b/src/hosts.c @@ -172,8 +172,8 @@ int dcc_get_hostlist(struct dcc_hostdef **ret_list, if ((ret = dcc_get_top_dir(&top)) == 0) { /* if we failed to get it, just warn */ - asprintf(&path, "%s/hosts", top); - if (access(path, R_OK) == 0) { + checked_asprintf(&path, "%s/hosts", top); + if (path != NULL && access(path, R_OK) == 0) { ret = dcc_parse_hosts_file(path, ret_list, ret_nhosts); free(path); return ret; @@ -183,8 +183,8 @@ int dcc_get_hostlist(struct dcc_hostdef **ret_list, } } - asprintf(&path, "%s/distcc/hosts", SYSCONFDIR); - if (access(path, R_OK) == 0) { + checked_asprintf(&path, "%s/distcc/hosts", SYSCONFDIR); + if (path != NULL && access(path, R_OK) == 0) { ret = dcc_parse_hosts_file(path, ret_list, ret_nhosts); free(path); return ret; @@ -259,7 +259,10 @@ static int dcc_mon_do_file(char *dirname, char *filename, return 0; } - asprintf(&fullpath, "%s/%s", dirname, filename); + checked_asprintf(&fullpath, "%s/%s", dirname, filename); + if (fullpath == NULL) { + return EXIT_OUT_OF_MEMORY; + } rs_trace("process %s", fullpath); /* Remember that the file might disappear at any time, so open it diff --git a/src/netutil.c b/src/netutil.c index 7324750..4a7b452 100644 --- a/src/netutil.c +++ b/src/netutil.c @@ -177,13 +177,13 @@ int dcc_sockaddr_to_string(struct sockaddr *sa, return 0; /* it's still a valid string */ } - asprintf(p_buf, "%s:%s", host, port); + checked_asprintf(p_buf, "%s:%s", host, port); } else if (sa->sa_family == AF_UNIX) { /* NB: The word 'sun' is predefined on Solaris */ struct sockaddr_un *sa_un = (struct sockaddr_un *) sa; - asprintf(p_buf, "UNIX-DOMAIN %s", sa_un->sun_path); + checked_asprintf(p_buf, "UNIX-DOMAIN %s", sa_un->sun_path); } else { - asprintf(p_buf, "UNKNOWN-FAMILY %d", sa->sa_family); + checked_asprintf(p_buf, "UNKNOWN-FAMILY %d", sa->sa_family); } return 0; @@ -200,14 +200,14 @@ int dcc_sockaddr_to_string(struct sockaddr *sa, /* The double-cast here suppresses warnings from -Wcast-align. */ struct sockaddr_in *sain = (struct sockaddr_in *) (void *) sa; - asprintf(p_buf, "%s:%d", inet_ntoa(sain->sin_addr), + checked_asprintf(p_buf, "%s:%d", inet_ntoa(sain->sin_addr), ntohs(sain->sin_port)); } else if (sa->sa_family == AF_UNIX) { /* NB: The word 'sun' is predefined on Solaris */ struct sockaddr_un *sa_un = (struct sockaddr_un *) sa; - asprintf(p_buf, "UNIX-DOMAIN %s", sa_un->sun_path); + checked_asprintf(p_buf, "UNIX-DOMAIN %s", sa_un->sun_path); } else { - asprintf(p_buf, "UNKNOWN-FAMILY %d", sa->sa_family); + checked_asprintf(p_buf, "UNKNOWN-FAMILY %d", sa->sa_family); } return 0; diff --git a/src/serve.c b/src/serve.c index e6c2232..6ee6dd0 100644 --- a/src/serve.c +++ b/src/serve.c @@ -431,7 +431,7 @@ static int tweak_include_arguments_for_server(char **argv, if (argv[i] != NULL) { /* in case of a dangling -I */ if (argv[i][index_of_first_filename_char] == '/') { char *buf; - asprintf(&buf, "%s%s%s", + checked_asprintf(&buf, "%s%s%s", include_option, root_dir, argv[i] + index_of_first_filename_char); @@ -544,7 +544,7 @@ static int make_temp_dir_and_chdir_for_cpp(int in_fd, if ((ret = dcc_r_cwd(in_fd, client_side_cwd))) return ret; - asprintf(server_side_cwd, "%s%s", *temp_dir, *client_side_cwd); + checked_asprintf(server_side_cwd, "%s%s", *temp_dir, *client_side_cwd); if (*server_side_cwd == NULL) { ret = EXIT_OUT_OF_MEMORY; } else if ((ret = dcc_mk_tmp_ancestor_dirs(*server_side_cwd))) { @@ -784,8 +784,10 @@ out_cleanup: dcc_stats_event(job_result); } - asprintf(&time_str, " exit:%d sig:%d core:%d ret:%d time:%dms ", WEXITSTATUS(status), WTERMSIG(status), WCOREDUMP(status), ret, time_ms); - dcc_job_summary_append(time_str); + checked_asprintf(&time_str, " exit:%d sig:%d core:%d ret:%d time:%dms ", + WEXITSTATUS(status), WTERMSIG(status), WCOREDUMP(status), + ret, time_ms); + if (time_str != NULL) dcc_job_summary_append(time_str); free(time_str); /* append compiler and input file info */ diff --git a/src/snprintf.c b/src/snprintf.c index da57960..3ccafbe 100644 --- a/src/snprintf.c +++ b/src/snprintf.c @@ -125,17 +125,16 @@ #include <stdlib.h> #endif -#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) \ - && defined(HAVE_VASPRINTF) && defined(HAVE_ASPRINTF) -/* This ifdef switches on or off basically the whole contents of the file. */ -/* Make the compiler happy with an empty file */ - void dummy_snprintf(void); - void dummy_snprintf(void) {} -#else - #include "snprintf.h" #include "va_copy.h" +#if !defined(HAVE_SNPRINTF) || \ + !defined(HAVE_VSNPRINTF) || \ + !defined(HAVE_C99_VSNPRINTF) || \ + !defined(HAVE_VASPRINTF) || \ + !defined(HAVE_ASPRINTF) +/* Lots of code to define our own vsnprintf(). */ + #ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double #else @@ -863,7 +862,6 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) } #endif /* HAVE_VASPRINTF */ - #ifndef HAVE_ASPRINTF int asprintf(char **ptr, const char *format, ...) { @@ -879,6 +877,26 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) } #endif /* HAVE_ASPRINTF */ +/* Like asprintf(), but on error it sets *ptr to NULL + * rather than returning -1. Unlike asprintf(), it + * guarantees to always set *ptr. + */ +int checked_asprintf(char **ptr, const char *format, ...) +{ + va_list ap; + int ret; + + *ptr = NULL; + va_start(ap, format); + ret = vasprintf(ptr, format, ap); + va_end(ap); + + if (ret == -1) { + *ptr = NULL; + } + return ret; +} + #ifdef TEST_SNPRINTF int sprintf(char *str,const char *fmt,...); diff --git a/src/snprintf.h b/src/snprintf.h index 5c5c9e3..db2a19f 100644 --- a/src/snprintf.h +++ b/src/snprintf.h @@ -36,3 +36,5 @@ int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); #if !HAVE_DECL_VSNPRINTF int vsnprintf(char *, size_t, const char *, va_list); #endif + +int checked_asprintf(char **, const char *, ...) PRINTF_ATTRIBUTE(2,3); diff --git a/src/srvnet.c b/src/srvnet.c index 383a679..c2efbca 100644 --- a/src/srvnet.c +++ b/src/srvnet.c @@ -86,6 +86,9 @@ static int dcc_listen_by_addr(int fd, setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)); dcc_sockaddr_to_string(sa, salen, &sa_buf); + if (sa_buf == NULL) { + return EXIT_OUT_OF_MEMORY; + } /* now we've got a socket - we need to bind it */ if (bind(fd, sa, salen) == -1) { diff --git a/src/srvrpc.c b/src/srvrpc.c index 15f73fa..08e3d7f 100644 --- a/src/srvrpc.c +++ b/src/srvrpc.c @@ -87,7 +87,7 @@ int dcc_r_cwd(int ifd, char **cwd) static int prepend_dir_to_name(const char *dirname, char **path) { char *buf; - asprintf(&buf, "%s%s", dirname, *path); + checked_asprintf(&buf, "%s%s", dirname, *path); if (buf == NULL) { return EXIT_OUT_OF_MEMORY; } diff --git a/src/stats.c b/src/stats.c index c2ef762..21aeb65 100644 --- a/src/stats.c +++ b/src/stats.c @@ -114,7 +114,7 @@ void dcc_stats_event(enum stats_e e) { struct statsdata sd; memset(&sd, 0, sizeof(sd)); sd.type = e; - write(dcc_statspipe[1], &sd, sizeof(sd)); + dcc_writex(dcc_statspipe[1], &sd, sizeof(sd)); } } @@ -135,7 +135,7 @@ void dcc_stats_compile_ok(char *compiler, char *filename, struct timeval start, sd.time = time_usec; strncpy(sd.filename, filename, MAX_FILENAME_LEN); strncpy(sd.compiler, compiler, MAX_FILENAME_LEN); - write(dcc_statspipe[1], &sd, sizeof(sd)); + dcc_writex(dcc_statspipe[1], &sd, sizeof(sd)); } } @@ -363,6 +363,7 @@ static void dcc_service_stats_request(int http_fd) { socklen_t cli_len = sizeof(cli_addr); double loadavg[3]; int free_space_mb; + ssize_t ret; const char replytemplate[] = "\ HTTP/1.0 200 OK\n\ @@ -438,8 +439,8 @@ dcc_free_space %d MB\n\ dcc_stats.io_rate, free_space_mb); dcc_set_nonblocking(acc_fd); - read(acc_fd, challenge, 1024); /* empty the receive queue */ - write(acc_fd, reply, reply_len); + ret = read(acc_fd, challenge, 1024); /* empty the receive queue */ + dcc_writex(acc_fd, reply, reply_len); } /* Don't think we need this to prevent RST anymore, since we read() now */ diff --git a/src/trace.c b/src/trace.c index f23f94f..c5f148b 100644 --- a/src/trace.c +++ b/src/trace.c @@ -319,6 +319,7 @@ rs_logger_file(int flags, const char *fn, char const *fmt, va_list va, /* NOTE NO TRAILING NUL */ char buf[4090]; size_t len; + ssize_t ret; rs_format_msg(buf, sizeof buf, flags, fn, fmt, va); @@ -327,7 +328,10 @@ rs_logger_file(int flags, const char *fn, char const *fmt, va_list va, len = (int) sizeof buf - 2; strcpy(&buf[len], "\n"); - (void) write(log_fd, buf, len+1); + ret = write(log_fd, buf, len + 1); + if (ret == -1) { + ret = write(/* stderr */ 2, buf, len + 1); + } } @@ -424,10 +424,17 @@ char *dcc_abspath(const char *path, int path_len) if (*path == '/') len = 0; else { + char *ret; #ifdef HAVE_GETCWD - getcwd(buf, sizeof buf); + ret = getcwd(buf, sizeof buf); + if (ret == NULL) { + rs_log_crit("getcwd failed: %s", strerror(errno)); + } #else - getwd(buf); + ret = getwd(buf); + if (ret == NULL) { + rs_log_crit("getwd failed: %s", strerror(errno)); + } #endif len = strlen(buf); if (len >= sizeof buf) { @@ -675,8 +682,14 @@ void dcc_get_disk_io_stats(int *n_reads, int *n_writes) { kernel26 = 0; } - if (!kernel26) /* blast away 2 header lines in /proc/partitions */ - fscanf(f, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s"); + if (!kernel26) /* blast away 2 header lines in /proc/partitions */ { + retval = fscanf(f, + "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s"); + if (retval == EOF) { + fclose(f); + return; + } + } while (1) { if (kernel26) @@ -707,7 +720,8 @@ void dcc_get_disk_io_stats(int *n_reads, int *n_writes) { break; #endif /* assume the lines aren't longer that 1024 characters */ - fgets(tmp, 1024, f); + if (fgets(tmp, 1024, f) == NULL) + break; } } |