diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 (patch) | |
tree | 54fd1b2695a591d2306d41264df67c53077b752c /logwrapper | |
download | system_core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.zip system_core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.tar.gz system_core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.tar.bz2 |
Initial Contribution
Diffstat (limited to 'logwrapper')
-rw-r--r-- | logwrapper/Android.mk | 7 | ||||
-rw-r--r-- | logwrapper/logwrapper.c | 126 |
2 files changed, 133 insertions, 0 deletions
diff --git a/logwrapper/Android.mk b/logwrapper/Android.mk new file mode 100644 index 0000000..5fd6356 --- /dev/null +++ b/logwrapper/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= logwrapper.c +LOCAL_MODULE := logwrapper +LOCAL_STATIC_LIBRARIES := liblog +include $(BUILD_EXECUTABLE) diff --git a/logwrapper/logwrapper.c b/logwrapper/logwrapper.c new file mode 100644 index 0000000..c7a2534 --- /dev/null +++ b/logwrapper/logwrapper.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include "cutils/log.h" + +void fatal(const char *msg) { + fprintf(stderr, msg); + LOG(LOG_ERROR, "logwrapper", msg); + exit(-1); +} + +void usage() { + fatal( + "Usage: logwrapper BINARY [ARGS ...]\n" + "\n" + "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n" + "the Android logging system. Tag is set to BINARY, priority is\n" + "always LOG_INFO.\n"); +} + +void parent(const char *tag, int parent_read) { + int status; + char buffer[1024]; + + int a = 0; // start index of unprocessed data + int b = 0; // end index of unprocessed data + int sz; + while ((sz = read(parent_read, &buffer[b], 1023 - b)) > 0) { + // Log one line at a time + for (b = a; b < sz; b++) { + if (buffer[b] == '\n') { + buffer[b] = '\0'; + LOG(LOG_INFO, tag, &buffer[a]); + a = b + 1; + } + } + + if (a == 0 && b == 1023) { + // buffer is full, flush + buffer[b] = '\0'; + LOG(LOG_INFO, tag, &buffer[a]); + b = 0; + } else { + // Keep left-overs + b = sz - a; + memmove(buffer, &buffer[a], b); + a = 0; + } + } + // Flush remaining data + if (a != b) { + buffer[b] = '\0'; + LOG(LOG_INFO, tag, &buffer[a]); + } + wait(&status); // Wait for child +} + +void child(int argc, char* argv[]) { + // create null terminated argv_child array + char* argv_child[argc + 1]; + memcpy(argv_child, argv, argc * sizeof(char *)); + argv_child[argc] = NULL; + + if (execvp(argv_child[0], argv_child)) { + LOG(LOG_ERROR, "logwrapper", + "executing %s failed: %s\n", argv_child[0], strerror(errno)); + exit(-1); + } +} + +int main(int argc, char* argv[]) { + pid_t pid; + + int pipe_fds[2]; + int *parent_read = &pipe_fds[0]; + int *child_write = &pipe_fds[1]; + + if (argc < 2) { + usage(); + } + + if (pipe(pipe_fds) < 0) { + fatal("Cannot create pipe\n"); + } + + pid = fork(); + if (pid < 0) { + fatal("Failed to fork\n"); + } else if (pid == 0) { + // redirect stdout and stderr + close(*parent_read); + dup2(*child_write, 1); + dup2(*child_write, 2); + close(*child_write); + + child(argc - 1, &argv[1]); + + } else { + close(*child_write); + + parent(argv[1], *parent_read); + } + + return 0; +} |