Я не знаю наверняка, но это, скорее всего, реализовано через flock()
. flock()
системный вызов создает консультацию, соединяют файл. Если другое приложение попытается достигнуть блокировки на файле, то ядро заблокируется, пока первоначальной блокировки не не стало, или возвратиться EWOULDBLOCK
если LOCK_NB
опция дана. Этот механизм блокировки позволил бы файлу блокировки использоваться, не удаляя и воссоздавая его.
Обновление: Проверенный источник и проверенный, что это - консультативная блокировка, но это не использует flock()
непосредственно. fcntl
используется:
enquiry.c:
if (modstatdb_is_locked())
puts(_(
"Another process has locked the database for writing, and might currently be\n"
"modifying it, some of the following problems might just be due to that.\n"));
head_running = true;
}
dbmodify.c:
modstatdb_is_locked(void)
{
int lockfd;
bool locked;
if (dblockfd == -1) {
lockfd = open(lockfile, O_RDONLY);
if (lockfd == -1)
ohshite(_("unable to open lock file %s for testing"), lockfile);
} else {
lockfd = dblockfd;
}
locked = file_is_locked(lockfd, lockfile);
/* We only close the file if there was no lock open, otherwise we would
* release the existing lock on close. */
if (dblockfd == -1)
close(lockfd);
return locked;
}
file.c:
file_is_locked(int lockfd, const char *filename)
{
struct flock fl;
file_lock_setup(&fl, F_WRLCK);
if (fcntl(lockfd, F_GETLK, &fl) == -1)
ohshit(_("unable to check file '%s' lock status"), filename);
if (fl.l_type == F_WRLCK && fl.l_pid != getpid())
return true;
else
return false;
}
dpkg.h:
#define LOCKFILE "lock"
От fcntl
страница справочника:
Advisory locking
F_GETLK, F_SETLK and F_SETLKW are used to acquire, release, and test for the existence of record locks (also known as file-segment or file-region locks). The third
argument, lock, is a pointer to a structure that has at least the following fields (in unspecified order).
Нет хорошего способа (я знаю) сделать это, но если вы готовы заплатить цену...
Вместо того, чтобы поместить код в функции, вы можете поместить его в исходные файлы. Если функциям нужны аргументы, то их нужно подготовить с помощью set
:
set -- arg1 arg2 arg3
source ...
Три файла:
testcript.sh
#! /bin/bash
startdir="$PWD"
эхо-сценарий
верно; но
эхо "начало: вспомогательный цикл"
источник "${startdir}/func_1".
эхо "конец: вспомогательная петля"
перерыв на
готовый
эхо-сценарий
func_1
echo "begin: commence:"
источник "${startdir}/func_2".
эхо "end: func_1"
func_2
echo "begin: commence:"
эхо-брейк от func_2
перерыв 100
эхо "end: func_2"
Результат:
> ./testscript.sh
mainscript
begin: helper loop
begin: func_1
begin: func_2
break from func_2
mainscript