Spence Murray, a founding partner of Codemonks Consulting, has been a UNIX/Linux developer since his early experiences writing code on SunOS back in the mid 1980's. Since then, he has spent time at IBM working on AIX, SGI on Irix, and lots of time writing cross-platform UNIX code for HP/UX, Irix, Solaris/SunOS, SCO UNIX, BSD variants, MacOS X, and of course, Linux. The work has ranged from graphics/video device drivers to UI code. A bunch of Murray's cross-platform code was X Window System Xserver code, as well as core browser code as part of Netscape Navigator.
Murray's most oft-used Linux tools are vi, bash, and Emacs. "Whether I'm writing C, C++, Java, shell scripts, or HTML, the vast majority of my time involves bouncing between these tools," he says.
For a Linux developer, Murray believes the shell is a powerful software development tool whose utility is hard to overestimate. "Shell scripting is an integral part of just about everything I do, whether quickly perusing and editing plain text or writing code," he says. "It's small and quick, and its short commands make moving code around a quick and painless process. As an editor, it quickly becomes second nature."
Emacs as a development tool came a few years later for Murray. "Around the early '90's, I experimented with Emacs as an IDE, and rapidly was converted. Emacs is immensely powerful, and these days, I constantly have an Emacs window present, often with many tens of source files open, each maintaining my editing context, debugging sessions via gdb, and bash shells running in various source directories. Many pages have been written about Emacs, but suffice it to say, the tool is awesome... and again, you can run it on just about any system you're likely to spend time developing on."
Since first experiencing the terse environment of vi on SunOS back in the mid-1980's, the Emacs editor has become Murray's standard tool. "It's available or can be built on every flavor of UNIX, which is a key factor given the cross-platform nature of my contract development work," he says.
Linux developers: know your shell
Know your shell, demands Murray. "Bash, tcsh, csh -- the shell is your fundamental software development tool," he insists." It can do many a great thing. Everything depends on it... and it's powerful." As an example of the power of shell scripting in common usage, see the Resources section for a downloadable file that includes a set of scripts to retrieve updated RPM packages for a Red Hat release and merge them with the original packages and custom packages. Once the downloadable file is unzipped, the scripts can be found in the /DeveloperWorks/rpm_update_scripts/ directory. The end result is a directory containing the latest version of all the packages and an updated hdlist file ready for network installs.
The code fragment below implements automated updates of Red Hat RPM packages to create readily installable distributions with the latest RPMs. This is a fundamental process for anyone maintaining public Linux servers. In our usage, we commonly maintain a large number of customer Web services across a set of publicly accessible Linux servers. The scripts below are part of our automated process of pulling in the latest security and functional updates.
The script samples below demonstrate common shell hacking techniques that are generally useful for a variety of system configuration and programming applications. Bourne shell is used, which is the most common shell available across UNIX systems. This ensures highly portable code that requires little or no change for use on different UNIX systems. The Red Hat package specifications can be easily modified to apply to other Linux distributions.
freshen.sh updates the original RPM list with update RPMs from the specified RPM ftp update site. Filtering is implemented to replace update RPMs. Finally, the anaconda distribution list is updated to reflect the new RPMs pulled down from the update mirror site.
Listing 1. fresh.sh
#!/bin/sh
rh_ver=$1
rh_path=$2
update_dir=${rh_path}/RH${rh_ver}-updates
custom_dir=${rh_path}/RH${rh_ver}-custom
install_dir=${rh_path}/RH${rh_ver}-install
# Sanity check for the original directory.
# Create update and install directories if they don't exist
[ -d ${update_dir} ] || mkdir ${update_dir}
[ -d ${install_dir}/RedHat/RPMS ] || mkdir -p ${install_dir}/RedHat/RPMS
# Get latest updates from fresh rpms FTP site
./get_update.sh ${rh_ver} ${update_dir}
# Create/update hardlinks from update, and custom directories
# to the install directory. We assume that original RPMS are already
# hardlinked to the install directory, so all we need to do is filter
# out any replaced by updated packages.
./do-links.sh ${update_dir} ${install_dir}/RedHat/RPMS
[ -d ${custom_dir} ] && ./do-links.sh ${custom_dir}
${install_dir}/RedHat/RPMS
# Filter out all but the latest version of everything.
./filter-rpms.pl $install_dir/RedHat/RPMS
# Rebuild the hard disk lists
/usr/lib/anaconda-runtime/genhdlist ${install_dir}
|
freshen.sh calls do-links.sh and get_update.sh to set up the source and destination locations of the RPM distributions (source RPMs are elided; hard links are used to set up the destination RPMs) and to retrieve the updates, respectively.
Listing 2. do-links.sh
#!/bin/sh src=$1 dest=$2 #for file in $src/*; do for file in `find $src -name *.rpm -a ! -name *.src.rpm -print`; do base=`basename $file;` if test ! -f $dest/$base; then echo "Linking $file"; ln $file $dest else echo "EXISTS: $file"; fi done |
Listing 3. get_update.sh
#!/bin/sh
rh_ver=$1
dest=$2
echo "Retrieving updates for version ${rh_ver} to $dest"
lftp << EOF
open ftp.freshrpms.net <ftp://ftp.freshrpms.net> <ftp://ftp.freshrpms.net>
<ftp://ftp.freshrpms.net>
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i386 $dest/i386
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i486 $dest/i486
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i586 $dest/i568
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i686 $dest/i686
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/SRPMS $dest/SRPMS
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/noarch $dest/noarch
|
A fair amount of the development work done at Codemonks is Java on Linux. The combination of these two tools provides a platform for the creation of commercial-quality Web applications, says Murray. "During the course of one such project, we found the need to profile a client's existing application code," he recalls. locks.c (in the /DeveloperWorks/locks/ directory from the downloadable zip file; see Resources) is a code snippet that implements read/write locks with extensive debugging code for use under the Java Virtual Machine Profiler Interface (JVMPI; see Resources for a link to more information on JVMPI).
"Don't write system-specific code when you don't need to," says Murray. Instead, overcome the challenge to "write good, cross-platform code." The mercenary Murray insists that his greatest asset has always been to "write commercial-quality code, build and host network services, and customize the OS or kernel, all from a solid open source platform."
Below is a code snippet from a cross-platform, custom IMAP server, which was jointly developed by developers on both Linux and MacOS X. The code implements a simple growing buffer for holding strings. This avoids the problem of buffer overflow (remember all those security holes), while not requiring a re-allocation every time you do something. It does this by maintaining a simple resizable buffer that can be filled in and emptied. This buffer is used in an experimental IMAP server written by a group in an intense weeklong hacking session.
In addition to implementing a simple string buffer, the code implements a variabl-sized array of strings. This is done with a simple interface where, when you finish writing one string, you mark it as done and continue with the next one. Again, this economizes on allocations and keeps the messy code all in one spot.
The code for the entire IMAP server should be released sometime this year.
Listing 4. Portion of custom IMAP server
#ifndef HOED_BUF_H
#define HOED_BUF_H
typedef struct {
char *str;
int size;
int length;
int str_start;
int max_size;
int n_strings;
int size_strings;
int *str_posn;
char **str_set;
} hoed_buf_t;
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define PRINTF(f, a) __attribute__((format (printf, f, a)))
#else
#define PRINTF(f,a)
#endif
extern hoed_buf_t *hoed_buf_alloc(int init_size, int max_size);
extern void hoed_buf_free(hoed_buf_t *);
extern void hoed_buf_reset(hoed_buf_t *);
extern void hoed_buf_new_string(hoed_buf_t *);
extern char **hoed_buf_get_set(hoed_buf_t *, int *n_string);
extern char *hoed_buf_put_char(hoed_buf_t *, char toadd);
extern char *hoed_buf_sprintf(hoed_buf_t *, const char *format,...)
PRINTF(2,3);
extern char *hoed_buf_strcat(hoed_buf_t *, const char *append);
extern char *hoed_buf_cat_sprintf(hoed_buf_t *, const char *format, ...)
PRINTF(2,3);
#endif /* HOED_BUF_H */
|
Name that killer Linux application
According to Murray there are two killer Linux applications: Emacs and Netscape Navigator. "Emacs is possibly the most impressive Linux-based and widely used application around," he says. "Another is Netscape Navigator. At one point, we supported more than 20 flavors of UNIX, and I did a lot of my work on Linux."
He continues, "The funny thing is that Linux-based applications will probably run on a bunch of different UNIX systems, even on Windows with Cygwin installed."
Currently, Murray has several Linux projects in development, ranging from distributed office applications supporting e-mail, messaging, and shared databases to Web applications using the standard tools: Apache/Tomcat, PHP, PostgreSQL, MySQL, and Linux. Murray also has his own company devoted to hosting network services and Web applications.
According to Murray, the list of applications that take advantage of Linux's strengths is constantly expanding "There are many," he says. "Oracle, WebSphere, Apache, PostgresQL, MySQL, Cyrus IMAP... the list is long and growing."
According to Murray, Linux is here to stay. "All of our servers run Linux; the majority of our development is done on Linux, regardless of our target platform; we recommend Linux to clients for server applications," he says. "If you combine the rapid pace at which Linux develops, its broad base of support in the open source community, and its low cost of development, it's a difficult platform to beat."
| Name | Size | Download method |
|---|---|---|
| l-murray/developerworks-samples.zip | HTTP |
Information about download methods
- Download the source code used in this article.
- Read John's "Secrets of the wireless elite" column on developerWorks.
- For a solid grounding in Linux fundamentals, read the developerWorksLPI 101 and LPI 102 test-preparation series of tutorials.
- "Living in Emacs" gives you a quick but effective introduction to this venerable editor. Similarly, "vi intro -- the cheat sheet method" aims to make you proficient with vi without a large investment of time.
- Build an IMAP client with Perl using the
Mail::IMAPClientCPAN module. - Get more information on the Java Virtual Machine Profiler Interface.
- Read about OProfile, an open source profiler for Linux.
- For a fast way to get started writing applications for Linux, check out Speed-start your Linux app. While you're there, order a free software evaluation kit on CD.
- You'll find more Linux articles in the developerWorks Linux zone.
John Papageorge has worked with some of the bigger names in the high-tech industry, launching products and Web initiatives for such companies as CNet, Macromedia, NBCi, Sun Microsystems, and MSNBC. John launched the groundbreaking CNet/Intel project Mediadome in 1996 and Macromedia's Shockwave.com in 1998. He also created NBCi's Media Sharehouse in 1999. John has worked as a consultant to forecast and explore the applications of Java technology for Sun Microsystems/Netscape's iPlanet site. John is currently working on his latest venture, Buzzphone, to create compelling voice-based fan club programs for pop music, sports film, NASCAR, and celebrity chefs. This patent-pending initiative has allowed Buzzphone to create relationships with some of the world's hottest talent. He can be reached at john@mediaoverdrive.com.
Comments (Undergoing maintenance)





