示例#1
0
static int FSWrite(const char *destination, int dd, const char *buf, size_t n_write)
{
    const void *cur = buf;
    const void *end = buf + n_write;

    while (cur < end)
    {
        const void *skip_span = MemSpan(cur, 0, end - cur);
        if (skip_span > cur)
        {
            if (lseek(dd, skip_span - cur, SEEK_CUR) < 0)
            {
                Log(LOG_LEVEL_ERR, "Copy failed (no space?) while copying to '%s' from network '%s'", destination, GetErrorStr());
                return false;
            }

            cur = skip_span;
        }

        const void *copy_span = MemSpanInverse(cur, 0, end - cur);
        if (copy_span > cur)
        {
            if (FullWrite(dd, cur, copy_span - cur) < 0)
            {
                Log(LOG_LEVEL_ERR, "Copy failed (no space?) while copying to '%s' from network '%s'", destination, GetErrorStr());
                return false;
            }

            cur = copy_span;
        }
    }

    return true;
}
示例#2
0
/*
 * Copy data jumping over areas filled by '\0', so files automatically become sparse if possible.
 */
static bool CopyData(const char *source, int sd, const char *destination, int dd, char *buf, size_t buf_size)
{
    off_t n_read_total = 0;

    while (true)
    {
        ssize_t n_read = read(sd, buf, buf_size);

        if (n_read == -1)
        {
            if (errno == EINTR)
            {
                continue;
            }

            CfOut(OUTPUT_LEVEL_ERROR, "read", "Unable to read source file while doing %s to %s", source, destination);
            return false;
        }

        if (n_read == 0)
        {
            /*
             * As the tail of file may contain of bytes '\0' (and hence
             * lseek(2)ed on destination instead of being written), do a
             * ftruncate(2) here to ensure the whole file is written to the
             * disc.
             */
            if (ftruncate(dd, n_read_total) < 0)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "ftruncate", "Copy failed (no space?) while doing %s to %s", source, destination);
                return false;
            }

            return true;
        }

        n_read_total += n_read;

        /* Copy/seek */

        void *cur = buf;
        void *end = buf + n_read;

        while (cur < end)
        {
            void *skip_span = MemSpan(cur, 0, end - cur);
            if (skip_span > cur)
            {
                if (lseek(dd, skip_span - cur, SEEK_CUR) < 0)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "lseek", "Copy failed (no space?) while doing %s to %s", source, destination);
                    return false;
                }

                cur = skip_span;
            }


            void *copy_span = MemSpanInverse(cur, 0, end - cur);
            if (copy_span > cur)
            {
                if (FullWrite(dd, cur, copy_span - cur) < 0)
                {
                    CfOut(OUTPUT_LEVEL_ERROR, "write", "Copy failed (no space?) while doing %s to %s", source, destination);
                    return false;
                }

                cur = copy_span;
            }
        }
    }
}