Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

os_unlink.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1997-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: os_unlink.c,v 12.7 2005/10/20 18:57:08 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <string.h>
00016 #endif
00017 
00018 #include "db_int.h"
00019 
00020 /*
00021  * __os_region_unlink --
00022  *      Remove a shared memory object file.
00023  */
00024 int
00025 __os_region_unlink(dbenv, path)
00026         DB_ENV *dbenv;
00027         const char *path;
00028 {
00029         if (F_ISSET(dbenv, DB_ENV_OVERWRITE))
00030                 (void)__db_file_multi_write(dbenv, path);
00031 
00032         return (__os_unlink(dbenv, path));
00033 }
00034 
00035 /*
00036  * __os_unlink --
00037  *      Remove a file.
00038  *
00039  * PUBLIC: int __os_unlink __P((DB_ENV *, const char *));
00040  */
00041 int
00042 __os_unlink(dbenv, path)
00043         DB_ENV *dbenv;
00044         const char *path;
00045 {
00046         HANDLE h;
00047         _TCHAR *tpath, *orig_tpath, buf[MAXPATHLEN];
00048         u_int32_t id;
00049         int ret;
00050 
00051         if (DB_GLOBAL(j_unlink) != NULL) {
00052                 ret = DB_GLOBAL(j_unlink)(path);
00053                 goto done;
00054         }
00055 
00056         TO_TSTRING(dbenv, path, tpath, ret);
00057         if (ret != 0)
00058                 return (ret);
00059         orig_tpath = tpath;
00060 
00061         /*
00062          * Windows NT and its descendents allow removal of open files, but the
00063          * DeleteFile Win32 system call isn't equivalent to a POSIX unlink.
00064          * Firstly, it only succeeds if FILE_SHARE_DELETE is set when the file
00065          * is opened.  Secondly, it leaves the file in a "zombie" state, where
00066          * it can't be opened again, but a new file with the same name can't be
00067          * created either.
00068          *
00069          * Since we depend on being able to recreate files (during recovery,
00070          * say), we have to first rename the file, and then delete it.  It
00071          * still hangs around, but with a name we don't care about.  The rename
00072          * will fail if the file doesn't exist, which isn't a problem, but if
00073          * it fails for some other reason, we need to know about it or a
00074          * subsequent open may fail for no apparent reason.
00075          */
00076         if (__os_is_winnt()) {
00077                 __os_unique_id(dbenv, &id);
00078                 _sntprintf(buf, MAXPATHLEN, _T("%s.del.%010u"), tpath, id);
00079                 if (MoveFile(tpath, buf))
00080                         tpath = buf;
00081                 else if (__os_get_errno() != ENOENT)
00082                         __db_err(dbenv,
00083                             "unlink: rename %s to temporary file failed", path);
00084 
00085                 /*
00086                  * Try removing the file using the delete-on-close flag.  This
00087                  * plays nicer with files that are still open than DeleteFile.
00088                  */
00089                 h = CreateFile(tpath, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
00090                     FILE_FLAG_DELETE_ON_CLOSE, 0);
00091                 if (h != INVALID_HANDLE_VALUE) {
00092                         (void)CloseHandle (h);
00093                         if (GetFileAttributes(tpath) == INVALID_FILE_ATTRIBUTES)
00094                                 goto skipdel;
00095                 }
00096         }
00097 
00098         RETRY_CHK((!DeleteFile(tpath)), ret);
00099 
00100 skipdel:
00101         FREE_STRING(dbenv, orig_tpath);
00102 
00103         /*
00104          * XXX
00105          * We shouldn't be testing for an errno of ENOENT here, but ENOENT
00106          * signals that a file is missing, and we attempt to unlink things
00107          * (such as v. 2.x environment regions, in DB_ENV->remove) that we
00108          * are expecting not to be there.  Reporting errors in these cases
00109          * is annoying.
00110          */
00111 done:   if (ret != 0 && ret != ENOENT)
00112                 __db_err(dbenv, "unlink: %s: %s", path, strerror(ret));
00113 
00114         return (ret);
00115 }

Generated on Sun Dec 25 12:14:42 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2