xfs initscript enhancements, take 5

Mike A. Harris mharris at redhat.com
Thu Oct 9 05:22:35 UTC 2003


Ok, I have made some more improvements to the xfs initscript, and
have also incorporated improvments suggested by Owen Taylor,
Havoc Pennington, Alexandre Oliva, and others.  I have added 
our xfree86-list at redhat.com to the CC list to widen 
distribution a bit.  Hope that doesn't annoy anyone.  ;o)

The latest patch is attached, and here is the current list of
changes for review:

- The shebang was changed to "#!/bin/bash" as I very much use 
  bash specific features in my shell scripts, and the current 
  initscript definitely contains non-Bourne shell script code.
  Futher rationale for Bourne purists:  bash allows constructs 
  using bash builtins, which allow much more to be accomplished
  in scripting, with much less code and complexity.  Red Hat 
  Linux, and now Fedora, requires bash be installed in /bin/bash 
  on all systems in so many places already, that it is basically 
  considered a hard coded requirement for running the OS in the 
  first place.  As such, using bash specifics in shell scripts is 
  perfectly acceptable in my eyes.  Don't try to convince me 
  otherwise, as I can convert it to processor specific assembly 
  language instead.  <evil grin>

- Cosmetic change:  The "NEEDED" variable was renamed to      
  "REGEN_FONTS_DIR" as I felt that was more descriptive and 
  readable.

- Ignore "fonts.cache*" metadata files in the font directory when 
  determining wether or not fonts.dir needs to be regenerated.

- Use grep options "-q" and "-s" on all grep invocations to 
  prevent stdout and stderr output instead of shell redirection.
  This IMHO looks nicer, and it might even be faster.

- Add a section to detect Opentype fonts separately from Truetype 
  fonts because ttmkfdir doesn't handle opentype fonts.  In the 
  new section we handle opentype fonts the same way as truetype 
  ones, only we call mkfontscale on them instead of ttmkfdir.

- When attempting to detect non-truetype non-opentype fonts in 
  the last section, we want to ignore all possible non-font files 
  including all known font metadata files, so as to not 
  needlessly trigger recreation of fonts.dir.  Some of the files 
  we are wanting to avoid are: fonts.scale, fonts.alias, 
  fonts.cache*, fonts.dir, encodings.dir, *.otc, *.otf, *.ttc, 
  *.ttf.  The current regular expresion I believe handles all of 
  these cases cleanly:
      '(^fonts\.(scale|alias|cache.*)$|.+(\.[ot]t[cf]|dir)$)'
  Comments appreciated for improvments here, or to poke holes in 
  my regex.

- Use "grep -E" instead of "egrep" now, as egrep is a shell 
  script which calls grep -E for some ungodly reason in some OS
  releases.  This eliminates a fork()/exec() at least and might 
  be slightly faster, without harming readability.  Also, both 
  "grep -E and egrep" have more readable regular expression 
  syntax for the ugly regular expression.

- If any fonts.dir files were created during this invocation, 
  then call fc-cache to update the fontconfig cache files also.  
  While testing this enhancement in Red Hat Linux 8.0 (since I 
  keep XFree86 4.3.0 buildable on RHL 8.0, and do much of my 
  testing there), I determined that the fc-cache version shipped
  in RHL 8.0 will SEGV when invoked from the xfs initscript in
  this manner.  We're unlikely to release an updated fontconfig
  for RHL 8.0 unless there is a security hole in it, however even
  if we did find and fix the bug and release erratum, I can't
  guarantee the user would have it installed anyway.  As such, we 
  test the fc-cache version and if it is version 1.0.2, we skip 
  running fc-cache.

Comments:

If anyone is interested in debugging and/or fixing fontconfig in 
Red Hat Linux 8.0, that would be nice, however I'll likely still 
need the initscript hack anyway.

The final "ls|grep -E" which detects non-ttf/non-otf fonts will 
come up true if the directory contains subdirectories.  The only 
way I can think of to easily avoid this, is to use "find" instead 
of "ls|grep -E" and disable directory recursion, and only return 
files, not dirs.  That change is a bit more experimental however, 
so I'm leaving that for the future.

Any feedback or comments are appreciated.  I'd like to commit 
these enhancements to 4.3.0-38 soon unless problems arise.



-- 
Mike A. Harris     ftp://people.redhat.com/mharris
OS Systems Engineer - XFree86 maintainer - Red Hat
-------------- next part --------------
--- xfs.init.old	2003-09-18 19:15:34.000000000 -0400
+++ xfs.init	2003-10-09 00:47:00.000000000 -0400
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # xfs:       Starts the X Font Server
 #
@@ -29,28 +29,46 @@
       if [ -d "$d" ]; then
          cd $d
          # Check if we need to rerun mkfontdir
-         NEEDED=no
+         REGEN_FONTS_DIR=no
          if ! [ -e fonts.dir ]; then
-            NEEDED=yes
-         elif [ "$(find . -type f -cnewer fonts.dir 2>/dev/null)" != "" ];then
-            NEEDED=yes
+            REGEN_FONTS_DIR=yes
+         elif [ "$(find . -type f -cnewer fonts.dir -not -name "fonts.cache*" 2>/dev/null)" != "" ];then
+            REGEN_FONTS_DIR=yes
          fi
-         if [ "$NEEDED" = "yes" ]; then
+         if [ "$REGEN_FONTS_DIR" = "yes" ]; then
             rm -f fonts.dir &>/dev/null
-            if ls | grep -i "\.tt[cf]$" &>/dev/null; then
-               # TrueType fonts found...
+            if ls | grep -iqs "\.tt[cf]$" ; then
+               # TrueType fonts found, generate fonts.scale and fonts.dir
                ttmkfdir -d . -o fonts.scale
                mkfontdir . &>/dev/null
                [ -e fonts.dir ] && chmod 644 fonts.scale fonts.dir
             fi
-            if [ "$(ls |egrep -iv '\.tt[cf]$|^fonts\.|^encodings\.')" != "" ]; then
-               # This directory contains fonts that are not TrueType...
+            if ls | grep -iqs "\.ot[cf]$" ; then
+               # Opentype fonts found, generate fonts.scale and fonts.dir
+               mkfontscale .
+               mkfontdir . &>/dev/null
+               [ -e fonts.dir ] && chmod 644 fonts.scale fonts.dir
+            fi
+            if ls |grep -Eiqsv '(^fonts\.(scale|alias|cache.*)$|.+(\.[ot]t[cf]|dir)$)' ; then
+               # This directory contains non-TrueType/non-Opentype fonts
                mkfontdir . &>/dev/null
                [ -e fonts.dir ] && chmod 644 fonts.dir
             fi
          fi
       fi
    done
+   # Recreating fonts.dir files above may result in stale fonts.cache-1
+   # files since the directory mtimes change, so we run fc-cache to
+   # update any necessary fonts.cache files.
+   FC_CACHE=/usr/bin/fc-cache
+   if [ "$REGEN_FONTS_DIR" = "yes" -a -x $FC_CACHE ]
+      # fc-cache 1.0.2 as included in Red Hat Linux 8.0 will SEGV when executed
+      # by this initscript, so we don't run fc-cache for version 1.0.2 since
+      # even if fc-cache were fixed, we can't guarantee the user would have the
+      # fixed version installed.  Yes, this is an ugly, but necessary hack for
+      # the time being.
+      [ $FC_CACHE --version 2>&1 | grep -q '1\.0\.2' ] || $FC_CACHE
+   fi
    popd &> /dev/null
 }
 


More information about the fedora-devel-list mailing list