+EC_CLEANUP:
+ if (cwd != -1) {
+ if (fchdir(cwd) != 0) {
+ AFP_PANIC("ad_flush: cant fchdir");
+ }
+ close(cwd);
+ }
+ EC_EXIT;
+}
+
+/* Flush resofork adouble file if any (currently adouble:ea and #ifndef HAVE_EAFD eg Linux) */
+static int ad_flush_rf(struct adouble *ad)
+{
+ ssize_t len;
+ char adbuf[AD_DATASZ_OSX];
+
+#ifdef HAVE_EAFD
+ return 0;
+#endif
+ if (ad->ad_vers != AD_VERSION_EA)
+ return 0;
+
+ LOG(log_debug, logtype_ad, "ad_flush_rf(%s)", adflags2logstr(ad->ad_adflags));
+
+ if ((ad->ad_rfp->adf_flags & O_RDWR)) {
+ if (ad_getentryoff(ad, ADEID_RFORK)) {
+ if (ad->ad_rlen > 0xffffffff)
+ ad_setentrylen(ad, ADEID_RFORK, 0xffffffff);
+ else
+ ad_setentrylen(ad, ADEID_RFORK, ad->ad_rlen);
+ }
+ len = ad_rebuild_adouble_header_osx(ad, &adbuf[0]);
+
+ if (adf_pwrite(ad->ad_rfp, adbuf, len, 0) != len) {
+ if (errno == 0)
+ errno = EIO;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int ad_flush(struct adouble *ad)
+{
+ EC_INIT;
+
+ LOG(log_debug, logtype_ad, "ad_flush(%s)", adflags2logstr(ad->ad_adflags));
+
+ if (AD_META_OPEN(ad)) {
+ EC_ZERO( ad_flush_hf(ad) );
+ }
+
+ if (AD_RSRC_OPEN(ad)) {
+ EC_ZERO( ad_flush_rf(ad) );
+ }
+
+EC_CLEANUP:
+ EC_EXIT;
+}
+
+static int ad_data_closefd(struct adouble *ad)
+{
+ int ret = 0;
+
+ if (ad_data_fileno(ad) == AD_SYMLINK) {
+ free(ad->ad_data_fork.adf_syml);
+ ad->ad_data_fork.adf_syml = NULL;
+ } else {
+ if (close(ad_data_fileno(ad)) < 0)
+ ret = -1;
+ }
+ ad_data_fileno(ad) = -1;
+ return ret;