@c @node Local package nicknames
@c @section Local package nicknames

@c @node Hierarchical packages
@c @section Hierarchical packages

@node Package locks
@section Package locks

@menu
* Package Locking Overview::       
* Operations Violating Package Locks::  
* Package Lock Dictionary::
@end menu

@cindex Package locks
@ftindex PACKAGE-LOCKS

@node Package Locking Overview
@subsection 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
@code{package-locks}:

@lisp
(require '#:package-locks)
@end lisp

Package locks protect against unintentional modifications of a package:
they provide similar protection to user packages as is mandated to
@code{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 @code{:lock}
option to @code{defpackage}).

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

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

@node Operations Violating Package Locks
@subsection Operations Violating Package Locks

The following actions cause a package lock violation if the package
operated on is locked, and @code{*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 @code{package-error}.

@enumerate
@item
Shadowing a symbol in a package.

@item
Importing a symbol to a package.

@item
Uninterning a symbol from a package.

@item
Exporting a symbol from a package.

@item
Unexporting a symbol from a package.

@item
Changing the packages used by a package.

@item
Renaming a package.

@item
Deleting a package.

@item
Attempting to redefine a function in a locked package.

@item
Adding a new package local nickname to a package.

@item
Removing an existing package local nickname to a package.

@end enumerate

@node Package Lock Dictionary
@subsection Package Lock Dictionary

@lspindex ext:package-locked-p
@defun ext:package-locked-p package
Returns @code{t} when @code{package} is locked, @code{nil}
otherwise. Signals an error if @code{package} doesn’t designate a valid
package.
@end defun

@lspindex ext:lock-package
@defun ext:lock-package package
Locks @code{package} and returns @code{t}. Has no effect if package was
already locked. Signals an error if package is not a valid
@code{package} designator
@end defun

@lspindex ext:unlock-package
@defun ext:unlock-package package
Unlocks @code{package} and returns @code{t}. Has no effect if
@code{package} was already unlocked. Signals an error if @code{package}
is not a valid package designator.
@end defun

@lspindex ext:without-package-locks
@defmac ext:without-package-locks &body body
Ignores all runtime package lock violations during the execution of
body. Body can begin with declarations.
@end defmac

@lspindex ext:with-unlocked-packages
@defmac ext:with-unlocked-packages (&rest packages) &body body
Unlocks @code{packages} for the dynamic scope of the
@code{body}. Signals an error if any of @code{packages} is not a valid
package designator.
@end defmac

@defmac cl:defpackage name [[option]]* @result{} package

Options are extended to include the following:

@itemize
@item
@code{:lock} @var{boolean}

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

@end itemize

@exindex Defpackage @code{:lock} option
Example:

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

;;; is equivalent to

(defpackage "FOO") (:export "BAR"))
(lock-package "FOO")
@end lisp
@end defmac
