gint main (gint argc, gchar **argv) { gint id1, id2; d(printf("locking started\n")); lock_helper_init (); id1 = camel_lock_helper_lock("1 path 1"); if (id1 != -1) { d(printf("lock ok, unlock\n")); camel_lock_helper_unlock (id1); } id1 = camel_lock_helper_lock("2 path 1"); id2 = camel_lock_helper_lock("2 path 2"); camel_lock_helper_unlock (id2); camel_lock_helper_unlock (id1); id1 = camel_lock_helper_lock("3 path 1"); id2 = camel_lock_helper_lock("3 path 2"); camel_lock_helper_unlock (id1); }
static int spool_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) { int retry = 0; CamelMboxFolder *mf = (CamelMboxFolder *)lf; CamelSpoolFolder *sf = (CamelSpoolFolder *)lf; mf->lockfd = open(lf->folder_path, O_RDWR, 0); if (mf->lockfd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create folder lock on %s: %s"), lf->folder_path, g_strerror (errno)); return -1; } while (retry < CAMEL_LOCK_RETRY) { if (retry > 0) sleep(CAMEL_LOCK_DELAY); camel_exception_clear(ex); if (camel_lock_fcntl(mf->lockfd, type, ex) == 0) { if (camel_lock_flock(mf->lockfd, type, ex) == 0) { if ((sf->lockid = camel_lock_helper_lock(lf->folder_path, ex)) != -1) return 0; camel_unlock_flock(mf->lockfd); } camel_unlock_fcntl(mf->lockfd); } retry++; } close (mf->lockfd); mf->lockfd = -1; return -1; }
/** * camel_movemail: * @source: source file * @dest: destination file * @error: return location for a #GError, or %NULL * * This copies an mbox file from a shared directory with multiple * readers and writers into a private (presumably Camel-controlled) * directory. Dot locking is used on the source file (but not the * destination). * * Return Value: Returns -1 on error or 0 on success. **/ gint camel_movemail (const gchar *source, const gchar *dest, GError **error) { gint lockid = -1; gint res = -1; gint sfd, dfd; struct stat st; /* open files */ sfd = open (source, O_RDWR); if (sfd == -1 && errno != ENOENT) { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Could not open mail file %s: %s"), source, g_strerror (errno)); return -1; } else if (sfd == -1) { /* No mail. */ return 0; } /* Stat the spool file. If it doesn't exist or * is empty, the user has no mail. (There's technically a race * condition here in that an MDA might have just now locked it * to deliver a message, but we don't care. In that case, * assuming it's unlocked is equivalent to pretending we were * called a fraction earlier.) */ if (fstat (sfd, &st) == -1) { close (sfd); g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Could not check mail file %s: %s"), source, g_strerror (errno)); return -1; } if (st.st_size == 0) { close (sfd); return 0; } dfd = open (dest, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); if (dfd == -1) { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Could not open temporary mail file %s: %s"), dest, g_strerror (errno)); close (sfd); return -1; } /* lock our source mailbox */ lockid = camel_lock_helper_lock (source, error); if (lockid == -1) { close (sfd); close (dfd); return -1; } #ifdef ENABLE_BROKEN_SPOOL res = camel_movemail_solaris (sfd, dfd, ex); #else res = camel_movemail_copy_file (sfd, dfd, error); #endif /* If no errors occurred copying the data, and we successfully * close the destination file, then truncate the source file. */ if (res != -1) { if (close (dfd) == 0) { CHECK_CALL (ftruncate (sfd, 0)); } else { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Failed to store mail in temp file %s: %s"), dest, g_strerror (errno)); res = -1; } } else close (dfd); close (sfd); camel_lock_helper_unlock (lockid); return res; }