2 * Copyright (C) 2018 Facebook
4 * This file is part of libbtrfsutil.
6 * libbtrfsutil is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * libbtrfsutil is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with libbtrfsutil. If not, see <http://www.gnu.org/licenses/>.
20 #include "btrfsutilpy.h"
22 static int fd_converter(PyObject *o, void *p)
28 tmp = PyLong_AsLongAndOverflow(o, &overflow);
29 if (tmp == -1 && PyErr_Occurred())
31 if (overflow > 0 || tmp > INT_MAX) {
32 PyErr_SetString(PyExc_OverflowError,
33 "fd is greater than maximum");
36 if (overflow < 0 || tmp < 0) {
37 PyErr_SetString(PyExc_ValueError, "fd is negative");
44 int path_converter(PyObject *o, void *p)
46 struct path_arg *path = p;
47 int is_index, is_bytes, is_unicode;
48 PyObject *bytes = NULL;
49 Py_ssize_t length = 0;
57 path->object = path->cleanup = NULL;
62 is_index = path->allow_fd && PyIndex_Check(o);
63 is_bytes = PyBytes_Check(o);
64 is_unicode = PyUnicode_Check(o);
66 if (!is_index && !is_bytes && !is_unicode) {
67 _Py_IDENTIFIER(__fspath__);
70 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
74 o = PyObject_CallFunctionObjArgs(func, NULL);
78 is_bytes = PyBytes_Check(o);
79 is_unicode = PyUnicode_Check(o);
83 if (!PyUnicode_FSConverter(o, &bytes))
85 } else if (is_bytes) {
88 } else if (is_index) {
89 if (!fd_converter(o, &path->fd))
95 PyErr_Format(PyExc_TypeError, "expected %s, not %s",
96 path->allow_fd ? "string, bytes, os.PathLike, or integer" :
97 "string, bytes, or os.PathLike",
102 length = PyBytes_GET_SIZE(bytes);
103 tmp = PyBytes_AS_STRING(bytes);
104 if ((size_t)length != strlen(tmp)) {
105 PyErr_SetString(PyExc_TypeError,
106 "path has embedded nul character");
114 path->cleanup = bytes;
118 path->length = length;
120 return Py_CLEANUP_SUPPORTED;
128 void path_cleanup(struct path_arg *path)
130 Py_CLEAR(path->object);
131 Py_CLEAR(path->cleanup);
134 static PyMethodDef btrfsutil_methods[] = {
138 static struct PyModuleDef btrfsutilmodule = {
139 PyModuleDef_HEAD_INIT,
141 "Library for managing Btrfs filesystems",
147 PyInit_btrfsutil(void)
151 BtrfsUtilError_type.tp_base = (PyTypeObject *)PyExc_OSError;
152 if (PyType_Ready(&BtrfsUtilError_type) < 0)
155 QgroupInherit_type.tp_new = PyType_GenericNew;
156 if (PyType_Ready(&QgroupInherit_type) < 0)
159 m = PyModule_Create(&btrfsutilmodule);
163 Py_INCREF(&BtrfsUtilError_type);
164 PyModule_AddObject(m, "BtrfsUtilError",
165 (PyObject *)&BtrfsUtilError_type);
167 Py_INCREF(&QgroupInherit_type);
168 PyModule_AddObject(m, "QgroupInherit",
169 (PyObject *)&QgroupInherit_type);
171 add_module_constants(m);