Code

Applied patch #1502063
authorjoncruz <joncruz@users.sourceforge.net>
Thu, 8 Jun 2006 02:43:15 +0000 (02:43 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Thu, 8 Jun 2006 02:43:15 +0000 (02:43 +0000)
ChangeLog
packaging/macosx/ScriptExec/main.c
packaging/osx-app.sh

index dee21c078739c1aeffd55d979ff1b616c11ada06..2b43ae4c8e2c3f61ea7b3ba20bf7ee00f5b95e69 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-06-07  Jon A. Cruz  <jon@joncruz.org>
+
+       * packaging/macosx/ScriptExec/main.c, packaging/osx-app.sh:
+
+         Fixing OS X fc-cache problem.
+         Applied patch #1502063.
+
 2006-06-07  Jon A. Cruz  <jon@joncruz.org>
 
        * src/sp-item-group.cpp, src/sp-path.cpp, src/sp-star.cpp,
index 89b07ddd0ed3a7bbd2421132de1afb4f45627c58..95092ee349a73c5505cafe20ad366ab7af284f92 100644 (file)
@@ -37,6 +37,7 @@
 #include <unistd.h>
 #include <sys/wait.h>
 #include <pthread.h>
+#include <stdio.h>
 
 ///////////////////////////////////////
 // Definitions
@@ -183,7 +184,7 @@ static OSStatus FCCacheFailedHandler(EventHandlerCallRef theHandlerCall,
        params.position = kWindowDefaultPosition;
 
        StandardAlert(kAlertStopAlert, "\pFont caches may need to be updated",
-                       "\pThere is a problem on OS X 10.4.x where X11 installation does not always generate the necessary fontconfig caches.  This can be corrected by running /usr/X11R6/bin/fc-cache as root.\n\nThis may take some time.  Please do not close Inkscape.",
+                       "\pA problem occurs on OS X 10.4 where X11 does not always generate the necessary fontconfig caches.  This can be corrected by running fc-cache as root.\n\nThis can take several minutes, with high processor usage.  Please do not close Inkscape.",
                        &params, &itemHit);
     
        if (itemHit == kAlertStdAlertOKButton)
@@ -206,7 +207,7 @@ static OSStatus FCCacheFailedHandler(EventHandlerCallRef theHandlerCall,
                params.cancelText = NULL;
 
                StandardAlert(kAlertNoteAlert, "\pFont caches have not been updated",
-                               "\pThey can be updated manually by running the following:\n   sudo /usr/X11R6/bin/fc-cache\nOnce you have dealt with this, please re-run Inkscape.", &params, &itemHit);
+                               "\pThey can be updated manually by running the following:\n   sudo /usr/X11R6/bin/fc-cache -f\nOnce you have dealt with this, please re-run Inkscape.", &params, &itemHit);
                system("test -d $HOME/.inkscape || mkdir $HOME/.inkscape; touch $HOME/.inkscape/.fccache");
        }
     
@@ -216,20 +217,61 @@ static OSStatus FCCacheFailedHandler(EventHandlerCallRef theHandlerCall,
 }
 
 
+static size_t safeRead(int d, void *buf, size_t nbytes)
+{
+       ssize_t bytesToRead = nbytes;
+       ssize_t bytesRead = 0;
+       char *offset = (char *) buf;
+
+       while ((bytesToRead > 0))
+       {
+               bytesRead = read(d, offset, bytesToRead);
+               if (bytesRead > 0)
+               {
+                       offset += bytesRead;
+                       bytesToRead -= bytesRead;
+               }
+               else if (bytesRead == 0)
+               {       
+                       // Reached EOF.
+                       break;
+               }
+               else if (bytesRead == -1)
+               {
+                       if ((errno == EINTR) || (errno == EAGAIN))
+                       {
+                               // Try again.
+                               continue;
+                       }
+                       return 0;
+               }
+       }
+       return bytesRead;
+}
+
+
 /////////////////////////////////////
 // Code to run fc-cache on first run
 /////////////////////////////////////
 static OSStatus FixFCCache (void)
 {
-   char* args[1];
+       FILE *fileConnToChild = NULL;
+       int fdConnToChild = 0;
+       pid_t childPID = WAIT_ANY;
+       size_t bytesChildPID;
+       size_t bytesRead;
+       int status;
+
+       char commandStr[] = "/usr/X11R6/bin/fc-cache";
+       char *commandArgs[] = { "-f", NULL };
 
        // Run fc-cache
        AuthorizationItem authItems[] = 
        {
        {
                kAuthorizationRightExecute,
-               23,
-               "/usr/X11R6/bin/fc-cache",
+               strlen(commandStr),
+               commandStr,
                0
        }
        };
@@ -240,18 +282,46 @@ static OSStatus FixFCCache (void)
        };
        AuthorizationRef authRef = NULL;
        OSStatus err = AuthorizationCreate (NULL, &authItemSet,
-                       kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights, &authRef);
+                       kAuthorizationFlagInteractionAllowed | 
+                       kAuthorizationFlagExtendRights, &authRef);
 
        if (err == errAuthorizationSuccess)
        {
-               //the arguments parameter to AuthorizationExecuteWithPrivileges is
-               //a NULL terminated array of C string pointers.
-               args[0]= NULL;
+               err = AuthorizationExecuteWithPrivileges(authRef, commandStr, 
+                               kAuthorizationFlagDefaults, commandArgs,
+                               &fileConnToChild);
 
-               AuthorizationExecuteWithPrivileges (authRef, "/usr/X11R6/bin/fc-cache", 
-                               kAuthorizationFlagDefaults, args, NULL);
+               if (err == errAuthorizationSuccess)
+               {
+                       // Unfortunately, AuthorizationExecuteWithPrivileges
+                       // does not return the process ID associated with the
+                       // process it runs.  The best solution we have it to
+                       // try and get the process ID from the file descriptor.
+                       // This is based on example code from Apple's
+                       // MoreAuthSample.
+
+                       fdConnToChild = fileno(fileConnToChild);
+                       
+                       // Try an get the process ID of the fc-cache command
+                       bytesChildPID = sizeof(childPID);
+                       bytesRead = safeRead(fdConnToChild, &childPID,
+                                       bytesChildPID);
+                       if (bytesRead != bytesChildPID)
+                       {
+                               // If we can't get it the best alternative
+                               // is to wait for any child to finish.
+                               childPID = WAIT_ANY;
+                       }
+
+                       if (fileConnToChild != NULL) {
+                               fclose(fileConnToChild);
+                       }
+
+                       // Wait for child process to finish.
+                       waitpid(childPID, &status, 0);
+               }
        }
-    AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
+       AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
 
        return err;
 }
index aa78b10bab7b5783221db17dd485a9f46d02456f..2025c260bc5c1b91e58120f3365b1ccdb084115e 100644 (file)
@@ -159,6 +159,7 @@ AliasFiles = "\${HOME}/.inkscape-etc/pangox.aliases"
 END_PANGO
 
 # We use a modified fonts.conf file so only need the dtd
+mkdir -p $pkgetc/fonts
 cp /etc/fonts/fonts.dtd $pkgetc/fonts/
 
 mkdir -p $pkgetc/gtk-2.0
@@ -205,6 +206,7 @@ do
 done
 
 if [ "$strip" = "true" ]; then
+  chmod +w "$package"/Contents/Resources/lib/*.dylib
   strip -x "$package"/Contents/Resources/lib/*.dylib
   strip -ur "$binpath"
 fi