#
Chapter 15
System Utilities

## 15.1 Time

### 15.1.1 Real Time and Date

`(current-seconds``)` returns the current time in seconds. This time is always an exact integer based on a platform-specific starting date (with a platform-specific minimum and maximum value).

The value of `(`current-seconds`)` increases as time passes (increasing by 1 for each second that passes). The current time in seconds can be compared with a time returned by ``file-or-directory-modify-seconds`` (see section 11.3.2).

`(seconds->date``` `secs-n``)` takes `secs-n`, a platform-specific time in seconds (an exact integer) returned by `current-seconds` or `file-or-directory-modify-seconds`, and returns an instance of the `date` structure type, which has the following fields:

- `second` : `0` to `61` (`60` and `61` are for unusual leap-seconds)

- `minute` : `0` to `59`

- `hour` : `0` to `23`

- `day` : `1` to `31`

- `month` : `1` to `12`

- `year` : e.g., `1996`

- `week-day` : `0` (Sunday) to `6` (Saturday)

- `year-day` : `0` to `365` (`364` in non-leap years)

- `dst?` : `#t` (daylight savings time) or `#f`

- `time-zone-offset` : the number of seconds east of GMT for this time zone (e.g., Pacific Standard Time is `-28800`), an exact integer 38

All fields of the `date` structure type are accessible by all inspectors (see section 4.5).

The value returned by `current-seconds` or `file-or-directory-modify-seconds` is not portable among platforms. Convert a time in seconds using ``seconds->date`` when portability is needed.

See also Chapter mz:mzlibdate in PLT MzLib: Libraries Manual for additional date utilities.

### 15.1.2 Machine Time

`(current-milliseconds``)` returns the current ``time'' in fixnum milliseconds (possibly negative). This time is based on a platform-specific starting date or on the machine's startup time. Since the result is a fixnum, the value is only strictly increasing for a limited (though reasonably long) time.

`(current-process-milliseconds``)` returns the amount of processor time in fixnum milliseconds that has been consumed by the MzScheme process on the underlying operating system. (Under Unix and Mac OS X, this includes both user and system time.) The precision of the result is platform-specific, and since the result is a fixnum, the value is only strictly increasing for a limited (though reasonably long) time.

`(current-gc-milliseconds``)` returns the amount of processor time in fixnum milliseconds that has been consumed by MzScheme's garbage collection so far. This time is a portion of the time reported by `(`current-process-milliseconds`)`.

### 15.1.3 Timing Execution

The ``time-apply`` procedure collects timing information for a procedure application:

- `(time-apply``` `proc arg-list``)` invokes the procedure `proc` with the arguments in `arg-list`. Four values are returned: a list containing the result(s) of applying `proc`, the number of milliseconds of CPU time required to obtain this result, the number of ``real'' milliseconds required for the result, and the number of milliseconds of CPU time (included in the second result) spent on garbage collection.

The reliability of the timing numbers depends on the platform; see section 15.1.2 for more information on time accounting. If multiple MzScheme threads are running, then the reported time may include work performed by other threads.

The `time` syntactic form reports timing information directly to the current output port:

- `(time `expr`)` times the evaluation of `expr`, printing timing information to the current output port. The result of the ``time`` expression is the result of `expr`.

## 15.2 Operating System Processes

`(subprocess``` `stdout-output-port stdin-input-port stderr-output-port command-path arg-string``` `···``)` creates a new process in the underlying operating system to execute `command-path` asynchronously. The `command-path` argument is a path to a program executable, and the `arg-string`s are command-line arguments for the program.

Under Mac OS Classic, arguments are not supported. However, a single `arg-string` argument triggers a hack specific to Mac OS Classic; in that case, `command-path` must be `"by-id"` and the `arg-string` argument is a four-character string specifying an application ID, which is used to find the application instead of an executable path.

