Cover V03, I05


New Messages

Subject: upcoming events

We believe the following technical meetings are of interest to your readers.

September 19-23, 1994


Co-sponsored by SAGE, the System Administrators Guild Town & Country Hotel, San Diego, California Program Chair: Dinah McNutt, Zilker Internet Park, Inc.

October 26-28, 1994


Santa Fe, New Mexico
El Dorado Hotel
Program Chair: Tom Christiansen, Consultant

November 14-18, 1994


Co-sponsored by the USENIX Association, ACM SIGOPS and IEEE TCOS
Monterey, California
Marriott Hotel
Program Chair: Jay Lepreau, University of Utah

January 16-20, 1995

The only "broad-topic" USENIX Conference in 1995!


New Orleans, Louisiana
Marriott Hotel
Program Chair: Peter Honeyman, CITI, University of Michigan


Please contact: USENIX Conference Office
22672 Lambert St., Suite 613
Lake Forest, CA USA 92630
FAX 1-714-588-9706

Cynthia Deno
The USENIX Association

In the "New Messages" section of vol. 3, no. 3, Larry Reznick wrote: "The kill(1) man page doesn't claim an exit status. I wonder if there isn't a way to OR those three [signals] together so that subsequent signals aren't necessary if an earlier one succeeds?"

kill does have an exit status (at least under Sun's Solaris 1 and 2 and HP's HP-UX 9). It indicates if the signal was successfully delivered or not, and has nothing to do with whether or not the process died.

Fortunately, there's a little-known/used solution: kill -0 {pid}. kill -0 {pid} will exit with status 0 if the process exists and the user has permission to send a signal to the process, otherwise it will exit with status 1. The shell script in Listing 1 (E-Media Production Manager's note: Listings referenced within the New Messages/Letters can be found by scrolling to the bottom of the current page.) uses this to send SIGHUP, SIGTERM, and SIGKILL to a process until it dies.

Gaspar Carson,

Larry Reznick responds -- Thank you very much for the "kill 0" suggestion. A script function might best implement your primary idea of sending the intended kill signal followed by a 0 query signal. The function could take one signal and a pid, send the signal, wait briefly to give the process time to die, and then use "kill 0" to test whether the signal worked, returning FALSE if it didn't work. One could OR together several calls to this function using increasingly severe kill signals. Alternately, the function could take a set of signals, looping through sending each one. -Larry

Subject: When Inodes Go Bad

In the July/August 1994 issue of Sys Admin, you printed an article by Emmett Dulaney entitled "When Inodes Go Bad." Most of what Mr. Dulaney says in there is OK, but some of it is either incomplete, inconsistent, or incorrect.

The incompleteness arises because Mr. Dulaney consistently fails to mention that there are (at least) two types of links: hard links and symbolic links. Mr. Dulaney only shows hard links. A prime example of where this matters is on page 6, in the last sentence. There Mr. Dulaney states "Two linked files will share the same inode number." This is true for hard links, but is not true for symbolic links. Symbolic links use a different inode. One significance for systems administrators is that hard links may not span file systems and may not refer to directories, whereas symbolic links may span file systems and may refer to directories.

Another place where this incompleteness shows up is on page 10, in the last sentence of the 3rd paragraph under "Inode Functionality." In there Mr. Dulaney says "The second link is now no longer a link, but still contains the same information -- by virtue of still referencing that same inode." Due to the nature of symbolic links, if a link of this type is made to a file and the file is removed, the link remains and points to nothing.

An inconsistency/incompleteness arises between page 8, #3 where Mr. Dulaney shows what the special permission modes are, and page 14 in the last sentence on that page (which continues on to the next page). In the first instance, Mr. Dulaney describes the entity permission as "Permissions are four digits, with the first indicating whether a special mode is set (1=sticky bit, 2=SGID, 4=SUID)," but in the other instance he describes this same permission/mode digit as "by being zero, shows the sticky bit is not set." What that digit completely indicates (by being zero) is that neither the SUID bit, the SGID bit, nor the sticky bit are set.

