3.11 Package locks

3.11.1 Package Locking Overview

ECL borrows parts of the protocol and documentation from SBCL for compatibility. Interface is the same except that the home package for locking is ext and that ECL doesn’t implement Implementation Packages and a few constructs. To load the extension you need to require package-locks:

(require '#:package-locks)

Package locks protect against unintentional modifications of a package: they provide similar protection to user packages as is mandated to common-lisp package by the ANSI specification. They are not, and should not be used as, a security measure.

Newly created packages are by default unlocked (see the :lock option to defpackage).

The package common-lisp and ECL internal implementation packages are locked by default, including ext.

It may be beneficial to lock common-lisp-user as well, to ensure that various libraries don’t pollute it without asking, but this is not currently done by default.

3.11.2 Operations Violating Package Locks

The following actions cause a package lock violation if the package operated on is locked, and *package* is not an implementation package of that package, and the action would cause a change in the state of the package (so e.g. exporting already external symbols is never a violation). Package lock violations caused by these operations signal errors of type package-error.

  1. Shadowing a symbol in a package.
  2. Importing a symbol to a package.
  3. Uninterning a symbol from a package.
  4. Exporting a symbol from a package.
  5. Unexporting a symbol from a package.
  6. Changing the packages used by a package.
  7. Renaming a package.
  8. Deleting a package.
  9. Attempting to redefine a function in a locked package.
  10. Adding a new package local nickname to a package.
  11. Removing an existing package local nickname to a package.

3.11.3 Package Lock Dictionary

Function: ext:package-locked-p package

Returns t when package is locked, nil otherwise. Signals an error if package doesn’t designate a valid package.

Function: ext:lock-package package

Locks package and returns t. Has no effect if package was already locked. Signals an error if package is not a valid package designator

Function: ext:unlock-package package

Unlocks package and returns t. Has no effect if package was already unlocked. Signals an error if package is not a valid package designator.

Macro: ext:without-package-locks &body body

Ignores all runtime package lock violations during the execution of body. Body can begin with declarations.

Macro: ext:with-unlocked-packages (&rest packages) &body body

Unlocks packages for the dynamic scope of the body. Signals an error if any of packages is not a valid package designator.

Macro: cl:defpackage name [[option]]* ⇒ package

Options are extended to include

    :lock boolean

If the argument to :lock is t, the package is initially locked. If :lock is not provided it defaults to nil.

Example:

(defpackage "FOO" (:export "BAR") (:lock t))

;;; is equivalent to

(defpackage "FOO") (:export "BAR"))
(lock-package "FOO")