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

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 4 01:53:03 PDT 2006


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

Log Message:
-----------
Add a define DARWINTRACE_LOG_FULL_PATH to control whether full paths
are logged for open(2). When set, all paths have F_GETPATH run on
them. When not set, only volfs paths are resolved.

In execve(2), relative paths are resolved. For symlinks, both the
original argument to execve(2) and the resolved path
are printed, which is great for /usr/bin/cc -> gcc-3.3, so that
there is a dependency on both gcc_os and gcc_select.

Refactor some code into __darwintrace_logpath().

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

Modified: trunk/darwintrace/darwintrace.c
===================================================================
--- trunk/darwintrace/darwintrace.c	2005-08-08 21:40:27 UTC (rev 162)
+++ trunk/darwintrace/darwintrace.c	2006-10-04 08:53:02 UTC (rev 163)
@@ -41,9 +41,11 @@
 #include <sys/param.h>
 #include <sys/syscall.h>
 
+#define DARWINTRACE_SHOW_PROCESS 0
+#define DARWINTRACE_LOG_FULL_PATH 1
+
 int __darwintrace_fd = -2;
 #define BUFFER_SIZE	1024
-char __darwintrace_buf[BUFFER_SIZE];
 #if DARWINTRACE_SHOW_PROCESS
 char __darwintrace_progname[BUFFER_SIZE];
 pid_t __darwintrace_pid = -1;
@@ -55,7 +57,7 @@
 	  if (path != NULL) {
 		__darwintrace_fd = open(path,
 		O_CREAT | O_WRONLY | O_APPEND,
-		0666);
+		DEFFILEMODE);
 		fcntl(__darwintrace_fd, F_SETFD, 1); /* close-on-exec */
 	  }
 	}
@@ -70,6 +72,26 @@
 #endif
 }
 
+/* __darwintrace_setup must have been called already */
+inline void __darwintrace_logpath(int fd, const char *procname, char *tag, const char *path) {
+#pragma unused(procname)
+  char __darwintrace_buf[BUFFER_SIZE];
+  int size;
+
+  size = snprintf(__darwintrace_buf, sizeof(__darwintrace_buf),
+#if DARWINTRACE_SHOW_PROCESS
+		  "%s[%d]\t"
+#endif
+		  "%s\t%s\n",
+#if DARWINTRACE_SHOW_PROCESS
+		  procname ? procname : __darwintrace_progname, __darwintrace_pid,
+#endif
+		  tag, path );
+  
+  write(fd, __darwintrace_buf, size);
+  fsync(fd);
+}
+
 /* 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.
@@ -89,32 +111,32 @@
 	va_end(args);
 	result = open(path, flags, mode);
 	if (result >= 0 && (flags & (O_CREAT | O_WRONLY /*O_RDWR*/)) == 0 ) {
-		__darwintrace_setup();
-		if (__darwintrace_fd >= 0) {
-		  int size;
-		  if(strncmp(path, "/.vol/", 6) == 0) {
-		    char realpath[MAXPATHLEN];
-		    if(0 == fcntl(result, F_GETPATH, realpath)) {
-#if DARWINTRACE_SHOW_PROCESS
-		      size = snprintf(__darwintrace_buf, BUFFER_SIZE, "%s[%d]\topen\t%s\n", __darwintrace_progname, __darwintrace_pid, realpath );
-		      /* printf("resolved %s to %s\n", path, realpath); */
-#else
-		      size = snprintf(__darwintrace_buf, BUFFER_SIZE, "open\t%s\n", realpath );
+	  __darwintrace_setup();
+	  if (__darwintrace_fd >= 0) {
+	    char realpath[MAXPATHLEN];
+#if DARWINTRACE_LOG_FULL_PATH
+	    int usegetpath = 1;
+#else	  
+	    int usegetpath = 0;
 #endif
-		    } else {
-		    /* if we can't resolve it, ignore the volfs path */
-				size = 0;
-			}
-		  } else {
-#if DARWINTRACE_SHOW_PROCESS
-		    size = snprintf(__darwintrace_buf, BUFFER_SIZE, "%s[%d]\topen\t%s\n", __darwintrace_progname, __darwintrace_pid, path );
-#else
-			size = snprintf(__darwintrace_buf, BUFFER_SIZE, "open\t%s\n", path );
-#endif
-		  }
-		  write(__darwintrace_fd, __darwintrace_buf, size);
-		  fsync(__darwintrace_fd);
-		}
+
+	    /* for volfs paths, we need to do a GETPATH anyway */
+	    if(!usegetpath && strncmp(path, "/.vol/", 6) == 0) {
+	      usegetpath = 1;
+	    }
+	    
+	    if(usegetpath) {
+	      if(0 == fcntl(result, F_GETPATH, realpath)) {
+		/* printf("resolved %s to %s\n", path, realpath); */
+		path = realpath;
+	      } else {
+		/* use original path */
+		/* printf("failed to resolve %s\n", path); */
+	      }
+	    }
+
+	    __darwintrace_logpath(__darwintrace_fd, NULL, "open", path);
+	  }
 	}
 	return result;
 }