An incorrectness/incompleteness shows up on page 11 in the last sentence of the 2nd paragraph, where he says "In order for ncheck to work properly, the name of the filesystem must be contained within a text file, /etc/checklist." This may be true for the systems he works with but it is not universally true (e.g., this is not true on any of the six types of UNIX systems I have access to).

What I consider to be the most blatant error is on page 10, #8. An inode does not store the file creation time (it isn't stored anywhere). The inode stores three time/date stamps, usually known as atime, ctime, and mtime. Atime is the last time/date the file was accessed. Mtime is the last time/date the file was modified. Since both of these refer to the file, it may be natural to assume that ctime does as well and if it does, to assume that it is the file creation time/date. However, both of these assumptions are wrong. Ctime refers to the inode itself and is the last time/date the inode was changed. The following is taken from the monthly Frequently Asked Questions (FAQ) documents for comp.unix.questions and USENET newsgroups, v2.5 4/28/94:

-- How do I find the creation time of a file?

You can't -- it isn't stored anywhere. Files have a last-modified time (shown by "ls -l"), a last-accessed time (shown by "ls -lu") and an inode change time (shown by "ls -lc"). The latter is often referred to as the "creation time" -- even in some man pages -- but that's wrong; it's also set by such operations as mv, ln, chmod, chown and chgrp.

The man page for "stat(2)" discusses this.

The following copyright notice refers to the above noted FAQ collection:

This collection of documents is Copyright 1994, Ted Timar. All rights reserved. Permission to distribute the collection is hereby granted providing that distribution is electronic, no money is involved, reasonable attempts are made to use the latest version and all credits and this copyright notice are maintained. Other requests for distribution will be considered.

Michael J. Chinni

Emmett Dulaney responds: You raise a few valid points, and a few questionable ones as well. It may not have been apparent from the introduction, but the purpose of the article was to address the subject of inodes in terms of the filesystem. For that reason, priority was given to hard links (which cannot span multiple filesystems) as opposed to symbolic links. You are correct in stating that removing the file a symbolic link points to leaves a reference to nothing, just as you would be correct in stating that the "date" command returns the current date -- as your first paragraph mentions, only hard links were discussed.

As for a digit of zero in the first position of a file's permissions indicating that sticky bit, SGID, and SUID are not set: I took the easy way out and simply said the sticky bit was not set, implying any of the special permissions. Semantically, you are correct.

I do not know what six UNIX systems you have around, but it has been my experience that the /etc/checklist file has been necessary. Given the number of vendors and versions, I won't say that you haven't come across six that do not utilize this.

On the last issue, you are 100 percent correct. Ctime refers to creation and modification. The date maintained is the date the file/inode was created or changed to its present form (i.e., created in this image).

Thanks for your input, and for keeping me on my toes.

Listing 1: Shell script to confirm a process kill

if [ "${#}" -ne 1 ]; then
echo "Usage: ${0} PID" 1>&2
exit 255

kill -0 ${1}
if [ "${?}" -eq 0 ]; then
kill -HUP "${1}"
if [ "${?}" -ne 0 ]; then
echo "kill -HUP ${1} failed with exit status ${?}" 1>&2
exit 1;
kill -0 ${1} >/dev/null 2>&1
if [ "${?}" -eq 0 ]; then
kill -TERM "${1}"
if [ "${?}" -ne 0 ]; then
echo "kill -TERM ${1} failed with exit status ${?}" 1>&2
exit 1;
kill -0 ${1} >/dev/null 2>&1
if [ "${?}" -eq 0 ]; then
kill -KILL "${1}"
if [ "${?}" -ne 0 ]; then
echo "kill -KILL ${1} failed with exit status ${?}" 1>&2
exit 1;
echo "Kill -0 ${1} failed!" 1>&2
exit 1;