#include #include #include #include #include #include #define RETRY(V, X) do { \ int return_value_; \ do { \ return_value_ = (X); \ } while (return_value_ == -1 && errno == EINTR); \ (V) = return_value_; \ } while (0) int System_IO_Lock_get_lock_async(int *got, int *release, int fd, int exclusive, short whence, off_t start, off_t len) { int in[2], out[2]; pid_t pid; int r, e; RETRY(r, pipe(in)); if (r) { return -1; } RETRY(r, pipe(out)); if (r) { close(in[0]); close(in[1]); return -1; } switch ((pid = fork())) { case -1: return -1; case 0: RETRY(r, close(in[0])); RETRY(r, close(out[1])); switch (fork()) { case -1: e = errno; RETRY(r, write(in[1], &e, sizeof e)); _exit(1); case 0: { struct flock fl; fl.l_type = exclusive ? F_WRLCK : F_RDLCK; fl.l_whence = whence; fl.l_start = start; fl.l_len = len; RETRY(r, fcntl(fd, F_SETLKW, &fl)); e = r ? errno : 0; RETRY(r, write(in[1], &e, sizeof e)); if (!e) { RETRY(r, close(in[1])); RETRY(r, read(out[0], &e, 1)); } _exit(0); } default: _exit(0); } default: RETRY(r, close(in[1])); RETRY(r, close(out[0])); RETRY(r, waitpid(pid, NULL, 0)); *got = in[0]; *release = out[1]; return 0; } }