Under Windows, the first `arg-string` can be `'exact`, which triggers a Windows-specific hack: the second `arg-string` is used exactly as the command-line for the subprocess, and no additional `arg-string`s can be supplied. Otherwise, a command-line string is constructed from `command-path` and `arg-string` so that a typical Windows console application can parse it back to an array of arguments.39 If `'exact` is provided on a non-Windows platform, the `exn:application:mismatch` exception is raised.

Unless it is `#f`, `stdout-output-port` is used for the launched process's standard output, `stdin-input-port` is used for the process's standard input, and `stderr-output-port` is used for the process's standard error. All provided ports must be file-stream ports. Any of the ports can be `#f`, in which case a system pipe is created and returned by ``subprocess``. For each port that is provided, no pipe is created and the corresponding returned value is `#f`.

The ``subprocess`` procedure returns four values:

- a subprocess value representing the create process;

- an input port piped from the process's standard output, or `#f` if `stdout-output-port` was a port;

- an output port piped to the process standard input, or `#f` if `stdin-input-port` was a port;

- an input port piped from the process's standard error, or `#f` if `stderr-output-port` was a port.

Important: All ports returned from ``subprocess`` must be explicitly closed with ``close-input-port`` and ``close-output-port``.

The returned ports are placed into the management of the current custodian (see section 9.2). The `exn:misc` exception is raised when a low-level error prevents the spawning of a process or the creation of operating system pipes for process communication.

A subprocess value can be used to obtain further information about the process:

- `(subprocess-wait``` `subprocess``)` blocks until the process terminates, then returns void.

- `(subprocess-status``` `subprocess``)` returns `'running` if the process is still running, or its exit code otherwise. The exit code is an exact integer, and `0` typically indicates success. If the process terminated due to a fault or signal, the exit code is non-zero.

- `(subprocess-kill``` `subprocess force?``)` terminates the subprocess if `force?` is true and if the process still running, then returns void. If an error occurs during termination, the `exn:misc` exception is raised.

  If `force?` is `#f` under Unix and Mac OS X, the subprocess is sent an interrupt signal instead of a kill signal (and the subprocess might handle the signal without terminating). Under Windows, no action is taken when `force?` is `#f`.

- `(subprocess-pid``` `subprocess``)` returns the operating system's numerical ID for the process (if any), valid only as long as the process is running. The ID is an exact integer. Under Mac OS Classic, the reported ID is always `0`.

- `(subprocess?``` `v``)` returns `#t` if `v` is a subprocess value, `#f` otherwise.

MzLib provides procedures for executing shell commands (as opposed to directly executing a program); see Chapter mz:mzlibprocess in PLT MzLib: Libraries Manual for details.

## 15.3 Windows Actions

