📄 kfsmodulepy.cc
字号:
{ "sync", kfs_sync, METH_NOARGS, "Flush file data." }, { "data_verify", kfs_dataVerify, METH_VARARGS, "Verify data matches what is in KFS."}, { NULL }};static PyMemberDef File_members[] = { { "name", T_OBJECT, offsetof(kfs_File, name), RO, "file name" }, { "mode", T_OBJECT, offsetof(kfs_File, mode), RO, "access mode" }, { "fd", T_INT, offsetof(kfs_File, fd), RO, "file descriptor" }, { NULL }};PyDoc_STRVAR(File_doc,"These objects represent KFS files. They include a file descriptor (fd)\n""that identifies the file to the KFS client library for reads, writes,\n""and syncs. When a file is closed, its fd becomes -1 and no further\n""operations can be done on it unless it is reopened with the kfs.file\n""open method.\n\n""Methods:\n""\topen([mode]) -- reopen closed file\n""\tclose() -- close file\n""\tread(len) -- read len bytes, return as string\n""\twrite(str) -- write string to file\n""\ttruncate(off) -- truncate file at specified offset\n""\tseek(off) -- seek to specified offset\n""\ttell() -- return current offest\n""\tsync() -- flush file data to server\n""\tchunk_locations(path, offset) -- location(s) of the chunk corresponding to offset\n""\tdata_verify(str) -- verify that the data in KFS matches what is passed in\n""\nData:\n\n""\tname -- the name of the file\n""\tmode -- access mode ('r', 'w', 'r+', or 'w+')\n""\tfd -- file descriptor (-1 if closed)\n");static PyTypeObject kfs_FileType = { PyObject_HEAD_INIT(NULL) 0, // ob_size "kfs.file", // tp_name sizeof (kfs_File), // tp_basicsize 0, // tp_itemsize File_dealloc, // tp_dealloc File_print, // tp_print 0, // tp_getattr 0, // tp_setattr 0, // tp_compare File_repr, // tp_repr 0, // tp_as_number 0, // tp_as_sequence 0, // tp_as_mapping 0, // tp_hash 0, // tp_call 0, // tp_str 0, // tp_getattro 0, // tp_setattro 0, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags File_doc, // tp_doc 0, // tp_traverse 0, // tp_clear 0, // tp_richcompare 0, // tp_weaklistoffest 0, // tp_iter 0, // tp_iternext File_methods, // tp_methods File_members, // tp_members 0, // tp_getset 0, // tp_base 0, // tp_dict 0, // tp_descr_get 0, // tp_descr_set 0, // tp_dictoffset File_init, // tp_init 0, // tp_alloc File_new // tp_new};static voidClient_dealloc(PyObject *pself){ kfs_Client *self = (kfs_Client *)pself; Py_XDECREF(self->propfile); Py_XDECREF(self->cwd); self->client.reset(); self->ob_type->tp_free(pself);}static PyObject *Client_new(PyTypeObject *type, PyObject *args, PyObject *kwds){ kfs_Client *self = (kfs_Client *)type->tp_alloc(type, 0); if (self == NULL) return NULL; PyObject *p = PyString_FromString(""); PyObject *c = PyString_FromString("/"); if (p == NULL || c == NULL) { Py_DECREF(self); return NULL; } self->propfile = p; self->cwd = c; return (PyObject *)self;}static intClient_init(PyObject *pself, PyObject *args, PyObject *kwds){ kfs_Client *self = (kfs_Client *)pself; char *pf = NULL; if (!PyArg_ParseTuple(args, "s", &pf)) return -1; KfsClientPtr client = KFS::getKfsClientFactory()->GetClient(pf); if (!client) { PyErr_SetString(PyExc_IOError, "Unable to start client."); return -1; } self->client = client; PyObject *tmp = self->propfile; self->propfile = PyString_FromString(pf); Py_XDECREF(tmp); return 0;}static PyObject *Client_repr(PyObject *pself){ kfs_Client *self = (kfs_Client *)pself; return PyString_FromFormat("kfs.client<%s, %s>", PyString_AsString(self->propfile), PyString_AsString(self->cwd));}static intClient_print(PyObject *pself, FILE *fp, int flags){ kfs_Client *self = (kfs_Client *)pself; fprintf(fp, "kfs.client<%s, %s>\n", PyString_AsString(self->propfile), PyString_AsString(self->cwd)); return 0;}static stringstrip_dots(string path){ vector <string> component; string result; string::size_type start = 0; while (start != string::npos) { assert(path[start] == '/'); string::size_type slash = path.find('/', start + 1); string nextc = path.substr(start, slash - start); start = slash; if (nextc.compare("/..") == 0) { if (!component.empty()) component.pop_back(); } else if (nextc.compare("/.") != 0) component.push_back(nextc); } if (component.empty()) component.push_back(string("/")); for (vector <string>::iterator c = component.begin(); c != component.end(); c++) { result += *c; } return result;}/* * Take a path name that was supplied as an argument for a KFS operation. * If it is not absolute, add the current directory to the front of it and * in either case, call strip_dots to strip out any "." and ".." components. */static stringbuild_path(PyObject *cwd, const char *input){ string tail(input); if (input[0] == '/') return strip_dots(tail); const char *c = PyString_AsString(cwd); bool is_root = (c[0] == '/' && c[1] == '\0'); string head(c); if (!is_root) head.append("/"); return strip_dots(head + tail);}static PyObject *kfs_cd(PyObject *pself, PyObject *args){ struct stat s; kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Stat(path.c_str(), s); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } if (!S_ISDIR(s.st_mode)) { PyErr_SetString(PyExc_IOError, strerror(ENOTDIR)); return NULL; } PyObject *newcwd = PyString_FromString(path.c_str()); if (newcwd != NULL) { Py_DECREF(self->cwd); self->cwd = newcwd; } Py_RETURN_NONE;}static PyObject *kfs_log_level(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *logLevel; if (PyArg_ParseTuple(args, "s", &logLevel) == -1) return NULL; self->client->SetLogLevel(logLevel); Py_RETURN_NONE;}static PyObject *kfs_isdir(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); bool res = self->client->IsDirectory(path.c_str()); return Py_BuildValue("b", res);}static PyObject *kfs_isfile(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); bool res = self->client->IsFile(path.c_str()); return Py_BuildValue("b", res);}static PyObject *kfs_mkdir(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Mkdir(path.c_str()); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } Py_RETURN_NONE;}static PyObject *kfs_mkdirs(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Mkdirs(path.c_str()); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } Py_RETURN_NONE;}static PyObject *kfs_rmdir(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Rmdir(path.c_str()); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } Py_RETURN_NONE;}static PyObject *kfs_rmdirs(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Rmdirs(path.c_str()); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } Py_RETURN_NONE;}/*! * \brief read directory * * Return directory contents as a tuple of names * XXX It should return a tuple of (name, fid) pairs, but * the KFS client readdir code currently only gives names */static PyObject *kfs_readdir(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); vector <string> result; int status = self->client->Readdir(path.c_str(), result); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } int n = result.size(); PyObject *tuple = PyTuple_New(n); for (int i = 0; i != n; i++) { PyTuple_SetItem(tuple, i, PyString_FromString(result[i].c_str())); } return tuple;}/*! * \brief Package a KfsFileAttr into a tuple */static PyObject *package_fattr(KfsFileAttr &fa){ PyObject *tuple = PyTuple_New(7); PyTuple_SetItem(tuple, 0, PyString_FromString(fa.filename.c_str())); PyTuple_SetItem(tuple, 1, PyLong_FromLong(fa.fileId)); PyTuple_SetItem(tuple, 2, PyString_FromString(ctime(&fa.mtime.tv_sec))); PyTuple_SetItem(tuple, 3, PyString_FromString(ctime(&fa.ctime.tv_sec))); PyTuple_SetItem(tuple, 4, PyString_FromString(ctime(&fa.crtime.tv_sec))); PyTuple_SetItem(tuple, 5, PyString_FromString( fa.isDirectory ? "dir" : "file")); PyTuple_SetItem(tuple, 6, PyLong_FromLong(fa.fileSize)); return tuple;}/*! * \brief read directory with attributes * * Returns a tuple of tuples, each with the following data: * * (name, fid, mtime, ctime, crtime, type, size) */static PyObject *kfs_readdirplus(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); vector <KfsFileAttr> result; int status = self->client->ReaddirPlus(path.c_str(), result); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } int n = result.size(); PyObject *outer = PyTuple_New(n); for (int i = 0; i != n; i++) { PyObject *inner = package_fattr(result[i]); PyTuple_SetItem(outer, i, inner); } return outer;}static PyObject *kfs_stat(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; struct stat s; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Stat(path.c_str(), s, true); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } /* * Return the stat information in the same format as * os.stat() so that we can use the standard stat module * on it. */ PyObject *pstat = PyTuple_New(10); PyTuple_SetItem(pstat, 0, PyInt_FromLong(s.st_mode)); PyTuple_SetItem(pstat, 1, PyInt_FromLong(s.st_ino)); PyTuple_SetItem(pstat, 2, PyLong_FromLong(s.st_dev)); PyTuple_SetItem(pstat, 3, PyInt_FromLong(s.st_nlink)); PyTuple_SetItem(pstat, 4, PyInt_FromLong(s.st_uid)); PyTuple_SetItem(pstat, 5, PyInt_FromLong(s.st_gid)); PyTuple_SetItem(pstat, 6, PyLong_FromLong(s.st_size)); PyTuple_SetItem(pstat, 7, PyInt_FromLong(s.st_atime)); PyTuple_SetItem(pstat, 8, PyInt_FromLong(s.st_mtime)); PyTuple_SetItem(pstat, 9, PyInt_FromLong(s.st_ctime)); return pstat;}static PyObject *kfs_create(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int fd = self->client->Create(path.c_str()); if (fd < 0) { PyErr_SetString(PyExc_IOError, strerror(-fd)); return NULL; } kfs_File *f = (kfs_File *)kfs_FileType.tp_new(&kfs_FileType, NULL, NULL); if (f == NULL || set_file_members(f, path.c_str(), "w", self, fd) < 0) return NULL; return (PyObject *)f;}static PyObject *kfs_remove(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg; if (PyArg_ParseTuple(args, "s", &patharg) == -1) return NULL; string path = build_path(self->cwd, patharg); int status = self->client->Remove(path.c_str()); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } Py_RETURN_NONE;}static PyObject *kfs_rename(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *srcpath, *dstpath; if (PyArg_ParseTuple(args, "ss", &srcpath, &dstpath) == -1) return NULL; string spath = build_path(self->cwd, srcpath); string dpath = build_path(self->cwd, dstpath); int status = self->client->Rename(spath.c_str(), dpath.c_str(), false); if (status < 0) { PyErr_SetString(PyExc_IOError, strerror(-status)); return NULL; } Py_RETURN_NONE;}static PyObject *kfs_open(PyObject *pself, PyObject *args){ kfs_Client *self = (kfs_Client *)pself; char *patharg, *modestr = "r"; if (PyArg_ParseTuple(args, "s|s", &patharg, &modestr) == -1) return NULL; string path = build_path(self->cwd, patharg); kfs_File *f = (kfs_File *)kfs_FileType.tp_new(&kfs_FileType, NULL, NULL); if (f == NULL || set_file_members(f, path.c_str(), modestr, self, -1) < 0) { return NULL; } return (PyObject *)f;}PyDoc_STRVAR(module_doc,"This module links to the KFS client library to provide simple KFS\n""file services akin to those for built-in Python file objects. To use\n""it, you must first create a kfs.client object. This provides the\n""connection to KFS; the appropriate KFS servers (i.e., the metaserver\n"" and chunkservers) must already be active.\n\n""Once you have a kfs.client, you can perform file system operations\n""corresponding to the KFS client library interfaces and create kfs.file\n""objects that represent files in KFS.\n");PyMODINIT_FUNCinitkfs(){ if (PyType_Ready(&kfs_ClientType) < 0 || PyType_Ready(&kfs_FileType) < 0) return; PyObject *m = Py_InitModule3("kfs", NULL, module_doc); Py_INCREF(&kfs_ClientType); PyModule_AddObject(m, "client", (PyObject *)&kfs_ClientType); Py_INCREF(&kfs_FileType); PyModule_AddObject(m, "file", (PyObject *)&kfs_FileType);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -