Chapter 4. User Activity

In the previous chapter, we explored the identity of a user and how this identity is managed and stored. Now let’s talk about how to manage users while they are active on our systems and network.

The significant actions of users fall into four domains:

Processes

Users can spawn, kill, pause, and resume processes on our machines. These processes compete for a computer’s finite processing power, adding resource issues to the list of problems a system administrator needs to mediate.

File operations

Most of the time, operations like writing, reading, creating, deleting, etc., take place when some user process interacts with files in a filesystem. But under Unix, there’s more to this picture. Unix uses the filesystem as a gateway to more than just file storage. Device control, input/output channels, and even some process control and network access are file operations. We dealt with filesystem administration in Chapter 2, but in this chapter we’ll approach this topic from a user administration perspective.

Network

Users can send and receive data over network interfaces on our machine. There is material elsewhere in this book on networking, but we’ll address this issue here from a different perspective.

OS-specific activities

This last domain is a catchall for the OS-specific features that users can access via different APIs. Included in this list are things like GUI element controls, shared memory usage, file sharing APIs, sound, etc. This category is so diverse that there’s no way to discuss it well in our current context. I recommend tracking down the OS-specific web sites like http://www.macperl.com for information on these topics.

Let’s look at ways to deal with the first three of these domains using Perl. Each of the operating systems in this book treats this topic differently, so we’re going to have to address them on an individual basis. The closest thing to common ground they share is the Perl kill( ) function, and even that is not implemented under MacOS. We will take each OS in turn, beginning with the least complicated (from a Perl perspective). Because we’re interested in user administration, the focus here will be on dealing with processes started by other users.

MacOS Process Control

“Control” might be too strong a word for the functionality offered under MacOS, since MacOS is not multiuser and is just barely multitasking. Using the module Mac::Processes, we can interact with the Macintosh Process Manager using the MacOS Toolbox API for process control. If you are going to delve any deeper than surface level with this module, you’ll want to seek out a copy of the Inside Macintosh:Processes volume that deals with the Process Manager.

When we load Mac::Processes via the standard use Mac::Processes directive, it initializes a special hash called %Process. This hash is magical because it always contains a representation of the current process state of the machine thanks to Perl’s tied variable functionality. Each time the contents of %Process are accessed, information about the machine’s current running processes are returned. To see a list of the current process serial numbers (the MacOS term for process ID, often abbreviated as PSN ), we can simply query the list of keys in this hash:

use Mac::Processes;
print map{"$_\n"} keys %Process;

For more information on the individual processes, we need to work with the values returned for each key. Each hash entry contains an object representing a ProcessInfo structure. To get at the individual fields of this structure, you call object methods with their names. For more information on each field and what it represents, see the canonical reference book Inside Macintosh:Processes. The currently available method names are processName( ), processNumber( ), processType( ), processSignature( ), processSize( ), processMode( ), processLocation( ), processLauncher( ), processLaunchDate( ), processActiveTime( ), and processAppSpec( ).

To get a list of the running processes and their names, we could write:

use Mac::Processes;
while(($psn, $psi) = each (%Process)){
  $name = $psi->processName(  );
  write;
}

format STDOUT_TOP =
Process Serial Number      Process Name
=====================      =========================================
.

format STDOUT =
@<<<<<<                    @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$psn,                      $name
.

which would yield output that looked like this:

Process Serial Number      Process Name
=====================      =========================
8192                       FaxMonitor
8193                       Queue Watcher
8194                       Finder
8195                       Serial Port Monitor
8198                       MacPerl

Once you know the processes running on a machine, it is natural to want to control them. Unfortunately, our abilities in this realm are negligible. The most exciting thing we can do is bring a process to the foreground using SetFrontProcess($psn). We don’t even have the ability to directly kill a process (the Perl kill( ) function is not implemented). The best we can do is send an AppleEvent to a running application or the finder to request that this process shut itself down. The easiest way to perform this task is to use Chris Nandor’s Mac::Apps::Launch module. It offers a function called QuitApps( ) that can quit an application given its creator ID. Mac::Apps::Launch also provides some useful functions for launching applications and bringing them to and away from the foreground similar to those we mentioned in Mac::Processes.

Let’s move on to an operating system that is much less limited in the process control realm.

Get Perl for System Administration now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.