I need to copy a directory tree that holds Unix socket files somewhere inside. As Unix sockets cannot be copied, when I use copy-directory
, the copy-file
function used by copy-directory
throws an error because it cannot copy the Unix socket file.
In an attempt to resolve that problem I wrote a advice for copy-file
, called copy-only-file
that copies only files, and skip Unix sockets:
(defun copy-only-file (file newname
&optional
ok-if-already-exists
keep-time
preserve-uid-gid
preserve-permissions)
"Copy files but not Unix sockets."
(unless (unix-socket-p file)
(copy-file file newname ok-if-already-exists keep-time
preserve-uid-gid preserve-permissions)))
Then later, inside another function, the code sets up the advice temporarily to copy the directory tree:
;; inside some function...
(advice-add 'copy-file :override #'copy-only-file)
(copy-directory (directory-file-name source-dirpath)
(directory-file-name destination-dirpath))
(advice-remove 'copy-file #'copy-only-file)
This being a recursive call, running the code causes too many recursions and the code eventually fails with the error (error Lisp nesting exceeds ‘max-lisp-eval-depth’)
I thought of using a :before
advice to filter out files that would be Unix socket files, but then is it possible to not call the function being advised when some criteria is met? Or would I have to pass the same file to the FILE and NEWFILE argument of copy-file
so that no copy is done because OK-IF-ALREADY-EXISTS would be nil?
I have also thought about re-defining the function using defalias to keep access to the original copy-file
:
(defalias 'original-copy-file #'copy-file)
(defun copy-file (file newname
&optional
ok-if-already-exists
keep-time
preserve-uid-gid
preserve-permissions)
"Copy files but not Unix sockets."
(unless (socket-p file)
(original-copy-file file newname ok-if-already-exists keep-time preserve-uid-gid preserve-permissions)))
That seems to work, but is it guaranteed to always work? It feels like a kludge to me. And I'm not clear on how I would restore the original copy-file
.
What is the proper way to handle this type of scenario?
:override
advice to clobber a function definition and subsequently restore it. There are other options, but that's the nicest method IMO, as it's both easy and visible.M-x report-emacs-bug
if I were you. It seems reasonable to provide users with a way to handle the presence of sockets and/or other similar things.