*
**************************************************************************/
+#ifndef _WIN32
#include <assert.h>
#include <string.h>
#ifdef ANDROID
#include <android/log.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/system_properties.h>
#endif
#ifndef PATH_MAX
#ifdef __APPLE__
uint32_t len = size;
if (_NSGetExecutablePath(buf, &len) != 0) {
- *buf = 0;
- return path;
+ // grow buf and retry
+ buf = path.buf(len);
+ _NSGetExecutablePath(buf, &len);
}
len = strlen(buf);
#else
ssize_t len;
len = readlink("/proc/self/exe", buf, size - 1);
- if (len == -1) {
+ if (len <= 0) {
// /proc/self/exe is not available on setuid processes, so fallback to
// /proc/self/cmdline.
int fd = open("/proc/self/cmdline", O_RDONLY);
if (fd >= 0) {
- len = read(fd, buf, size - 1);
+ // buf already includes trailing zero
+ len = read(fd, buf, size);
close(fd);
+ if (len >= 0) {
+ len = strlen(buf);
+ }
}
}
if (len <= 0) {
- snprintf(buf, size, "%i", (int)getpid());
- return path;
+ // fallback to process ID
+ len = snprintf(buf, size, "%i", (int)getpid());
+ if (len >= size) {
+ len = size - 1;
+ }
}
#endif
path.truncate(len);
return path;
}
-#ifdef ANDROID
-static String
-getZygoteProcessName(void)
-{
- String path;
- size_t size = PATH_MAX;
- char *buf = path.buf(size);
- ssize_t len;
-
- int fd = open("/proc/self/cmdline", O_RDONLY);
-
- assert(fd >= 0);
- len = read(fd, buf, size - 1);
- close(fd);
- path.truncate(len);
-
- return path;
-}
-
-static bool isZygoteProcess(void)
-{
- os::String proc_name;
-
- proc_name = getProcessName();
- proc_name.trimDirectory();
-
- return strcmp(proc_name, "app_process") == 0;
-}
-
-bool apitrace_enabled(void)
-{
- static pid_t cached_pid;
- static bool enabled;
- pid_t pid;
-
- pid = getpid();
- if (cached_pid == pid)
- return enabled;
- cached_pid = pid;
-
- if (!isZygoteProcess()) {
- os::log("apitrace[%d]: enabled for standalone %s", pid,
- (const char *)getProcessName());
- enabled = true;
- return true;
- }
-
- char target_proc_name[PROP_VALUE_MAX] = "";
- os::String proc_name;
-
- proc_name = getZygoteProcessName();
- proc_name.trimDirectory();
-
- __system_property_get("debug.apitrace.procname", target_proc_name);
- enabled = !strcmp(target_proc_name, proc_name);
- os::log("apitrace[%d]: %s for %s",
- pid, enabled ? "enabled" : "disabled", (const char *)proc_name);
-
- return enabled;
-}
-#endif
-
String
getCurrentDir(void)
{
return path;
}
+bool
+createDirectory(const String &path)
+{
+ return mkdir(path, 0777) == 0;
+}
+
bool
String::exists(void) const
{
return false;
}
- if (!S_ISREG(st.st_mode))
- return false;
-
return true;
}
if (pid == 0) {
// child
execvp(args[0], args);
- fprintf(stderr, "error: failed to execute %s\n", args[0]);
+ fprintf(stderr, "error: failed to execute:");
+ for (unsigned i = 0; args[i]; ++i) {
+ fprintf(stderr, " %s", args[i]);
+ }
+ fprintf(stderr, "\n");
exit(-1);
} else {
// parent
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_DEBUG, "apitrace", format, ap);
#else
- vfprintf(stderr, format, ap);
+ static FILE *log = NULL;
+ if (!log) {
+ // Duplicate stderr file descriptor, to prevent applications from
+ // redirecting our debug messages to somewhere else.
+ //
+ // Another alternative would be to log to /dev/tty when available.
+ log = fdopen(dup(STDERR_FILENO), "at");
+ }
+ vfprintf(log, format, ap);
+ fflush(log);
#endif
va_end(ap);
logging = false;
void
abort(void)
{
- exit(0);
+ _exit(1);
}
} /* namespace os */
+#endif // !defined(_WIN32)