-
Notifications
You must be signed in to change notification settings - Fork 0
/
directrwmodule.c
135 lines (106 loc) · 3.43 KB
/
directrwmodule.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* Copyright 2007,2008 The University of New South Wales
* Author: Joshua Root <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the Australian Public Licence B. See the file
* OZPLB.txt for the licence terms.
*/
#include "Python.h"
static PyObject *ErrorObject;
/* ----------------------------------------------------- */
static char directrw_read__doc__[] =
""
;
static PyObject *
directrw_read(PyObject *self /* Not used */, PyObject *args)
{
int fd = 0;
size_t sz = 0;
char *buf;
ssize_t n;
if (!PyArg_ParseTuple(args, "il", &fd, &sz))
return NULL;
//printf("directrw_read: args ok - fd=%d, sz=%ul\n", fd, sz);
/* valloc aligns to page size; Linux read/write with O_DIRECT
only really needs 512-byte alignment, but meh */
buf = valloc(sz);
if (!buf)
return PyErr_NoMemory();
//printf("directrw_read: memory allocated ok\n");
Py_BEGIN_ALLOW_THREADS
n = read(fd, buf, sz);
Py_END_ALLOW_THREADS
if (n == -1) {
free(buf);
return PyErr_SetFromErrno(PyExc_OSError);
}
//printf("directrw_read: read ok\n");
return Py_BuildValue("s", buf);
}
static char directrw_write__doc__[] =
""
;
static PyObject *
directrw_write(PyObject *self /* Not used */, PyObject *args)
{
int fd = 0;
size_t sz = 0;
char *abuf = NULL; /* correctly aligned buffer */
char *buf = NULL; /* original buffer */
ssize_t n;
if (!PyArg_ParseTuple(args, "isl", &fd, &buf, &sz))
return NULL;
//printf("directrw_write: args ok - fd=%d, buf=%p, sz=%ul\n", fd, buf, sz);
if (((Py_uintptr_t)buf & 511) != 0) {
/* misaligned, so fix up */
//printf("directrw_write: buf misaligned\n");
abuf = valloc(sz);
if (!abuf)
return PyErr_NoMemory();
}
Py_BEGIN_ALLOW_THREADS
if (abuf)
memcpy(abuf, buf, sz);
else
abuf = buf;
n = write(fd, abuf, sz);
Py_END_ALLOW_THREADS
if (n == -1) {
if (abuf && abuf != buf)
free(abuf);
return PyErr_SetFromErrno(PyExc_OSError);
}
//printf("directrw_write: write ok\n");
if (abuf)
free(abuf);
Py_INCREF(Py_None);
return Py_None;
}
/* List of methods defined in the module */
static struct PyMethodDef directrw_methods[] = {
{"read", (PyCFunction)directrw_read, METH_VARARGS, directrw_read__doc__},
{"write", (PyCFunction)directrw_write, METH_VARARGS, directrw_write__doc__},
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
};
/* Initialization function for the module (*must* be called initdirectrw) */
static char directrw_module_documentation[] =
""
;
void
initdirectrw()
{
PyObject *m, *d;
/* Create the module and add the functions */
m = Py_InitModule4("directrw", directrw_methods,
directrw_module_documentation,
(PyObject*)NULL,PYTHON_API_VERSION);
/* Add some symbolic constants to the module */
d = PyModule_GetDict(m);
ErrorObject = PyString_FromString("directrw.error");
PyDict_SetItemString(d, "error", ErrorObject);
/* XXXX Add constants here */
/* Check for errors */
if (PyErr_Occurred())
Py_FatalError("can't initialize module directrw");
}