Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37509617
en ru br
Репозитории ALT
S:0.3.1-alt1.qa1
5.1: 0.3.1-alt1
4.1: 0.2-alt1
4.0: 0.2-alt1
www.altlinux.org/Changes

Группа :: Интерпретаторы команд
Пакет: bash-builtin-lockf

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

/*
Copyright (C) 2008 Dmitry V. Levin <ldv@altlinux.org>

"lock" builtin implementation for GNU bash.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <config.h>

#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/file.h>

#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#include "filecntl.h"

static int
lock_file(const char *fname, int operation, int verbose)
{
int fd, flags = O_RDONLY | O_NOCTTY;

if (operation & LOCK_NB)
flags |= O_NONBLOCK;
fd = open(fname, flags | O_CREAT, 0666);
if (fd < 0 && errno == EISDIR)
fd = open(fname, flags);
if (fd < 0)
{
builtin_error("Failed to open file %s: %m", fname);
return -1;
}

fd = move_to_high_fd(fd, 1, -1);
SET_CLOSE_ON_EXEC(fd);

if (flock(fd, operation) == 0)
return 0;

if (verbose)
builtin_error("Failed to place a lock on file %s: %m",
fname);
close(fd);
return -1;
}

static int
lockf_builtin (WORD_LIST *list)
{
int opt, operation = LOCK_EX, nonblock = 0, verbose = 0;

reset_internal_getopt();
while ((opt = internal_getopt(list, "ensvx")) != -1)
{
switch (opt)
{
case 'e': case 'x':
operation = LOCK_EX;
break;
case 's':
operation = LOCK_SH;
break;
case 'n':
nonblock = LOCK_NB;
break;
case 'v':
verbose = 1;
break;
default:
builtin_usage();
return EX_USAGE;
}
}
list = loptend;

if (!list || list->next)
{
builtin_usage();
return EX_USAGE;
}

return lock_file(list->word->word, operation | nonblock, verbose) ?
EXECUTION_FAILURE : EXECUTION_SUCCESS;
}

static char *lockf_doc[] = {
"Locks a specified file, which is created if it does not already exist.",
"File descriptor of the opened file has the close-on-exec flag set.",
"Options have the following meanings:",
" ",
" -s obtain a shared lock, sometimes called a read lock",
" -e, -x obtain an exclusive lock, sometimes called a write lock",
" (this is the default)",
" -n fail rather than wait if the lock cannot be immediately acquired",
" -v complain when lock attempt fails",
NULL
};

struct builtin lockf_struct = {
"lockf", /* builtin name */
lockf_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
lockf_doc, /* array of long documentation strings. */
"lockf [-ensx] file", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin