|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <Python.h> |
|
#include <apt-pkg/init.h> |
|
#include <apt-pkg/error.h> |
|
#include <apt-pkg/fileutl.h> |
|
#include <apt-pkg/pkgsystem.h> |
|
#include "generic.h" |
|
|
|
static PyObject *systemlock_exit(PyObject *self, PyObject *args) |
|
{ |
|
|
|
PyObject *exc_type = 0; |
|
PyObject *exc_value = 0; |
|
PyObject *traceback = 0; |
|
if (!PyArg_UnpackTuple(args, "__exit__", 3, 3, &exc_type, &exc_value, |
|
&traceback)) { |
|
return 0; |
|
} |
|
|
|
if (_system->UnLock() == 0) { |
|
|
|
|
|
|
|
HandleErrors(); |
|
if (exc_type == Py_None) |
|
return NULL; |
|
else |
|
PyErr_WriteUnraisable(self); |
|
} |
|
|
|
Py_RETURN_FALSE; |
|
} |
|
|
|
static PyObject *systemlock_enter(PyObject *self, PyObject *args) |
|
{ |
|
if (!PyArg_ParseTuple(args, "")) |
|
return NULL; |
|
if (!_system->Lock()) |
|
return HandleErrors(); |
|
Py_INCREF(self); |
|
return self; |
|
} |
|
|
|
static PyObject *systemlock_new(PyTypeObject *type, PyObject *args, |
|
PyObject *kwds) |
|
{ |
|
if (_system == 0) { |
|
PyErr_SetString(PyExc_ValueError,"_system not initialized"); |
|
return 0; |
|
} |
|
return PyType_GenericNew(type,args,kwds); |
|
} |
|
|
|
static PyMethodDef systemlock_methods[] = { |
|
{"__enter__",systemlock_enter,METH_VARARGS,"Lock the system."}, |
|
{"__exit__",systemlock_exit,METH_VARARGS,"Unlock the system."}, |
|
{NULL} |
|
}; |
|
|
|
static char *systemlock_doc = "SystemLock()\n\n" |
|
"Context manager for locking the package system. The lock is established\n" |
|
"as soon as the method __enter__() is called. It is released when\n" |
|
"__exit__() is called.\n\n" |
|
"This should be used via the 'with' statement, for example:\n\n" |
|
" with apt_pkg.SystemLock():\n" |
|
" ...\n\n" |
|
"Once the block is left, the lock is released automatically. The object\n" |
|
"can be used multiple times:\n\n" |
|
" lock = apt_pkg.SystemLock()\n" |
|
" with lock:\n" |
|
" ...\n" |
|
" with lock:\n" |
|
" ...\n\n"; |
|
|
|
PyTypeObject PySystemLock_Type = { |
|
PyVarObject_HEAD_INIT(&PyType_Type, 0) |
|
"apt_pkg.SystemLock", |
|
0, |
|
0, |
|
|
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
(Py_TPFLAGS_DEFAULT | |
|
Py_TPFLAGS_BASETYPE), |
|
systemlock_doc, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
systemlock_methods, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
systemlock_new, |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct filelock_object { |
|
PyObject_HEAD |
|
char *filename; |
|
int lock_count; |
|
int fd; |
|
}; |
|
|
|
static PyObject *filelock_enter(filelock_object *self, PyObject *args) |
|
{ |
|
self->lock_count++; |
|
|
|
if (self->lock_count == 1) { |
|
self->fd = GetLock(self->filename, true); |
|
if (self->fd == -1) { |
|
self->lock_count--; |
|
return HandleErrors(); |
|
} |
|
} |
|
Py_INCREF(self); |
|
return (PyObject *)self; |
|
} |
|
|
|
static PyObject *filelock_exit(filelock_object *self, PyObject *args) |
|
{ |
|
|
|
self->lock_count--; |
|
if (self->lock_count < 0) |
|
self->lock_count = 0; |
|
if (self->lock_count == 0 && self->fd != 0 && close(self->fd) == -1) { |
|
return PyErr_SetFromErrno(PyExc_OSError); |
|
} |
|
Py_RETURN_FALSE; |
|
} |
|
|
|
static PyObject *filelock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
|
{ |
|
PyApt_Filename filename; |
|
char *kwlist[] = {"filename", NULL}; |
|
if (PyArg_ParseTupleAndKeywords(args, kwds, "O&:__init__", kwlist, |
|
PyApt_Filename::Converter, |
|
&filename) == 0) { |
|
return NULL; |
|
} |
|
filelock_object *self = (filelock_object *)type->tp_alloc(type, 0); |
|
|
|
self->filename = new char[strlen(filename) + 1]; |
|
strcpy(self->filename, filename); |
|
return (PyObject *)self; |
|
} |
|
|
|
static void filelock_dealloc(filelock_object *self) |
|
{ |
|
delete[] self->filename; |
|
((PyObject*)self)->ob_type->tp_free(self); |
|
} |
|
|
|
static PyMethodDef filelock_methods[] = { |
|
{"__enter__",(PyCFunction)filelock_enter,METH_VARARGS,"Lock the system."}, |
|
{"__exit__",(PyCFunction)filelock_exit,METH_VARARGS,"Unlock the system."}, |
|
{NULL} |
|
}; |
|
|
|
static char *filelock_doc = "SystemLock(filename: str)\n\n" |
|
"Context manager for locking using a file. The lock is established\n" |
|
"as soon as the method __enter__() is called. It is released when\n" |
|
"__exit__() is called.\n\n" |
|
"This should be used via the 'with' statement, for example:\n\n" |
|
" with apt_pkg.FileLock(filename):\n" |
|
" ...\n\n" |
|
"Once the block is left, the lock is released automatically. The object\n" |
|
"can be used multiple times:\n\n" |
|
" lock = apt_pkg.FileLock(filename)\n" |
|
" with lock:\n" |
|
" ...\n" |
|
" with lock:\n" |
|
" ...\n\n"; |
|
|
|
PyTypeObject PyFileLock_Type = { |
|
PyVarObject_HEAD_INIT(&PyType_Type, 0) |
|
"apt_pkg.FileLock", |
|
sizeof(filelock_object), |
|
0, |
|
|
|
destructor(filelock_dealloc), |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
(Py_TPFLAGS_DEFAULT | |
|
Py_TPFLAGS_BASETYPE), |
|
filelock_doc, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
filelock_methods, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
0, |
|
filelock_new, |
|
}; |
|
|