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@xxxxxxxxxx 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
--- 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
}