/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996, 1997, 1998, 1999 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint static const char sccsid[] = "@(#)os_fid.c 11.1 (Sleepycat) 7/25/99"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES #include #include #if TIME_WITH_SYS_TIME #include #include #else #if HAVE_SYS_TIME_H #include #else #include #endif #endif #include #endif #include "db_int.h" /* * CDB___os_fileid -- * Return a unique identifier for a file. * * PUBLIC: int CDB___os_fileid __P((DB_ENV *, const char *, int, u_int8_t *)); */ int CDB___os_fileid(dbenv, fname, timestamp, fidp) DB_ENV *dbenv; const char *fname; int timestamp; u_int8_t *fidp; { struct stat sb; size_t i; u_int32_t tmp; u_int8_t *p; /* Clear the buffer. */ memset(fidp, 0, DB_FILE_ID_LEN); /* On POSIX/UNIX, use a dev/inode pair. */ if (stat(fname, &sb)) { CDB___db_err(dbenv, "%s: %s", fname, strerror(CDB___os_get_errno())); return (CDB___os_get_errno()); } /* * !!! * Nothing is ever big enough -- on Sparc V9, st_ino, st_dev and the * time_t types are all 8 bytes. As DB_FILE_ID_LEN is only 20 bytes, * we convert to a (potentially) smaller fixed-size type and use it. * * We don't worry about byte sexing or the actual variable sizes. * * When this routine is called from the DB access methods, it's only * called once -- whatever ID is generated when a database is created * is stored in the database file's metadata, and that is what is * saved in the mpool region's information to uniquely identify the * file. * * When called from the mpool layer this routine will be called each * time a new thread of control wants to share the file, which makes * things tougher. As far as byte sexing goes, since the mpool region * lives on a single host, there's no issue of that -- the entire * region is byte sex dependent. As far as variable sizes go, we make * the simplifying assumption that 32-bit and 64-bit processes will * get the same 32-bit values if we truncate any returned 64-bit value * to a 32-bit value. */ tmp = (u_int32_t)sb.st_ino; for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) *fidp++ = *p++; tmp = (u_int32_t)sb.st_dev; for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) *fidp++ = *p++; if (timestamp) { /* * We want the number of seconds, not the high-order 0 bits, * so convert the returned time_t to a (potentially) smaller * fixed-size type. */ tmp = (u_int32_t)time(NULL); for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) *fidp++ = *p++; } return (0); }