Example #1
0
int bee_flock(char *filename, int operation, int flags)
{
    int res;
    int fd, fd2;
    struct stat statbuf_pre, statbuf_post;

    fd = open_and_stat(filename, O_RDONLY|O_CREAT|O_NOCTTY, 0666, &statbuf_pre);
    if (fd < 0)
        return -1;

    while (1) {
        res = bee_flock_fd(fd, operation, 0);
        if (res < 0)
            return -1;

        fd2 = open_and_stat(filename, O_RDONLY|O_CREAT|O_NOCTTY, 0666, &statbuf_post);
        if (fd2 < 0) {
            bee_flock_close(fd);
            return -1;
        }

        if (statbuf_pre.st_ino == statbuf_post.st_ino) {
            res = close(fd2);
            if (res < 0) {
                perror("bee_flock: close");
                bee_flock_close(fd);
                return -1;
            }
            return fd;
        }

        res = bee_flock_close(fd);
        if (res < 0) {
            res = close(fd2);
            if (res < 0)
                perror("bee_flock: close");
            return -1;
        }
        fd = fd2;
        statbuf_pre = statbuf_post;
    }

    return -1;
}
int main(int argc, char *argv[])
{
	int ret;
	int fd;
	off_t length;
	pid_t pid;
	struct stat prev_stat;

	if (argc != 3) {
		printf("usage: %s path <length>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	fd = open_and_stat(argv[1], &prev_stat);
	if (fd == -1)
		exit(EXIT_FAILURE);

	length = atoi(argv[2]);

	pid = fork();
	if (pid == -1) {
		perror("fork");
		ret = -1;
		goto exit;
	}

	if (pid == 0) {
		/* child */
		ret = testftruncate(fd, length);
	} else {
		/* parent */
		ret = check_end_child_status(pid);
		if (ret)
			goto exit;

		ret = check_changes(fd, &prev_stat, length);
		if (ret)
			goto exit;
	}

exit:
	close_and_exit(fd, ret);

	/* never reached */
	return 0;
}