+
+/* -------------------------
+*/
+static int ad_fcntl_tmplock(struct adouble *ad, const u_int32_t eid, const int locktype,
+ const off_t off, const off_t len, const int fork)
+{
+ struct flock lock;
+ struct ad_fd *adf;
+ int err;
+ int type;
+
+ lock.l_start = off;
+ type = locktype;
+ if (eid == ADEID_DFORK) {
+ adf = &ad->ad_data_fork;
+ } else {
+ /* FIXME META */
+ adf = &ad->ad_resource_fork;
+ if (adf->adf_fd == -1) {
+ /* there's no resource fork. return success */
+ return 0;
+ }
+ /* if ADLOCK_FILELOCK we want a lock from offset 0
+ * it's used when deleting a file:
+ * in open we put read locks on meta datas
+ * in delete a write locks on the whole file
+ * so if the file is open by somebody else it fails
+ */
+ if (!(type & ADLOCK_FILELOCK))
+ lock.l_start += ad_getentryoff(ad, eid);
+ }
+
+ if (!(adf->adf_flags & O_RDWR) && (type & ADLOCK_WR)) {
+ type = (type & ~ADLOCK_WR) | ADLOCK_RD;
+ }
+
+ lock.l_type = XLATE_FCNTL_LOCK(type & ADLOCK_MASK);
+ lock.l_whence = SEEK_SET;
+ lock.l_len = len;
+
+ /* see if it's locked by another fork. */
+ if (fork && adf_findxlock(adf, fork, ADLOCK_WR |
+ ((type & ADLOCK_WR) ? ADLOCK_RD : 0),
+ lock.l_start, lock.l_len) > -1) {
+ errno = EACCES;
+ return -1;
+ }
+
+ /* okay, we might have ranges byte-locked. we need to make sure that
+ * we restore the appropriate ranges once we're done. so, we check
+ * for overlap on an unlock and relock.
+ * XXX: in the future, all the byte locks will be sorted and contiguous.
+ * we just want to upgrade all the locks and then downgrade them
+ * here. */
+ if (!adf->adf_excl) {
+ err = set_lock(adf->adf_fd, F_SETLK, &lock);
+ }
+ else {
+ err = 0;
+ }
+ if (!err && (lock.l_type == F_UNLCK))
+ adf_relockrange(adf, adf->adf_fd, lock.l_start, len);
+
+ return err;
+}
+
+/* --------------------- */
+static void ad_fcntl_unlock(struct adouble *ad, const int fork)
+{
+ if (ad_data_fileno(ad) != -1) {
+ adf_unlock(&ad->ad_data_fork, fork);
+ }
+ if (ad_reso_fileno(ad) != -1) {
+ adf_unlock(&ad->ad_resource_fork, fork);
+ }
+
+ if (ad->ad_flags != AD_VERSION_EA) {
+ return;
+ }
+ if (ad_meta_fileno(ad) != -1) {
+ adf_unlock(&ad->ad_metadata_fork, fork);
+ }
+}
+
+/******************************************************************************
+ * Public functions
+ ******************************************************************************/
+