From 511946b31e1f4e5f6d6cd378e0e3d683031a3a1f Mon Sep 17 00:00:00 2001 From: Iustin Pop Date: Sun, 29 Jun 2008 19:00:42 +0200 Subject: [PATCH] Convert to object protocol This patch changes the hardcoded if-then-else constructs for selecting the type of function (file-descriptor, symlink, normal path) into a generic framework. --- xattr.c | 134 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/xattr.c b/xattr.c index 1e4ffaa..581b58a 100644 --- a/xattr.c +++ b/xattr.c @@ -1,21 +1,69 @@ #include #include +typedef enum {T_FD, T_PATH, T_LINK} target_e; + +typedef struct { + target_e type; + union { + const char *name; + int fd; + }; +} target_t; + /** Converts from a string, file or int argument to what we need. */ -static int convertObj(PyObject *myobj, int *ishandle, int *filehandle, - char **filename) { +static int convertObj(PyObject *myobj, target_t *tgt, int nofollow) { + int fd; if(PyString_Check(myobj)) { - *ishandle = 0; - *filename = PyString_AS_STRING(myobj); - } else if((*filehandle = PyObject_AsFileDescriptor(myobj)) != -1) { - *ishandle = 1; + tgt->type = nofollow ? T_LINK : T_PATH; + tgt->name = PyString_AS_STRING(myobj); + } else if((fd = PyObject_AsFileDescriptor(myobj)) != -1) { + tgt->type = T_FD; + tgt->fd = fd; } else { - PyErr_SetString(PyExc_TypeError, "argument 1 must be string or int"); + PyErr_SetString(PyExc_TypeError, "argument must be string or int"); return 0; } return 1; } +static ssize_t _list_obj(target_t *tgt, char *list, size_t size) { + if(tgt->type == T_FD) + return flistxattr(tgt->fd, list, size); + else if (tgt->type == T_LINK) + return llistxattr(tgt->name, list, size); + else + return listxattr(tgt->name, list, size); +} + +static ssize_t _get_obj(target_t *tgt, char *name, void *value, size_t size) { + if(tgt->type == T_FD) + return fgetxattr(tgt->fd, name, value, size); + else if (tgt->type == T_LINK) + return lgetxattr(tgt->name, name, value, size); + else + return getxattr(tgt->name, name, value, size); +} + +static ssize_t _set_obj(target_t *tgt, char *name, void *value, size_t size, + int flags) { + if(tgt->type == T_FD) + return fsetxattr(tgt->fd, name, value, size, flags); + else if (tgt->type == T_LINK) + return lsetxattr(tgt->name, name, value, size, flags); + else + return setxattr(tgt->name, name, value, size, flags); +} + +static ssize_t _remove_obj(target_t *tgt, char *name) { + if(tgt->type == T_FD) + return fremovexattr(tgt->fd, name); + else if (tgt->type == T_LINK) + return lremovexattr(tgt->name, name); + else + return removexattr(tgt->name, name); +} + /* Wrapper for getxattr */ static char __pygetxattr_doc__[] = "Get the value of a given extended attribute.\n" @@ -36,8 +84,8 @@ static PyObject * pygetxattr(PyObject *self, PyObject *args) { PyObject *myarg; - char *file = NULL; - int filedes = -1, ishandle, dolink=0; + target_t tgt; + int dolink=0; char *attrname; char *buf; int nalloc, nret; @@ -46,16 +94,11 @@ pygetxattr(PyObject *self, PyObject *args) /* Parse the arguments */ if (!PyArg_ParseTuple(args, "Os|i", &myarg, &attrname, &dolink)) return NULL; - if(!convertObj(myarg, &ishandle, &filedes, &file)) + if(!convertObj(myarg, &tgt, dolink)) return NULL; /* Find out the needed size of the buffer */ - nalloc = ishandle ? - fgetxattr(filedes, attrname, NULL, 0) : - dolink ? - lgetxattr(file, attrname, NULL, 0) : - getxattr(file, attrname, NULL, 0); - if(nalloc == -1) { + if((nalloc = _get_obj(&tgt, attrname, NULL, 0)) == -1) { return PyErr_SetFromErrno(PyExc_IOError); } @@ -66,12 +109,7 @@ pygetxattr(PyObject *self, PyObject *args) } /* Now retrieve the attribute value */ - nret = ishandle ? - fgetxattr(filedes, attrname, buf, nalloc) : - dolink ? - lgetxattr(file, attrname, buf, nalloc) : - getxattr(file, attrname, buf, nalloc); - if(nret == -1) { + if((nret = _get_obj(&tgt, attrname, buf, nalloc)) == -1) { PyMem_Free(buf); return PyErr_SetFromErrno(PyExc_IOError); } @@ -118,28 +156,22 @@ static PyObject * pysetxattr(PyObject *self, PyObject *args) { PyObject *myarg; - char *file; - int ishandle, filedes, dolink=0; + int dolink=0; char *attrname; char *buf; int bufsize, nret; int flags = 0; + target_t tgt; /* Parse the arguments */ if (!PyArg_ParseTuple(args, "Oss#|bi", &myarg, &attrname, &buf, &bufsize, &flags, &dolink)) return NULL; - if(!convertObj(myarg, &ishandle, &filedes, &file)) + if(!convertObj(myarg, &tgt, dolink)) return NULL; /* Set the attribute's value */ - nret = ishandle ? - fsetxattr(filedes, attrname, buf, bufsize, flags) : - dolink ? - lsetxattr(file, attrname, buf, bufsize, flags) : - setxattr(file, attrname, buf, bufsize, flags); - - if(nret == -1) { + if((nret = _set_obj(&tgt, attrname, buf, bufsize, flags)) == -1) { return PyErr_SetFromErrno(PyExc_IOError); } @@ -168,27 +200,22 @@ static PyObject * pyremovexattr(PyObject *self, PyObject *args) { PyObject *myarg; - char *file; - int ishandle, filedes, dolink=0; + int dolink=0; char *attrname; int nret; + target_t tgt; /* Parse the arguments */ if (!PyArg_ParseTuple(args, "Os|i", &myarg, &attrname, &dolink)) return NULL; - if(!convertObj(myarg, &ishandle, &filedes, &file)) + if(!convertObj(myarg, &tgt, dolink)) return NULL; /* Remove the attribute */ - nret = ishandle ? - fremovexattr(filedes, attrname) : - dolink ? - lremovexattr(file, attrname) : - removexattr(file, attrname); - - if(nret == -1) + if((nret = _remove_obj(&tgt, attrname)) == -1) { return PyErr_SetFromErrno(PyExc_IOError); + } /* Return the result */ Py_INCREF(Py_None); @@ -212,30 +239,23 @@ static char __pylistxattr_doc__[] = static PyObject * pylistxattr(PyObject *self, PyObject *args) { - char *file = NULL; - int filedes = -1; char *buf; - int ishandle, dolink=0; + int dolink=0; int nalloc, nret; PyObject *myarg; PyObject *mylist; int nattrs; char *s; + target_t tgt; /* Parse the arguments */ if (!PyArg_ParseTuple(args, "O|i", &myarg, &dolink)) return NULL; - if(!convertObj(myarg, &ishandle, &filedes, &file)) + if(!convertObj(myarg, &tgt, dolink)) return NULL; /* Find out the needed size of the buffer */ - nalloc = ishandle ? - flistxattr(filedes, NULL, 0) : - dolink ? - llistxattr(file, NULL, 0) : - listxattr(file, NULL, 0); - - if(nalloc == -1) { + if((nalloc = _list_obj(&tgt, NULL, 0)) == -1) { return PyErr_SetFromErrno(PyExc_IOError); } @@ -246,13 +266,7 @@ pylistxattr(PyObject *self, PyObject *args) } /* Now retrieve the list of attributes */ - nret = ishandle ? - flistxattr(filedes, buf, nalloc) : - dolink ? - llistxattr(file, buf, nalloc) : - listxattr(file, buf, nalloc); - - if(nret == -1) { + if((nret = _list_obj(&tgt, buf, nalloc)) == -1) { PyMem_Free(buf); return PyErr_SetFromErrno(PyExc_IOError); } -- 2.39.2