`(shell-execute``` `verb-string target-string parameters-string dir-path show-mode-symbol``)` performs the action specified by `verb-string` on `target-string` in Windows. For example,

    (shell-execute #f "http://www.plt-scheme.org" "" (current-directory) 'sw_shownormal)

opens the PLT Scheme home page in a browser window. For platforms other than Windows, the `exn:misc:unsupported` exception is raised.

The `verb-string` can be `#f`, in which case the operating system will use a default verb. Common verbs include `"open"`, `"edit"`, `"find"`, `"explore"`, and `"print"`.

The `target-string` is the target for the action, usually a filename path. The file could be executable, or it could be a file with a recognized extension that can be handled by an installed application.

The `parameters-string` argument is passed on to the system to perform the action. For example, in the case of opening an executable, the `parameters-string` is used as the command line (after the executable name).

The `dir-path` is used as the current directory when performing the action.

The `show-mode-symbol` sets the display mode for an Window affected by the action. It must be one of the following symbols; the description of each symbol's meaning is taken from the Windows API documentation.

- `'sw_hide` -- Hides the window and activates another window.

- `'sw_maximize` -- Maximizes the window.

- `'sw_minimize` -- Minimizes the window and activates the next top-level window in the z-order.

- `'sw_restore` -- Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position.

- `'sw_show` -- Activates the window and displays it in its current size and position.

- `'sw_showdefault` -- Uses a default.

- `'sw_showmaximized` -- Activates the window and displays it as a maximized window.

- `'sw_showminimized` -- Activates the window and displays it as a minimized window.

- `'sw_showminnoactive` -- Displays the window as a minimized window. The active window remains active.

- `'sw_showna` -- Displays the window in its current state. The active window remains active.

- `'sw_shownoactivate` -- Displays a window in its most recent size and position. The active window remains active.

- `'sw_shownormal` -- Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position.

If the action fails, the `exn:misc` exception is raised. If the action succeeds, the result is `#f`. In future versions of MzScheme, the result may be a subprocess value (see section 15.2) if the operating system did returns a process handle (but if a subprocess value is returned, its process ID will be `0` instead of the real process ID).

## 15.4 Operating System Environment Variables

`(getenv``` `name-string``)` gets the value of an operating system environment variable. The `name-string` argument cannot contain a null character; if an environment variable named by `name-string` exists, its value is returned (as a string); otherwise, `#f` is returned.

`(putenv``` `name-string value-string``)` sets the value of an operating system environment variable. The `name-string` and `value-string` arguments are strings that cannot contain a null character; the environment variable named by `name-string` is set to `value-string`. The return value is `#t` if the assignment succeeds, `#f` otherwise.

Although Mac OS Classic does not have operating system environment variables, ``getenv`` returns values installed with ``putenv`` (which always succeeds) in the same MzScheme session. When MzScheme is started, an initial environment is read from an `Environment` file in the current directory if it exists. An `Environment` file must contain a sequence of two-item lists where the `name` string is the first item in the list and the `value` string is the second. For example, an `Environment` file might contain the following:

    ("PLTCOLLECTS" ";My Disk:Extra Collections:")
    ("USER" "joeuser")

## 15.5 Runtime Information

`(system-type``` [`details?`]`)` returns a symbol indicating the type of the operating system for a running MzScheme if `details?` is `#f` or not provided. The possible values are:

- `'unix`

- `'windows`

- `'macos`

- `'macosx`

- `'oskit`

Future ports of MzScheme will expand this list of system types. If `details?` is not `#f`, then the result is a string, which contains further details about the operating system and the current machine in a platform-specific format.

`(system-library-subpath``)` returns a relative directory pathname string. This string can be used to build pathnames to system-specific files. For example, when MzScheme is running under Solaris on a Sparc architecture, the subpath is `"sparc-solaris"`, while the subpath for Windows on an Intel architecture is `"win32\\i386"`.

`(version``)` returns an immutable string indicating the currently executing version of MzScheme.

`(banner``)` returns an immutable string for MzScheme's start-up banner text (or the banner text for an embedding program, such as MrEd). The banner string ends with a newline.

`(vector-set-performance-stats!``` `mutable-vector``)` sets elements in `mutable-vector` to report current performance statistics. Currently, up to 6 elements are set in the vector, starting from the begining. In the future versions of MzScheme, additional elements will be set. If `mutable-vector` has n elements where n < 6, then the n elements are set to the first n performance-statistics values. The reported statistics values are as follows, in the order that they are set within `mutable-vector`:

- `0`: The same value as returned by `current-process-milliseconds` (see section 15.1.2).

- `1`: The same value as returned by `current-milliseconds` (see section 15.1.2).

- `2`: The same value as returned by `current-gc-milliseconds` (see section 15.1.2).

- `3`; The number of garbage collections performed since start-up.

- `4`: The number of thread context switches performed since start-up.

- `5`: The number of internal stack overflows handled since start-up.

38 The value produced for the `time-zone-offset` field tends to be sensitive to the value of the `"TZ"` environment variable, especially on Unix platforms. Consult the system documentation (usually under `tzset`) for details.

39 For information on the Windows command-line conventions, search for ``command line parsing'' at `http://msdn.microsoft.com/`.