@@ -126,54 +148,77 @@
 	__darwintrace_setup();
 	if (__darwintrace_fd >= 0) {
 	  struct stat sb;
-	  if (stat(path, &sb) == 0) {
-#if DARWINTRACE_SHOW_PROCESS
-		int size = snprintf(__darwintrace_buf, BUFFER_SIZE, "%s[%d]\texecve\t%s\n", __darwintrace_progname, __darwintrace_pid, path );
-#else
-		int size = snprintf(__darwintrace_buf, BUFFER_SIZE, "execve\t%s\n", path );
-#endif
-		int fd;
+	  int printorig = 1;
+	  int printreal = 0;
+	  int fd;
+
+	  /* We initially assume path is normal like /bin/cp */
+
+	  if (lstat(path, &sb) == 0) {
+	    if(path[0] != '/') {
+	      /* for relative paths, only print full path */
+	      printreal = 1;
+	      printorig = 0;
+	    } else if(S_ISLNK(sb.st_mode)) {
+	      /* for symlinks, print both */
+	      printreal = 1;
+	      printorig = 1;
+	    }
+
+	    if(printorig) {
+	      __darwintrace_logpath(__darwintrace_fd, NULL, "execve", path);
+	    }
 		
-		write(__darwintrace_fd, __darwintrace_buf, size);
-		fsync(__darwintrace_fd);
+	    fd = open(path, O_RDONLY, 0);
+	    if (fd != -1) {
+
+	      char buffer[MAXPATHLEN];
+	      ssize_t bytes_read;
+
+	      /* once we have an open fd, if a full path was requested, do it */
+	      if(printreal) {
+		char realpath[MAXPATHLEN];
 		
-		fd = open(path, O_RDONLY, 0);
-		if (fd != -1) {
-			char buffer[MAXPATHLEN];
-			ssize_t bytes_read = read(fd, buffer, MAXPATHLEN);
-			if (bytes_read > 0 &&
-			    buffer[0] == '#' && buffer[1] == '!') {
-				const char* interp = &buffer[2];
-				int i;
-				/* skip past leading whitespace */
-				for (i = 2; i < bytes_read; ++i) {
-					if (buffer[i] != ' ' && buffer[i] != '\t') {
-						interp = &buffer[i];
-						break;
-					}
-				}
-				/* found interpreter (or ran out of data)
-				 skip until next whitespace, then terminate the string */
-				for (; i < bytes_read; ++i) {
-					if (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n') {
-						buffer[i] = 0;
-					}
-				}
-				/* we have liftoff */
-				if (interp) {
+		if(0 == fcntl(fd, F_GETPATH, realpath)) {
+		  /* printf("resolved %s to %s\n", path, realpath); */
+		  __darwintrace_logpath(__darwintrace_fd, NULL, "execve", realpath);
+		}
+	      }
+
+	      bzero(buffer, sizeof(buffer));
+
+	      bytes_read = read(fd, buffer, MAXPATHLEN);
+	      if (bytes_read > 2 &&
+		  buffer[0] == '#' && buffer[1] == '!') {
+		const char* interp = &buffer[2];
+		int i;
+		/* skip past leading whitespace */
+		for (i = 2; i < bytes_read; ++i) {
+		  if (buffer[i] != ' ' && buffer[i] != '\t') {
+		    interp = &buffer[i];
+		    break;
+		  }
+		}
+		/* found interpreter (or ran out of data)
+		   skip until next whitespace, then terminate the string */
+		for (; i < bytes_read; ++i) {
+		  if (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n') {
+		    buffer[i] = 0;
+		    break;
+		  }
+		}
+		/* we have liftoff */
+		if (interp && interp[0] != '\0') {
+		  const char* procname = NULL;
 #if DARWINTRACE_SHOW_PROCESS
-					const char* procname = strrchr(argv[0], '/') + 1;
-					if (procname == NULL) procname = argv[0];
-					int size = snprintf(__darwintrace_buf, BUFFER_SIZE, "%s[%d]\texecve\t%s\n", procname, 0, interp );
-#else
-					int size = snprintf(__darwintrace_buf, BUFFER_SIZE, "execve\t%s\n", interp );
+		  procname = strrchr(argv[0], '/') + 1;
+		  if (procname == NULL) procname = argv[0];
 #endif
-					write(__darwintrace_fd, __darwintrace_buf, size);
-					fsync(__darwintrace_fd);
-				}
-			}
-			close(fd);
+		  __darwintrace_logpath(__darwintrace_fd, procname, "execve", interp);
 		}
+	      }
+	      close(fd);
+	    }
 	  }
 	}
 	result = execve(path, argv, envp);

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


More information about the darwinbuild-changes mailing list