Ejemplo n.º 1
0
struct ref *fetch_pack(struct fetch_pack_args *my_args,
		       int fd[], struct child_process *conn,
		       const struct ref *ref,
		const char *dest,
		int nr_heads,
		char **heads,
		char **pack_lockfile)
{
	struct stat st;
	struct ref *ref_cpy;

	fetch_pack_setup();
	if (&args != my_args)
		memcpy(&args, my_args, sizeof(args));
	if (args.depth > 0) {
		if (stat(git_path("shallow"), &st))
			st.st_mtime = 0;
	}

	if (heads && nr_heads)
		nr_heads = remove_duplicates(nr_heads, heads);
	if (!ref) {
		packet_flush(fd[1]);
		die("no matching remote head");
	}
	ref_cpy = do_fetch_pack(fd, ref, nr_heads, heads, pack_lockfile);

	if (args.depth > 0) {
		struct cache_time mtime;
		struct strbuf sb = STRBUF_INIT;
		char *shallow = git_path("shallow");
		int fd;

		mtime.sec = st.st_mtime;
		mtime.nsec = ST_MTIME_NSEC(st);
		if (stat(shallow, &st)) {
			if (mtime.sec)
				die("shallow file was removed during fetch");
		} else if (st.st_mtime != mtime.sec
#ifdef USE_NSEC
				|| ST_MTIME_NSEC(st) != mtime.nsec
#endif
			  )
			die("shallow file was changed during fetch");

		fd = hold_lock_file_for_update(&lock, shallow,
					       LOCK_DIE_ON_ERROR);
		if (!write_shallow_commits(&sb, 0)
		 || write_in_full(fd, sb.buf, sb.len) != sb.len) {
			unlink_or_warn(shallow);
			rollback_lock_file(&lock);
		} else {
			commit_lock_file(&lock);
		}
		strbuf_release(&sb);
	}

	reprepare_packed_git();
	return ref_cpy;
}
Ejemplo n.º 2
0
static void ConvertFileStatus(const struct stat_* src, FileStatus* dst)
{
    dst->Dev = (int64_t)src->st_dev;
    dst->Ino = (int64_t)src->st_ino;
    dst->Flags = FILESTATUS_FLAGS_NONE;
    dst->Mode = (int32_t)src->st_mode;
    dst->Uid = src->st_uid;
    dst->Gid = src->st_gid;
    dst->Size = src->st_size;

    dst->ATime = src->st_atime;
    dst->MTime = src->st_mtime;
    dst->CTime = src->st_ctime;

    dst->ATimeNsec = ST_ATIME_NSEC(src);
    dst->MTimeNsec = ST_MTIME_NSEC(src);
    dst->CTimeNsec = ST_CTIME_NSEC(src);

#if HAVE_STAT_BIRTHTIME
    dst->BirthTime = src->st_birthtimespec.tv_sec;
    dst->BirthTimeNsec = src->st_birthtimespec.tv_nsec;
    dst->Flags |= FILESTATUS_FLAGS_HAS_BIRTHTIME;
#else
    // Linux path: until we use statx() instead
    dst->BirthTime = 0;
    dst->BirthTimeNsec = 0;
#endif
}
Ejemplo n.º 3
0
static void
maildir_sync_index_update_ext_header(struct maildir_index_sync_context *ctx)
{
	struct maildir_mailbox *mbox = ctx->mbox;
	const char *cur_path;
	const void *data;
	size_t data_size;
	struct stat st;

	cur_path = t_strconcat(mailbox_get_path(&mbox->box), "/cur", NULL);
	if (ctx->update_maildir_hdr_cur && stat(cur_path, &st) == 0) {
		if ((time_t)mbox->maildir_hdr.cur_check_time < st.st_mtime)
			mbox->maildir_hdr.cur_check_time = st.st_mtime;
		mbox->maildir_hdr.cur_mtime = st.st_mtime;
		mbox->maildir_hdr.cur_mtime_nsecs = ST_MTIME_NSEC(st);
	}

	mail_index_get_header_ext(mbox->box.view, mbox->maildir_ext_id,
				  &data, &data_size);
	if (data_size != sizeof(mbox->maildir_hdr) ||
	    maildir_index_header_has_changed(data, &mbox->maildir_hdr)) {
		mail_index_update_header_ext(ctx->trans, mbox->maildir_ext_id,
					     0, &mbox->maildir_hdr,
					     sizeof(mbox->maildir_hdr));
	}
}
Ejemplo n.º 4
0
void check_shallow_file_for_update(void)
{
	struct stat st;

	if (!is_shallow)
		return;
	else if (is_shallow == -1)
		die("BUG: shallow must be initialized by now");

	if (stat(git_path("shallow"), &st))
		die("shallow file was removed during fetch");
	else if (st.st_mtime != shallow_stat.st_mtime
#ifdef USE_NSEC
		 || ST_MTIME_NSEC(st) != ST_MTIME_NSEC(shallow_stat)
#endif
		   )
		die("shallow file was changed during fetch");
}
Ejemplo n.º 5
0
int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd)
{
    int inFd = ToFileDescriptor(sourceFd);
    int outFd = ToFileDescriptor(destinationFd);

#if HAVE_FCOPYFILE
    // If fcopyfile is available (OS X), try to use it, as the whole copy
    // can be performed in the kernel, without lots of unnecessary copying.
    // Copy data and metadata.
    return fcopyfile(inFd, outFd, NULL, COPYFILE_ALL) == 0 ? 0 : -1;
#else
    // Get the stats on the source file.
    int ret;
    struct stat_ sourceStat;
    bool copied = false;
#if HAVE_SENDFILE_4
    // If sendfile is available (Linux), try to use it, as the whole copy
    // can be performed in the kernel, without lots of unnecessary copying.
    while ((ret = fstat_(inFd, &sourceStat)) < 0 && errno == EINTR);
    if (ret != 0)
    {
        return -1;
    }


    // On 32-bit, if you use 64-bit offsets, the last argument of `sendfile' will be a
    // `size_t' a 32-bit integer while the `st_size' field of the stat structure will be off64_t.
    // So `size' will have to be `uint64_t'. In all other cases, it will be `size_t'.
    uint64_t size = (uint64_t)sourceStat.st_size;

    // Note that per man page for large files, you have to iterate until the
    // whole file is copied (Linux has a limit of 0x7ffff000 bytes copied).
    while (size > 0)
    {
        ssize_t sent = sendfile(outFd, inFd, NULL, (size >= SSIZE_MAX ? SSIZE_MAX : (size_t)size));
        if (sent < 0)
        {
            if (errno != EINVAL && errno != ENOSYS)
            {
                return -1;
            }
            else
            {
                break;
            }
        }
        else
        {
            assert((size_t)sent <= size);
            size -= (size_t)sent;
        }
    }
    if (size == 0)
    {
        copied = true;
    }
    // sendfile couldn't be used; fall back to a manual copy below. This could happen
    // if we're on an old kernel, for example, where sendfile could only be used
    // with sockets and not regular files.
#endif // HAVE_SENDFILE_4

    // Manually read all data from the source and write it to the destination.
    if (!copied && CopyFile_ReadWrite(inFd, outFd) != 0)
    {
        return -1;
    }

    // Now that the data from the file has been copied, copy over metadata
    // from the source file.  First copy the file times.
    // If futimes nor futimes are available on this platform, file times will
    // not be copied over.
    while ((ret = fstat_(inFd, &sourceStat)) < 0 && errno == EINTR);
    if (ret == 0)
    {
#if HAVE_FUTIMES
        struct timeval origTimes[2];
        origTimes[0].tv_sec = sourceStat.st_atime;
        origTimes[0].tv_usec = ST_ATIME_NSEC(&sourceStat) / 1000;
        origTimes[1].tv_sec = sourceStat.st_mtime;
        origTimes[1].tv_usec = ST_MTIME_NSEC(&sourceStat) / 1000;
        while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR);
#elif HAVE_FUTIMENS
        // futimes is not a POSIX function, and not available on Android,
        // but futimens is
        struct timespec origTimes[2];
        origTimes[0].tv_sec = (time_t)sourceStat.st_atime;
        origTimes[0].tv_nsec = ST_ATIME_NSEC(&sourceStat);
        origTimes[1].tv_sec = (time_t)sourceStat.st_mtime;
        origTimes[1].tv_nsec = ST_MTIME_NSEC(&sourceStat);
        while ((ret = futimens(outFd, origTimes)) < 0 && errno == EINTR);
#endif
    }
    if (ret != 0)
    {
        return -1;
    }

    // Then copy permissions.
    while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR);
    if (ret != 0)
    {
        return -1;
    }

    return 0;
#endif // HAVE_FCOPYFILE
}