* poe.el (make-temp-file): New function.
authorteranisi <teranisi>
Thu, 15 May 2003 13:26:31 +0000 (13:26 +0000)
committerteranisi <teranisi>
Thu, 15 May 2003 13:26:31 +0000 (13:26 +0000)
ChangeLog
poe.el

index 78daf90..4d936c5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-05-15  Yuuichi Teranishi  <teranisi@gohome.org>
+
+       * poe.el (make-temp-file): New function.
+
 2002-11-05  MORIOKA Tomohiko  <tomo@kanji.zinbun.kyoto-u.ac.jp>
 
        * mcs-20.el (mcs-region-repertoire-p): New function for UTF-2000
        (minor-mode-map-alist): Ditto.
 
        * README.en ((d) make.bat (for MS-DOS family)): New section.
-       * README.ja ((d) make.bat \e$(B$rMxMQ$9$k\e(B (MS-DOS \e$(B7O\e(B OS \e$(B$N>l9g\e(B)):
+       * README.ja ((d) make.bat \e$B$rMxMQ$9$k\e(B (MS-DOS \e$B7O\e(B OS \e$B$N>l9g\e(B)):
        Ditto.
 
 2000-12-22  MORIOKA Tomohiko  <tomo@kanji.zinbun.kyoto-u.ac.jp>
 
        * APEL: Version 8.4 was released.
 
-       * EMU-ELS: Don't use HIRAGANA LETTER A (\e$(B$"\e(B) to detect character
+       * EMU-ELS: Don't use HIRAGANA LETTER A (\e$B$"\e(B) to detect character
        indexing (Emacs 20.3 or later).
 
 1998-04-20  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
diff --git a/poe.el b/poe.el
index 91447c1..c643cd3 100644 (file)
--- a/poe.el
+++ b/poe.el
@@ -1595,6 +1595,185 @@ See `walk-windows' for the meaning of MINIBUF and FRAME."
          (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "/tmp"))))
   "The directory for writing temporary files.")
 
+;; Emacs 21: Create a temporary file. (lisp/subr.el)
+;; Emacs 21.1-21.3
+;;  (make-temp-file PREFIX &optional DIR-FLAG)
+;; Emacs 21.3.x(?) and later
+;;  (make-temp-file PREFIX &optional DIR-FLAG SUFFIX)
+(static-condition-case nil
+    ;; compile-time check
+    (progn
+      (delete-file (make-temp-file "EMU" nil ".txt"))
+      (if (get 'make-temp-file 'defun-maybe)
+         (error "`make-temp-file' is already defined")))
+  (wrong-number-of-arguments ; Emacs 21.1-21.3
+   ;; load-time check.
+   ;; Replace original definition.
+   (or (fboundp 'si:make-temp-file)
+       (progn
+        (fset 'si:make-temp-file (symbol-function 'make-temp-file))
+        (put 'make-temp-file 'defun-maybe t)
+        (defun make-temp-file (prefix &optional dir-flag suffix)
+          "\
+Create a temporary file.
+The returned file name (created by appending some random characters at the end
+of PREFIX, and expanding against `temporary-file-directory' if necessary),
+is guaranteed to point to a newly created empty file.
+You can then use `write-region' to write new data into the file.
+
+If DIR-FLAG is non-nil, create a new empty directory instead of a file.
+
+If SUFFIX is non-nil, add that at the end of the file name."
+          (let ((umask (default-file-modes))
+                file)
+            (unwind-protect
+                (progn
+                  ;; Create temp files with strict access rights.  
+                  ;; It's easy toloosen them later, whereas it's impossible
+                  ;;  to close the time-window of loose permissions otherwise.
+                  (set-default-file-modes ?\700)
+                  (while (condition-case ()
+                             (progn
+                               (setq file
+                                     (make-temp-name
+                                      (expand-file-name
+                                       prefix temporary-file-directory)))
+                               (if suffix
+                                   (setq file (concat file suffix)))
+                               (if dir-flag
+                                   (make-directory file)
+                                 (write-region "" nil file nil
+                                               'silent nil 'excl))
+                               nil)
+                           (file-already-exists t))
+                    ;; the file was somehow created by someone else between
+                    ;; `make-temp-name' and `write-region', let's try again.
+                    nil)
+                  file)
+              ;; Reset the umask.
+              (set-default-file-modes umask))))
+        ;; for `load-history'.
+        (setq current-load-list (cons 'make-temp-file current-load-list)))))
+  (error)) ; found our definition or no definition at compile-time.
+
+;; For the Emacsen which don't have make-temp-file.
+(cond
+ ;; must be load-time check to share .elc between different systems.
+ ((fboundp 'make-temp-file))
+ ((memq system-type '(windows-nt ms-dos))
+  ;; For single-user systems:
+  (defun-maybe make-temp-file (prefix &optional dir-flag suffix)
+    "Create a temporary file.
+The returned file name (created by appending some random characters at the end
+of PREFIX, and expanding against `temporary-file-directory' if necessary),
+is guaranteed to point to a newly created empty file.
+You can then use `write-region' to write new data into the file.
+
+If DIR-FLAG is non-nil, create a new empty directory instead of a file.
+
+If SUFFIX is non-nil, add that at the end of the file name."
+    (let ((file (make-temp-name (expand-file-name prefix
+                                                 temporary-file-directory))))
+      (if suffix
+         (setq file (concat file suffix)))
+      (if dir-flag
+         (make-directory file)
+       (write-region "" nil file nil 'silent))
+      file)))
+ (t
+  (defun-maybe make-temp-file (prefix &optional dir-flag suffix)
+    "Create a temporary file.
+The returned file name (created by appending some random characters at the end
+of PREFIX, and expanding against `temporary-file-directory' if necessary),
+is guaranteed to point to a newly created empty file.
+You can then use `write-region' to write new data into the file.
+
+If DIR-FLAG is non-nil, create a new empty directory instead of a file.
+
+If SUFFIX is non-nil, add that at the end of the file name."
+    (let ((orig-mode (default-file-modes)))
+      (unwind-protect
+         (let ((prefix (expand-file-name prefix temporary-file-directory)))
+           ;; Create temp files with strict access rights.  It's easy to
+           ;; loosen them later, whereas it's impossible to close the
+           ;; time-window of loose permissions otherwise.
+           (set-default-file-modes 448)
+           (if dir-flag
+               ;; Create a new empty directory.
+               (let (dir)
+                 (while (condition-case ()
+                            (progn
+                              (setq dir (make-temp-name prefix))
+                              (if suffix
+                                  (setq dir (concat dir suffix)))
+                              (make-directory dir)
+                              ;; `make-directory' returns nil,
+                              ;; but we return nil explicitly.
+                              nil)
+                          (file-already-exists t))
+                   ;; the dir was somehow created by someone else between
+                   ;; `make-temp-name' and `make-directory', let's try again.
+                   )
+                 dir)
+             ;; Create a temporary file.
+             ;; First, create a temporary directory.
+             (let (tempdir)
+               (unwind-protect
+                   (let ((tempdir-prefix (concat
+                                          (file-name-directory prefix)
+                                          "DIR")))
+                     (while (condition-case ()
+                                (progn
+                                  (setq tempdir (make-temp-name
+                                                 tempdir-prefix))
+                                  (make-directory tempdir)
+                                  ;; `make-directory' returns nil,
+                                  ;; but we return nil explicitly.
+                                  nil)
+                              (file-already-exists t))
+                       ;; the tempdir was somehow created by someone else
+                       ;; between `make-temp-name' and `make-directory',
+                       ;; let's try again.
+                       )
+                     ;; Second, create a temporary file in the tempdir.
+                     (let (tempfile)
+                       (unwind-protect
+                           (let (file)
+                             (setq tempfile (make-temp-name
+                                             (concat tempdir "/EMU")))
+                             ;; There *is* a race condition between
+                             ;; `make-temp-file' and `write-region',
+                             ;; but we don't care it since we are in
+                             ;; a private directory now.
+                             (write-region "" nil tempfile nil 'silent)
+                             ;; Finally, make a hard-link from the tempfile.
+                             (while (condition-case ()
+                                        (progn
+                                          (setq file (make-temp-name prefix))
+                                          (if suffix
+                                              (setq file (concat
+                                                          file suffix)))
+                                          (add-name-to-file tempfile file)
+                                          ;; `add-name-to-file' returns nil,
+                                          ;; but we return nil explicitly.
+                                          nil)
+                                      (file-already-exists t))
+                               ;; the file was somehow created by someone else
+                               ;; between `make-temp-name' and
+                               ;; `add-name-to-file', let's try again.
+                               )
+                             file)
+                         ;; Cleanup the tempfile.
+                         (and tempfile
+                              (file-exists-p tempfile)
+                              (delete-file tempfile)))))
+                 ;; Cleanup the tempdir.
+                 (and tempdir
+                      (file-directory-p tempdir)
+                      (delete-directory tempdir))))))
+       ;; Reset the original file mode.
+       (set-default-file-modes orig-mode))))))
+
 ;; Actually, `path-separator' is defined in src/emacs.c and overrided
 ;; in dos-w32.el.
 (defvar-maybe path-separator ":"