[darwinbuild-changes] [183] trunk/darwintrace/darwintrace.c

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 4 01:55:15 PDT 2006


Revision: 183
          http://trac.macosforge.org/projects/darwinbuild/changeset/183
Author:   ssen
Date:     2006-10-04 01:55:14 -0700 (Wed, 04 Oct 2006)

Log Message:
-----------
Implement __darwintrace_cleanup_path() to do some cleanup of
paths before they are logged. Add "static" keywords to limit
external visibility. Add dprintf() macro, controlled by
DARWINTRACE_DEBUG_OUTPUT, to log out some debug stuff.

Modified Paths:
--------------
    trunk/darwintrace/darwintrace.c

Modified: trunk/darwintrace/darwintrace.c
===================================================================
--- trunk/darwintrace/darwintrace.c	2005-08-13 03:33:03 UTC (rev 182)
+++ trunk/darwintrace/darwintrace.c	2006-10-04 08:55:14 UTC (rev 183)
@@ -40,18 +40,26 @@
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <sys/syscall.h>
+#include <sys/paths.h>
 
 #define DARWINTRACE_SHOW_PROCESS 0
 #define DARWINTRACE_LOG_FULL_PATH 1
+#define DARWINTRACE_DEBUG_OUTPUT 0
 
-int __darwintrace_fd = -2;
+static int __darwintrace_fd = -2;
 #define BUFFER_SIZE	1024
 #if DARWINTRACE_SHOW_PROCESS
-char __darwintrace_progname[BUFFER_SIZE];
-pid_t __darwintrace_pid = -1;
+static char __darwintrace_progname[BUFFER_SIZE];
+static pid_t __darwintrace_pid = -1;
 #endif
 
