Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Unified Diff: src/platform/metrics/metrics_library.cc

Issue 1649007: metrics cleanup and fixes. (Closed)
Patch Set: Expose the pass/fail status. Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/metrics/metrics_library.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/metrics/metrics_library.cc
diff --git a/src/platform/metrics/metrics_library.cc b/src/platform/metrics/metrics_library.cc
index 99ad61640af785026fd1f64307e1495a8320d3ae..f482145a33d9fec0ad31fd153b4c0a9d893ce8d3 100644
--- a/src/platform/metrics/metrics_library.cc
+++ b/src/platform/metrics/metrics_library.cc
@@ -13,21 +13,23 @@
#include <errno.h>
#include <sys/file.h>
-#include <string.h>
-#include <stdio.h>
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstring>
#define READ_WRITE_ALL_FILE_FLAGS \
(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
static const char kAutotestPath[] = "/tmp/.chromeos-metrics-autotest";
static const char kChromePath[] = "/tmp/.chromeos-metrics";
-static const int kBufferSize = 4096;
+static const int32_t kBufferSize = 1024;
using namespace std;
// TODO(sosa@chromium.org) - use Chromium logger instead of stderr
-void MetricsLibrary::PrintError(const char *message, const char *file,
- int code) {
+static void PrintError(const char *message, const char *file,
+ int code) {
const char *kProgramName = "metrics_library";
if (code == 0) {
fprintf(stderr, "%s: %s\n", kProgramName, message);
@@ -40,61 +42,105 @@ void MetricsLibrary::PrintError(const char *message, const char *file,
}
}
-void MetricsLibrary::SendToAutotest(string name, string value) {
- FILE *autotest_file = fopen(kAutotestPath, "a+");
- if (autotest_file == NULL) {
- PrintError("fopen", kAutotestPath, errno);
- return;
- }
-
- fprintf(autotest_file, "%s=%s\n", name.c_str(), value.c_str());
- fclose(autotest_file);
-}
-
-void MetricsLibrary::SendToChrome(string name, string value) {
+// Sends message of size length to Chrome and returns true on success.
+static bool SendMessageToChrome(int32_t length, const char *message) {
int chrome_fd = open(kChromePath,
O_WRONLY | O_APPEND | O_CREAT,
READ_WRITE_ALL_FILE_FLAGS);
- // If we failed to open it, return
+ // If we failed to open it, return.
if (chrome_fd < 0) {
PrintError("open", kChromePath, errno);
- return;
+ return false;
}
- // Need to chmod because open flags are anded with umask.
- if (fchmod(chrome_fd, READ_WRITE_ALL_FILE_FLAGS) < 0) {
- PrintError("fchmod", kChromePath, errno);
- close(chrome_fd);
- return;
- }
+ // Need to chmod because open flags are anded with umask. Ignore the
+ // exit code -- a chronos process may fail chmoding because the file
+ // has been created by a root process but that should be OK.
+ fchmod(chrome_fd, READ_WRITE_ALL_FILE_FLAGS);
- // Grab an exclusive lock to protect Chrome from truncating underneath us
+ // Grab an exclusive lock to protect Chrome from truncating
+ // underneath us. Keep the file locked as briefly as possible.
if (flock(chrome_fd, LOCK_EX) < 0) {
PrintError("flock", kChromePath, errno);
close(chrome_fd);
- return;
+ return false;
}
- // Message format is: LENGTH (binary), NAME, VALUE
- char message[kBufferSize];
- char *curr_ptr = message;
- int32_t message_length =
- name.length() + value.length() + 2 + sizeof(message_length);
- if (message_length > static_cast<int32_t>(sizeof(message)))
- PrintError("name/value too long", NULL, 0);
-
- // Make sure buffer is blanked
- memset(message, 0, sizeof(message));
- memcpy(curr_ptr, &message_length, sizeof(message_length));
- curr_ptr += sizeof(message_length);
- strncpy(curr_ptr, name.c_str(), name.length());
- curr_ptr += name.length() + 1;
- strncpy(curr_ptr, value.c_str(), value.length());
- if (write(chrome_fd, message, message_length) != message_length)
+ bool success = true;
+ if (write(chrome_fd, message, length) != length) {
PrintError("write", kChromePath, errno);
+ success = false;
+ }
- // Release the file lock and close file
- if (flock(chrome_fd, LOCK_UN) < 0)
+ // Release the file lock and close file.
+ if (flock(chrome_fd, LOCK_UN) < 0) {
PrintError("unlock", kChromePath, errno);
+ success = false;
+ }
close(chrome_fd);
+ return success;
+}
+
+// Formats a name/value message for Chrome in buffer and returns the
+// length of the message or a negative value on error.
+//
+// Message format is: | LENGTH(binary) | NAME | \0 | VALUE | \0 |
+//
+// The arbitrary format argument covers the non-LENGTH portion of the
+// message. The caller is responsible to store the \0 character
+// between NAME and VALUE (e.g. "%s%c%d", name, '\0', value).
+static int32_t FormatChromeMessage(int32_t buffer_size, char *buffer,
+ const char *format, ...) {
+ int32_t message_length;
+ size_t len_size = sizeof(message_length);
+
+ // Format the non-LENGTH contents in the buffer by leaving space for
+ // LENGTH at the start of the buffer.
+ va_list args;
+ va_start(args, format);
+ message_length = vsnprintf(&buffer[len_size], buffer_size - len_size,
+ format, args);
+ va_end(args);
+
+ if (message_length < 0) {
+ PrintError("chrome message format error", NULL, 0);
+ return -1;
+ }
+
+ // +1 to account for the trailing \0.
+ message_length += len_size + 1;
+ if (message_length > buffer_size) {
+ PrintError("chrome message too long", NULL, 0);
+ return -1;
+ }
+
+ // Prepend LENGTH to the message.
+ memcpy(buffer, &message_length, len_size);
+ return message_length;
+}
+
+bool MetricsLibrary::SendToAutotest(string name, int value) {
+ FILE *autotest_file = fopen(kAutotestPath, "a+");
+ if (autotest_file == NULL) {
+ PrintError("fopen", kAutotestPath, errno);
+ return false;
+ }
+
+ fprintf(autotest_file, "%s=%d\n", name.c_str(), value);
+ fclose(autotest_file);
+ return true;
+}
+
+bool MetricsLibrary::SendToChrome(string name, int value) {
+ // Format the message.
+ char message[kBufferSize];
+ int32_t message_length =
+ FormatChromeMessage(kBufferSize, message,
+ "%s%c%d", name.c_str(), '\0', value);
+
+ if (message_length < 0)
+ return false;
+
+ // Send the message.
+ return SendMessageToChrome(message_length, message);
}
« no previous file with comments | « src/platform/metrics/metrics_library.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698