/* _tarfile.c - extension module for tarfile.py _tarfile enables some os-specific functions that are not available in Python 2.2 and/or that have not yet made their way into Python 2.3: os.mknod os.major os.minor os.makedev os.lchown The code bases entirely on patches by Gustavo Niemeyer. It should (hopefully) compile without errors on Linux and FreeBSD. If your OS should not be supported, please add an #include <...> below and send a patch. lars@gustaebel.de (08/06/2002) $Id: _tarfile.c 145 2002-07-22 12:10:19Z lars $ */ #include /* Include header file which holds the major and minor macros. Add an #include statement here, if your OS is not supported, and please send me a patch. */ #ifdef __FreeBSD__ #include #define BUILD_TAREXT #endif #ifdef __linux__ #include #include #include #define BUILD_TAREXT #endif #ifdef BUILD_TAREXT static PyObject * posix_error(void) { return PyErr_SetFromErrno(PyExc_OSError); } static PyObject * posix_error_with_allocated_filename(char* name) { PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); PyMem_Free(name); return rc; } /* All functions below have been written by Gustavo Niemeyer. They are either already patched to the Python core or waiting in the queue. */ static char tarfile_mknod__doc__[] = "mknod(filename, [, mode=0600, device]) -> None\n\ Create a filesystem node (file, device special file or named pipe)\n\ named filename. mode specifies both the permissions to use and the\n\ type of node to be created, being combined (bitwise OR) with one of\n\ S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ device defines the newly created device special file (probably using\n\ os.makedev()), otherwise it is ignored."; static PyObject * tarfile_mknod(PyObject *self, PyObject *args) { char *filename; int mode = 0600; int device = 0; int res; if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename, &mode, &device)) return NULL; Py_BEGIN_ALLOW_THREADS res = mknod(filename, mode, device); Py_END_ALLOW_THREADS if (res < 0) return posix_error(); Py_INCREF(Py_None); return Py_None; }; static char tarfile_major__doc__[] = "major(device) -> major number\n\ Extracts a device major number from a raw device number."; static PyObject * tarfile_major(PyObject *self, PyObject *args) { int device; if (!PyArg_ParseTuple(args, "i:major", &device)) return NULL; return PyInt_FromLong((long)major(device)); }; static char tarfile_minor__doc__[] = "minor(device) -> minor number\n\ Extracts a device minor number from a raw device number."; static PyObject * tarfile_minor(PyObject *self, PyObject *args) { int device; if (!PyArg_ParseTuple(args, "i:minor", &device)) return NULL; return PyInt_FromLong((long)minor(device)); }; static char tarfile_makedev__doc__[] = "makedev(major, minor) -> device number\n\ Composes a raw device number from the major and minor device numbers."; static PyObject * tarfile_makedev(PyObject *self, PyObject *args) { int major, minor; if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) return NULL; return PyInt_FromLong((long)makedev(major, minor)); }; static char tarfile_lchown__doc__[] = "lchown(path, uid, gid)\n\n\ Change the owner and group id of path to the numeric uid and gid.\n\ This function will not follow symbolic links."; static PyObject * tarfile_lchown(PyObject *self, PyObject *args) { char *path = NULL; int uid, gid; int res; if (!PyArg_ParseTuple(args, "etii:lchown", Py_FileSystemDefaultEncoding, &path, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = lchown(path, (uid_t) uid, (gid_t) gid); Py_END_ALLOW_THREADS if (res < 0) return posix_error_with_allocated_filename(path); PyMem_Free(path); Py_INCREF(Py_None); return Py_None; }; #endif static PyMethodDef tarfileMethods[] = { #ifdef BUILD_TAREXT {"mknod", tarfile_mknod, METH_VARARGS, tarfile_mknod__doc__}, {"major", tarfile_major, METH_VARARGS, tarfile_major__doc__}, {"minor", tarfile_minor, METH_VARARGS, tarfile_minor__doc__}, {"makedev", tarfile_makedev, METH_VARARGS, tarfile_makedev__doc__}, {"lchown", tarfile_lchown, METH_VARARGS, tarfile_lchown__doc__}, #endif {NULL, NULL, 0, NULL} }; void init_tarfile(void) { #ifdef BUILD_TAREXT (void) Py_InitModule("_tarfile", tarfileMethods); #else PyObject *m, *d; m = Py_InitModule("_tarfile", tarfileMethods); d = PyModule_GetDict(m); PyDict_SetItemString(d, "mknod", Py_None); PyDict_SetItemString(d, "major", Py_None); PyDict_SetItemString(d, "minor", Py_None); PyDict_SetItemString(d, "makedev", Py_None); PyDict_SetItemString(d, "lchown", Py_None); #endif };