-inline void __darwintrace_setup() {
+#if DARWINTRACE_DEBUG_OUTPUT
+#define dprintf(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define dprintf(...)
+#endif
+
+static inline void __darwintrace_setup() {
 	if (__darwintrace_fd == -2) {
 	  char* path = getenv("DARWINTRACE_LOG");
 	  if (path != NULL) {
@@ -73,7 +81,7 @@
 }
 
 /* __darwintrace_setup must have been called already */
-inline void __darwintrace_logpath(int fd, const char *procname, char *tag, const char *path) {
+static inline void __darwintrace_logpath(int fd, const char *procname, char *tag, const char *path) {
 #pragma unused(procname)
   char __darwintrace_buf[BUFFER_SIZE];
   int size;
@@ -92,6 +100,49 @@
   fsync(fd);
 }
 
+/* remap resource fork access to the data fork.
+ * do a partial realpath(3) to fix "foo//bar" to "foo/bar"
+ */
+static inline void __darwintrace_cleanup_path(char *path) {
+  size_t pathlen, rsrclen;
+  size_t i, shiftamount;
+  enum { SAWSLASH, NOTHING } state = NOTHING;
+
+  /* if this is a foo/..namedfork/rsrc, strip it off */
+  pathlen = strlen(path);
+  rsrclen = strlen(_PATH_RSRCFORKSPEC);
+  if(pathlen > rsrclen
+     && 0 == strcmp(path + pathlen - rsrclen,
+		    _PATH_RSRCFORKSPEC)) {
+    path[pathlen - rsrclen] = '\0';
+    pathlen -= rsrclen;
+  }
+
+  /* for each position in string (including
+     terminal \0), check if we're in a run of
+     multiple slashes, and only emit the
+     first one
+  */
+  for(i=0, shiftamount=0; i <= pathlen; i++) {
+    if(state == SAWSLASH) {
+      if(path[i] == '/') {
+	/* consume it */
+	shiftamount++;
+      } else {
+	state = NOTHING;
+	path[i - shiftamount] = path[i];
+      }
+    } else {
+      if(path[i] == '/') {
+	state = SAWSLASH;
+      }
+      path[i - shiftamount] = path[i];
+    }
+  }
+
+  dprintf("darwintrace: cleanup resulted in %s\n", path);
+}
+
 /* Log calls to open(2) into the file specified by DARWINTRACE_LOG.
    Only logs if the DARWINTRACE_LOG environment variable is set.
    Only logs files where the open succeeds.
@@ -120,6 +171,8 @@
 	    int usegetpath = 0;
 #endif
 
+	    dprintf("darwintrace: original open path is %s\n", path);
+
 	    /* for volfs paths, we need to do a GETPATH anyway */
 	    if(!usegetpath && strncmp(path, "/.vol/", 6) == 0) {
 	      usegetpath = 1;
@@ -127,15 +180,19 @@
 	    
 	    if(usegetpath) {
 	      if(0 == fcntl(result, F_GETPATH, realpath)) {
-		/* printf("resolved %s to %s\n", path, realpath); */
-		path = realpath;
+		dprintf("darwintrace: resolved %s to %s\n", path, realpath);
 	      } else {
 		/* use original path */
-		/* printf("failed to resolve %s\n", path); */
+		dprintf("darwintrace: failed to resolve %s\n", path);
+		strcpy(realpath, path);
 	      }
+	    } else {
+		strcpy(realpath, path);
 	    }
 
-	    __darwintrace_logpath(__darwintrace_fd, NULL, "open", path);
+	    __darwintrace_cleanup_path(realpath);
+
+	    __darwintrace_logpath(__darwintrace_fd, NULL, "open", realpath);
 	  }
 	}
 	return result;
@@ -148,12 +205,23 @@
 	__darwintrace_setup();
 	if (__darwintrace_fd >= 0) {
 	  struct stat sb;
-	  int printorig = 1;
+	  char realpath[MAXPATHLEN];
+	  int printorig = 0;
 	  int printreal = 0;
 	  int fd;
+#if DARWINTRACE_LOG_FULL_PATH
+	  int usegetpath = 1;
+#else	  
+	  int usegetpath = 0;
+#endif
 
-	  /* We initially assume path is normal like /bin/cp */
+	  dprintf("darwintrace: original execve path is %s\n", path);
 
+	  /* for symlinks, we wan't to capture
+	   * both the original path and the modified one,
+	   * since for /usr/bin/gcc -> gcc-4.0,
+	   * both "gcc_select" and "gcc" are contributors
+	   */
 	  if (lstat(path, &sb) == 0) {
 	    if(path[0] != '/') {
 	      /* for relative paths, only print full path */
@@ -163,10 +231,17 @@
 	      /* for symlinks, print both */
 	      printreal = 1;
 	      printorig = 1;
+	    } else {
+	      /* for fully qualified paths, print real */
+	      printreal = 1;
+	      printorig = 0;
 	    }
 
 	    if(printorig) {
-	      __darwintrace_logpath(__darwintrace_fd, NULL, "execve", path);
+	      strcpy(realpath, path);
+
+	      __darwintrace_cleanup_path(realpath);
+	      __darwintrace_logpath(__darwintrace_fd, NULL, "execve", realpath);
 	    }
 		
 	    fd = open(path, O_RDONLY, 0);
@@ -177,12 +252,20 @@
 
 	      /* once we have an open fd, if a full path was requested, do it */
 	      if(printreal) {
-		char realpath[MAXPATHLEN];
 		
-		if(0 == fcntl(fd, F_GETPATH, realpath)) {
-		  /* printf("resolved %s to %s\n", path, realpath); */
-		  __darwintrace_logpath(__darwintrace_fd, NULL, "execve", realpath);
+		if(usegetpath) {
+		  if(0 == fcntl(fd, F_GETPATH, realpath)) {
+		    dprintf("darwintrace: resolved execve path %s to %s\n", path, realpath);
+		  } else {
+		    dprintf("darwintrace: failed to resolve %s\n", path);
+		    strcpy(realpath, path);
+		  }
+		} else {
+		  strcpy(realpath, path);
 		}
+		__darwintrace_cleanup_path(realpath);
+
+		__darwintrace_logpath(__darwintrace_fd, NULL, "execve", realpath);
 	      }
 
 	      bzero(buffer, sizeof(buffer));
@@ -190,7 +273,7 @@
 	      bytes_read = read(fd, buffer, MAXPATHLEN);
 	      if (bytes_read > 2 &&
 		  buffer[0] == '#' && buffer[1] == '!') {
-		const char* interp = &buffer[2];
+		char* interp = &buffer[2];
 		int i;
 		/* skip past leading whitespace */
 		for (i = 2; i < bytes_read; ++i) {
@@ -214,6 +297,8 @@
 		  procname = strrchr(argv[0], '/') + 1;
 		  if (procname == NULL) procname = argv[0];
 #endif
+		  __darwintrace_cleanup_path(interp);
+
 		  __darwintrace_logpath(__darwintrace_fd, procname, "execve", interp);
 		}
 	      }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20061004/5346b104/attachment-0001.html


More information about the darwinbuild-changes mailing list