Skip to content
Snippets Groups Projects
bwrap-lock.c 4.16 KiB
/*
 * Copyright © 2019 Collabora Ltd.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"
#include "subprojects/libglnx/config.h"

#include <gio/gio.h>

#include "bwrap-lock.h"

/**
 * PvBwrapLock:
 *
 * A read/write lock compatible with the locks taken out by
 * `bwrap --lock-file FILENAME` and Flatpak.
 */
struct _PvBwrapLock
{
  int fd;
};

/**
 * pv_bwrap_lock_new:
 * @path: Runtime directory to lock; the actual lock file will be `$path/.ref`
 * @flags: Flags affecting how we lock the directory
 * @error: Used to raise an error on failure
 *
 * Take out a lock on a directory.
 *
 * If %PV_BWRAP_LOCK_FLAGS_WRITE is in @flags, the lock is a write-lock,
 * which can be held by at most one process at a time. This is appropriate
 * when about to modify or delete the runtime. Otherwise it is a read-lock,
 * which excludes writers but does not exclude other readers. This is
 * appropriate when running an app or game using the runtime.
 *
 * If %PV_BWRAP_LOCK_FLAGS_WAIT is not in @flags, raise %G_IO_ERROR_BUSY
 * if the lock cannot be obtained immediately.
 *
 * Returns: (nullable): A lock (release and free with pv_bwrap_lock_free())
 *  or %NULL.
 */
PvBwrapLock *
pv_bwrap_lock_new (const gchar *path,
                   PvBwrapLockFlags flags,
                   GError **error)
{
  glnx_autofd int fd = -1;
  struct flock l = {
    .l_type = F_RDLCK,
    .l_whence = SEEK_SET,
    .l_start = 0,
    .l_len = 0
  };
  const char *type_str = "reading";