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);
}
Example #2
0
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;
}