summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/Setup.dist2
-rw-r--r--Modules/_cryptmodule.c (renamed from Modules/cryptmodule.c)4
-rw-r--r--Modules/_ctypes/_ctypes.c2
-rw-r--r--Modules/_ctypes/cfield.c3
-rw-r--r--Modules/_datetimemodule.c2
-rw-r--r--Modules/_dbmmodule.c2
-rw-r--r--Modules/_io/bytesio.c2
-rw-r--r--Modules/_io/textio.c135
-rw-r--r--Modules/_json.c21
-rw-r--r--Modules/_multiprocessing/multiprocessing.h2
-rw-r--r--Modules/_sqlite/connection.c3
-rw-r--r--Modules/_sqlite/cursor.c8
-rw-r--r--Modules/_sqlite/statement.c4
-rw-r--r--Modules/_ssl.c3
-rw-r--r--Modules/_threadmodule.c7
-rw-r--r--Modules/_tkinter.c3
-rw-r--r--Modules/arraymodule.c1
-rw-r--r--Modules/audioop.c4
-rw-r--r--Modules/cjkcodecs/_codecs_iso2022.c2
-rw-r--r--Modules/cjkcodecs/multibytecodec.c1
-rw-r--r--Modules/main.c3
-rw-r--r--Modules/posixmodule.c1016
-rw-r--r--Modules/socketmodule.c37
23 files changed, 1161 insertions, 106 deletions
diff --git a/Modules/Setup.dist b/Modules/Setup.dist
index e1c8fe4..56f3314 100644
--- a/Modules/Setup.dist
+++ b/Modules/Setup.dist
@@ -207,7 +207,7 @@ _symtable symtablemodule.c
#
# First, look at Setup.config; configure may have set this for you.
-#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
+#_crypt _cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
# Some more UNIX dependent modules -- off by default, since these
diff --git a/Modules/cryptmodule.c b/Modules/_cryptmodule.c
index d5a42ff..5100788 100644
--- a/Modules/cryptmodule.c
+++ b/Modules/_cryptmodule.c
@@ -45,7 +45,7 @@ static PyMethodDef crypt_methods[] = {
static struct PyModuleDef cryptmodule = {
PyModuleDef_HEAD_INIT,
- "crypt",
+ "_crypt",
NULL,
-1,
crypt_methods,
@@ -56,7 +56,7 @@ static struct PyModuleDef cryptmodule = {
};
PyMODINIT_FUNC
-PyInit_crypt(void)
+PyInit__crypt(void)
{
return PyModule_Create(&cryptmodule);
}
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index ff35862..d30018b 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1826,7 +1826,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
if (PyUnicode_Check(proto)) {
- PyObject *v = _PyUnicode_AsDefaultEncodedString(proto, NULL);
+ PyObject *v = _PyUnicode_AsDefaultEncodedString(proto);
if (!v)
goto error;
proto_str = PyBytes_AS_STRING(v);
diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
index ccaa3c9..0aa9f0b 100644
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -52,7 +52,7 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
{
CFieldObject *self;
PyObject *proto;
- Py_ssize_t size, align, length;
+ Py_ssize_t size, align;
SETFUNC setfunc = NULL;
GETFUNC getfunc = NULL;
StgDictObject *dict;
@@ -106,7 +106,6 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
}
size = dict->size;
- length = dict->length;
proto = desc;
/* Field descriptors for 'c_char * n' are be scpecial cased to
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 6195940..cd44471 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -1461,7 +1461,7 @@ delta_to_microseconds(PyDateTime_Delta *self)
goto Done;
Py_DECREF(x1);
Py_DECREF(x2);
- x1 = x2 = NULL;
+ /* x1 = */ x2 = NULL;
/* x3 has days+seconds in seconds */
x1 = PyNumber_Multiply(x3, us_per_second); /* us */
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
index 827acce..69a7112 100644
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -219,7 +219,7 @@ dbm_contains(PyObject *self, PyObject *arg)
return -1;
}
if (PyUnicode_Check(arg)) {
- arg = _PyUnicode_AsDefaultEncodedString(arg, NULL);
+ arg = _PyUnicode_AsDefaultEncodedString(arg);
if (arg == NULL)
return -1;
}
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index b40513f..65ec931 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -938,13 +938,11 @@ static int
bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
{
int ret;
- void *ptr;
bytesio *b = (bytesio *) obj->source;
if (view == NULL) {
b->exports++;
return 0;
}
- ptr = (void *) obj;
ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size,
0, flags);
if (ret >= 0) {
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 73d83a1..35bd922 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -678,12 +678,16 @@ typedef struct
PyObject *pending_bytes; /* list of bytes objects waiting to be
written, or NULL */
Py_ssize_t pending_bytes_count;
- PyObject *snapshot;
+
/* snapshot is either None, or a tuple (dec_flags, next_input) where
* dec_flags is the second (integer) item of the decoder state and
* next_input is the chunk of input bytes that comes next after the
* snapshot point. We use this to reconstruct decoder states in tell().
*/
+ PyObject *snapshot;
+ /* Bytes-to-characters ratio for the current chunk. Serves as input for
+ the heuristic in tell(). */
+ double b2cratio;
/* Cache raw object if it's a FileIO object */
PyObject *raw;
@@ -850,6 +854,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
self->decoded_chars_used = 0;
self->pending_bytes_count = 0;
self->encodefunc = NULL;
+ self->b2cratio = 0.0;
if (encoding == NULL) {
/* Try os.device_encoding(fileno) */
@@ -1390,6 +1395,7 @@ textiowrapper_read_chunk(textio *self)
PyObject *dec_flags = NULL;
PyObject *input_chunk = NULL;
PyObject *decoded_chars, *chunk_size;
+ Py_ssize_t nbytes, nchars;
int eof;
/* The return value is True unless EOF was reached. The decoded string is
@@ -1435,7 +1441,8 @@ textiowrapper_read_chunk(textio *self)
goto fail;
assert(PyBytes_Check(input_chunk));
- eof = (PyBytes_Size(input_chunk) == 0);
+ nbytes = PyBytes_Size(input_chunk);
+ eof = (nbytes == 0);
if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
decoded_chars = _PyIncrementalNewlineDecoder_decode(
@@ -1450,7 +1457,12 @@ textiowrapper_read_chunk(textio *self)
if (decoded_chars == NULL)
goto fail;
textiowrapper_set_decoded_chars(self, decoded_chars);
- if (PyUnicode_GET_SIZE(decoded_chars) > 0)
+ nchars = PyUnicode_GET_SIZE(decoded_chars);
+ if (nchars > 0)
+ self->b2cratio = (double) nbytes / nchars;
+ else
+ self->b2cratio = 0.0;
+ if (nchars > 0)
eof = 0;
if (self->telling) {
@@ -2139,8 +2151,12 @@ textiowrapper_tell(textio *self, PyObject *args)
cookie_type cookie = {0,0,0,0,0};
PyObject *next_input;
Py_ssize_t chars_to_skip, chars_decoded;
+ Py_ssize_t skip_bytes, skip_back;
PyObject *saved_state = NULL;
char *input, *input_end;
+ char *dec_buffer;
+ Py_ssize_t dec_buffer_len;
+ int dec_flags;
CHECK_INITIALIZED(self);
CHECK_CLOSED(self);
@@ -2176,6 +2192,7 @@ textiowrapper_tell(textio *self, PyObject *args)
#else
cookie.start_pos = PyLong_AsLong(posobj);
#endif
+ Py_DECREF(posobj);
if (PyErr_Occurred())
goto fail;
@@ -2190,57 +2207,99 @@ textiowrapper_tell(textio *self, PyObject *args)
/* How many decoded characters have been used up since the snapshot? */
if (self->decoded_chars_used == 0) {
/* We haven't moved from the snapshot point. */
- Py_DECREF(posobj);
return textiowrapper_build_cookie(&cookie);
}
chars_to_skip = self->decoded_chars_used;
- /* Starting from the snapshot position, we will walk the decoder
- * forward until it gives us enough decoded characters.
- */
+ /* Decoder state will be restored at the end */
saved_state = PyObject_CallMethodObjArgs(self->decoder,
_PyIO_str_getstate, NULL);
if (saved_state == NULL)
goto fail;
- /* Note our initial start point. */
- if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
- goto fail;
+#define DECODER_GETSTATE() do { \
+ PyObject *_state = PyObject_CallMethodObjArgs(self->decoder, \
+ _PyIO_str_getstate, NULL); \
+ if (_state == NULL) \
+ goto fail; \
+ if (!PyArg_Parse(_state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) { \
+ Py_DECREF(_state); \
+ goto fail; \
+ } \
+ Py_DECREF(_state); \
+ } while (0)
+
+ /* TODO: replace assert with exception */
+#define DECODER_DECODE(start, len, res) do { \
+ PyObject *_decoded = PyObject_CallMethod( \
+ self->decoder, "decode", "y#", start, len); \
+ if (_decoded == NULL) \
+ goto fail; \
+ assert (PyUnicode_Check(_decoded)); \
+ res = PyUnicode_GET_SIZE(_decoded); \
+ Py_DECREF(_decoded); \
+ } while (0)
+
+ /* Fast search for an acceptable start point, close to our
+ current pos */
+ skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip);
+ skip_back = 1;
+ assert(skip_back <= PyBytes_GET_SIZE(next_input));
+ input = PyBytes_AS_STRING(next_input);
+ while (skip_bytes > 0) {
+ /* Decode up to temptative start point */
+ if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
+ goto fail;
+ DECODER_DECODE(input, skip_bytes, chars_decoded);
+ if (chars_decoded <= chars_to_skip) {
+ DECODER_GETSTATE();
+ if (dec_buffer_len == 0) {
+ /* Before pos and no bytes buffered in decoder => OK */
+ cookie.dec_flags = dec_flags;
+ chars_to_skip -= chars_decoded;
+ break;
+ }
+ /* Skip back by buffered amount and reset heuristic */
+ skip_bytes -= dec_buffer_len;
+ skip_back = 1;
+ }
+ else {
+ /* We're too far ahead, skip back a bit */
+ skip_bytes -= skip_back;
+ skip_back *= 2;
+ }
+ }
+ if (skip_bytes <= 0) {
+ skip_bytes = 0;
+ if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
+ goto fail;
+ }
- /* Feed the decoder one byte at a time. As we go, note the
- * nearest "safe start point" before the current location
- * (a point where the decoder has nothing buffered, so seek()
+ /* Note our initial start point. */
+ cookie.start_pos += skip_bytes;
+ cookie.chars_to_skip = chars_to_skip;
+ if (chars_to_skip == 0)
+ goto finally;
+
+ /* We should be close to the desired position. Now feed the decoder one
+ * byte at a time until we reach the `chars_to_skip` target.
+ * As we go, note the nearest "safe start point" before the current
+ * location (a point where the decoder has nothing buffered, so seek()
* can safely start from there and advance to this location).
*/
chars_decoded = 0;
input = PyBytes_AS_STRING(next_input);
input_end = input + PyBytes_GET_SIZE(next_input);
+ input += skip_bytes;
while (input < input_end) {
- PyObject *state;
- char *dec_buffer;
- Py_ssize_t dec_buffer_len;
- int dec_flags;
-
- PyObject *decoded = PyObject_CallMethod(
- self->decoder, "decode", "y#", input, 1);
- if (decoded == NULL)
- goto fail;
- assert (PyUnicode_Check(decoded));
- chars_decoded += PyUnicode_GET_SIZE(decoded);
- Py_DECREF(decoded);
+ Py_ssize_t n;
+ DECODER_DECODE(input, 1, n);
+ /* We got n chars for 1 byte */
+ chars_decoded += n;
cookie.bytes_to_feed += 1;
-
- state = PyObject_CallMethodObjArgs(self->decoder,
- _PyIO_str_getstate, NULL);
- if (state == NULL)
- goto fail;
- if (!PyArg_Parse(state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) {
- Py_DECREF(state);
- goto fail;
- }
- Py_DECREF(state);
+ DECODER_GETSTATE();
if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
/* Decoder buffer is empty, so this is a safe start point. */
@@ -2272,8 +2331,7 @@ textiowrapper_tell(textio *self, PyObject *args)
}
}
- /* finally */
- Py_XDECREF(posobj);
+finally:
res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
Py_DECREF(saved_state);
if (res == NULL)
@@ -2284,8 +2342,7 @@ textiowrapper_tell(textio *self, PyObject *args)
cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
return textiowrapper_build_cookie(&cookie);
- fail:
- Py_XDECREF(posobj);
+fail:
if (saved_state) {
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
diff --git a/Modules/_json.c b/Modules/_json.c
index 75b14ee..6c1a194 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -335,7 +335,7 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next
PyObject *rval = NULL;
Py_ssize_t len = PyUnicode_GET_SIZE(pystr);
Py_ssize_t begin = end - 1;
- Py_ssize_t next = begin;
+ Py_ssize_t next /* = begin */;
const Py_UNICODE *buf = PyUnicode_AS_UNICODE(pystr);
PyObject *chunks = NULL;
PyObject *chunk = NULL;
@@ -1532,13 +1532,12 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
goto bail;
Py_CLEAR(ident);
}
+ /* TODO DOES NOT RUN; dead code
if (s->indent != Py_None) {
- /* TODO: DOES NOT RUN */
indent_level -= 1;
- /*
- yield '\n' + (' ' * (_indent * _current_indent_level))
- */
- }
+
+ yield '\n' + (' ' * (_indent * _current_indent_level))
+ }*/
if (PyList_Append(rval, close_dict))
goto bail;
return 0;
@@ -1624,13 +1623,13 @@ encoder_listencode_list(PyEncoderObject *s, PyObject *rval, PyObject *seq, Py_ss
goto bail;
Py_CLEAR(ident);
}
+
+ /* TODO: DOES NOT RUN
if (s->indent != Py_None) {
- /* TODO: DOES NOT RUN */
indent_level -= 1;
- /*
- yield '\n' + (' ' * (_indent * _current_indent_level))
- */
- }
+
+ yield '\n' + (' ' * (_indent * _current_indent_level))
+ }*/
if (PyList_Append(rval, close_array))
goto bail;
Py_DECREF(s_fast);
diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h
index 14425de..b9917c3 100644
--- a/Modules/_multiprocessing/multiprocessing.h
+++ b/Modules/_multiprocessing/multiprocessing.h
@@ -4,7 +4,7 @@
#define PY_SSIZE_T_CLEAN
#ifdef __sun
-/* The control message API is only available on Solaris
+/* The control message API is only available on Solaris
if XPG 4.2 or later is requested. */
#define _XOPEN_SOURCE 500
#endif
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index e4969e3..4bc16c3 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -673,7 +673,6 @@ void _pysqlite_final_callback(sqlite3_context* context)
{
PyObject* function_result = NULL;
PyObject** aggregate_instance;
- PyObject* aggregate_class;
#ifdef WITH_THREAD
PyGILState_STATE threadstate;
@@ -681,8 +680,6 @@ void _pysqlite_final_callback(sqlite3_context* context)
threadstate = PyGILState_Ensure();
#endif
- aggregate_class = (PyObject*)sqlite3_user_data(context);
-
aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
if (!*aggregate_instance) {
/* this branch is executed if there was an exception in the aggregate's
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index 97908a3..eb099c4 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -126,11 +126,9 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*
static void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
{
- int rc;
-
/* Reset the statement if the user has not closed the cursor */
if (self->statement) {
- rc = pysqlite_statement_reset(self->statement);
+ pysqlite_statement_reset(self->statement);
Py_DECREF(self->statement);
}
@@ -529,7 +527,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
if (self->statement != NULL) {
/* There is an active statement */
- rc = pysqlite_statement_reset(self->statement);
+ pysqlite_statement_reset(self->statement);
}
operation_cstr = _PyUnicode_AsStringAndSize(operation, &operation_len);
@@ -734,7 +732,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
}
if (multiple) {
- rc = pysqlite_statement_reset(self->statement);
+ pysqlite_statement_reset(self->statement);
}
Py_XDECREF(parameters);
}
diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c
index f89fc9a..4e039c1 100644
--- a/Modules/_sqlite/statement.c
+++ b/Modules/_sqlite/statement.c
@@ -369,11 +369,9 @@ void pysqlite_statement_mark_dirty(pysqlite_Statement* self)
void pysqlite_statement_dealloc(pysqlite_Statement* self)
{
- int rc;
-
if (self->st) {
Py_BEGIN_ALLOW_THREADS
- rc = sqlite3_finalize(self->st);
+ sqlite3_finalize(self->st);
Py_END_ALLOW_THREADS
}
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 141b1ae..d077895 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -354,7 +354,6 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self)
/* Actually negotiate SSL connection */
/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
- sockstate = 0;
do {
PySSL_BEGIN_ALLOW_THREADS
ret = SSL_do_handshake(self->ssl);
@@ -1090,7 +1089,6 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args)
goto error;
}
do {
- err = 0;
PySSL_BEGIN_ALLOW_THREADS
len = SSL_write(self->ssl, buf.buf, buf.len);
err = SSL_get_error(self->ssl, len);
@@ -1226,7 +1224,6 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args)
}
}
do {
- err = 0;
PySSL_BEGIN_ALLOW_THREADS
count = SSL_read(self->ssl, mem, len);
err = SSL_get_error(self->ssl, count);
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index ffd1ec2..14ed55e 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -53,8 +53,9 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds)
_PyTime_timeval curtime;
_PyTime_timeval endtime;
+
+ _PyTime_gettimeofday(&endtime);
if (microseconds > 0) {
- _PyTime_gettimeofday(&endtime);
endtime.tv_sec += microseconds / (1000 * 1000);
endtime.tv_usec += microseconds % (1000 * 1000);
}
@@ -1307,7 +1308,9 @@ PyInit__thread(void)
/* Add a symbolic constant */
d = PyModule_GetDict(m);
- ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
+ ThreadError = PyExc_RuntimeError;
+ Py_INCREF(ThreadError);
+
PyDict_SetItemString(d, "error", ThreadError);
Locktype.tp_doc = lock_doc;
Py_INCREF(&Locktype);
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index c7c1530..5939357 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -2005,7 +2005,7 @@ static int
PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
{
PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData;
- PyObject *self, *func, *arg, *res;
+ PyObject *func, *arg, *res;
int i, rv;
Tcl_Obj *obj_res;
@@ -2014,7 +2014,6 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
/* TBD: no error checking here since we know, via the
* Tkapp_CreateCommand() that the client data is a two-tuple
*/
- self = data->self;
func = data->func;
/* Create argument list (argv1, ..., argvN) */
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index fe6106c..533f404 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -876,7 +876,6 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n)
if (Py_SIZE(self) > 0) {
if (n < 0)
n = 0;
- items = self->ob_item;
if ((self->ob_descr->itemsize != 0) &&
(Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
return PyErr_NoMemory();
diff --git a/Modules/audioop.c b/Modules/audioop.c
index a031d42..daf70dc 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -513,7 +513,6 @@ audioop_findfit(PyObject *self, PyObject *args)
best_result = result;
best_j = 0;
- j = 0;
for ( j=1; j<=len1-len2; j++) {
aj_m1 = (double)cp1[j-1];
@@ -599,7 +598,6 @@ audioop_findmax(PyObject *self, PyObject *args)
best_result = result;
best_j = 0;
- j = 0;
for ( j=1; j<=len1-len2; j++) {
aj_m1 = (double)cp1[j-1];
@@ -1433,7 +1431,6 @@ audioop_lin2adpcm(PyObject *self, PyObject *args)
if ( state == Py_None ) {
/* First time, it seems. Set defaults */
valpred = 0;
- step = 7;
index = 0;
} else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
return 0;
@@ -1534,7 +1531,6 @@ audioop_adpcm2lin(PyObject *self, PyObject *args)
if ( state == Py_None ) {
/* First time, it seems. Set defaults */
valpred = 0;
- step = 7;
index = 0;
} else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
return 0;
diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c
index 25c1a36..cbc1542 100644
--- a/Modules/cjkcodecs/_codecs_iso2022.c
+++ b/Modules/cjkcodecs/_codecs_iso2022.c
@@ -123,7 +123,7 @@ struct iso2022_config {
CODEC_INIT(iso2022)
{
- const struct iso2022_designation *desig = CONFIG_DESIGNATIONS;
+ const struct iso2022_designation *desig;
for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++)
if (desig->initializer != NULL && desig->initializer() != 0)
return -1;
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index af7ea5b..e137ff6 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -483,6 +483,7 @@ multibytecodec_encode(MultibyteCodec *codec,
return PyBytes_FromStringAndSize(NULL, 0);
buf.excobj = NULL;
+ buf.outobj = NULL;
buf.inbuf = buf.inbuf_top = *data;
buf.inbuf_end = buf.inbuf_top + datalen;
diff --git a/Modules/main.c b/Modules/main.c
index fcd9330..7ff4908 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -577,7 +577,6 @@ Py_Main(int argc, wchar_t **argv)
if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
wchar_t* buffer;
size_t len = strlen(p);
- size_t r;
buffer = malloc(len * sizeof(wchar_t));
if (buffer == NULL) {
@@ -585,7 +584,7 @@ Py_Main(int argc, wchar_t **argv)
"not enough memory to copy PYTHONEXECUTABLE");
}
- r = mbstowcs(buffer, p, len);
+ mbstowcs(buffer, p, len);
Py_SetProgramName(buffer);
/* buffer is now handed off - do not free */
} else {
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 39beaba..b07ce9c 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -95,6 +95,20 @@ corresponding Unix manual entries for more information on calls.");
#include <langinfo.h>
#endif
+#ifdef HAVE_SYS_SENDFILE_H
+#include <sys/sendfile.h>
+#endif
+
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#endif
+
/* Various compilers have only certain posix functions */
/* XXX Gosh I wish these were all moved into pyconfig.h */
#if defined(PYCC_VACPP) && defined(PYOS_OS2)
@@ -121,7 +135,7 @@ corresponding Unix manual entries for more information on calls.");
#ifdef _MSC_VER /* Microsoft compiler */
#define HAVE_GETCWD 1
#define HAVE_GETPPID 1
-#define HAVE_GETLOGIN 1
+#define HAVE_GETLOGIN 1
#define HAVE_SPAWNV 1
#define HAVE_EXECV 1
#define HAVE_PIPE 1
@@ -349,6 +363,19 @@ static int win32_can_symlink = 0;
#endif
#endif
+static int
+_parse_off_t(PyObject* arg, void* addr)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ *((off_t*)addr) = PyLong_AsLong(arg);
+#else
+ *((off_t*)addr) = PyLong_AsLongLong(arg);
+#endif
+ if (PyErr_Occurred())
+ return 0;
+ return 1;
+}
+
#if defined _MSC_VER && _MSC_VER >= 1400
/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
* valid and throw an assertion if it isn't.
@@ -1283,7 +1310,7 @@ win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
The _w represent Unicode equivalents of the aformentioned ANSI functions. */
-static int
+static int
win32_lstat(const char* path, struct win32_stat *result)
{
return win32_xstat(path, result, FALSE);
@@ -1301,7 +1328,7 @@ win32_stat(const char* path, struct win32_stat *result)
return win32_xstat(path, result, TRUE);
}
-static int
+static int
win32_stat_w(const wchar_t* path, struct win32_stat *result)
{
return win32_xstat_w(path, result, TRUE);
@@ -2339,7 +2366,7 @@ posix_listdir(PyObject *self, PyObject *args)
if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
WIN32_FIND_DATAW wFileData;
Py_UNICODE *wnamebuf, *po_wchars;
-
+
if (po == NULL) { /* Default arg: "." */
po_wchars = L".";
len = 1;
@@ -2650,6 +2677,76 @@ posix_listdir(PyObject *self, PyObject *args)
#endif /* which OS */
} /* end of posix_listdir */
+#ifdef HAVE_FDOPENDIR
+PyDoc_STRVAR(posix_fdlistdir__doc__,
+"fdlistdir(fd) -> list_of_strings\n\n\
+Like listdir(), but uses a file descriptor instead.\n\
+After succesful execution of this function, fd will be closed.");
+
+static PyObject *
+posix_fdlistdir(PyObject *self, PyObject *args)
+{
+ PyObject *d, *v;
+ DIR *dirp;
+ struct dirent *ep;
+ int fd;
+
+ errno = 0;
+ if (!PyArg_ParseTuple(args, "i:fdlistdir", &fd))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ dirp = fdopendir(fd);
+ Py_END_ALLOW_THREADS
+ if (dirp == NULL) {
+ close(fd);
+ return posix_error();
+ }
+ if ((d = PyList_New(0)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ return NULL;
+ }
+ for (;;) {
+ errno = 0;
+ Py_BEGIN_ALLOW_THREADS
+ ep = readdir(dirp);
+ Py_END_ALLOW_THREADS
+ if (ep == NULL) {
+ if (errno == 0) {
+ break;
+ } else {
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(d);
+ return posix_error();
+ }
+ }
+ if (ep->d_name[0] == '.' &&
+ (NAMLEN(ep) == 1 ||
+ (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
+ continue;
+ v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
+ if (v == NULL) {
+ Py_CLEAR(d);
+ break;
+ }
+ if (PyList_Append(d, v) != 0) {
+ Py_DECREF(v);
+ Py_CLEAR(d);
+ break;
+ }
+ Py_DECREF(v);
+ }
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+
+ return d;
+}
+#endif
+
#ifdef MS_WINDOWS
/* A helper function for abspath on win32 */
static PyObject *
@@ -2741,7 +2838,7 @@ posix__getfinalpathname(PyObject *self, PyObject *args)
int result_length;
PyObject *result;
wchar_t *path;
-
+
if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
return NULL;
}
@@ -2762,7 +2859,7 @@ posix__getfinalpathname(PyObject *self, PyObject *args)
/* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
-
+
if(hFile == INVALID_HANDLE_VALUE) {
return win32_error_unicode("GetFinalPathNamyByHandle", path);
return PyErr_Format(PyExc_RuntimeError,
@@ -2930,6 +3027,52 @@ posix_nice(PyObject *self, PyObject *args)
}
#endif /* HAVE_NICE */
+
+#ifdef HAVE_GETPRIORITY
+PyDoc_STRVAR(posix_getpriority__doc__,
+"getpriority(which, who) -> current_priority\n\n\
+Get program scheduling priority.");
+
+static PyObject *
+posix_getpriority(PyObject *self, PyObject *args)
+{
+ int which, who, retval;
+
+ if (!PyArg_ParseTuple(args, "ii", &which, &who))
+ return NULL;
+ errno = 0;
+ Py_BEGIN_ALLOW_THREADS
+ retval = getpriority(which, who);
+ Py_END_ALLOW_THREADS
+ if (errno != 0)
+ return posix_error();
+ return PyLong_FromLong((long)retval);
+}
+#endif /* HAVE_GETPRIORITY */
+
+
+#ifdef HAVE_SETPRIORITY
+PyDoc_STRVAR(posix_setpriority__doc__,
+"setpriority(which, who, prio) -> None\n\n\
+Set program scheduling priority.");
+
+static PyObject *
+posix_setpriority(PyObject *self, PyObject *args)
+{
+ int which, who, prio, retval;
+
+ if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ retval = setpriority(which, who, prio);
+ Py_END_ALLOW_THREADS
+ if (retval == -1)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_SETPRIORITY */
+
+
PyDoc_STRVAR(posix_rename__doc__,
"rename(old, new)\n\n\
Rename a file or directory.");
@@ -3072,7 +3215,7 @@ BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
-
+
/* Get WIN32_FIND_DATA structure for the path to determine if
it is a symlink */
if(is_directory &&
@@ -4262,7 +4405,7 @@ posix_getgroups(PyObject *self, PyObject *noargs)
#endif
gid_t grouplist[MAX_GROUPS];
- /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
+ /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
* This is a helper variable to store the intermediate result when
* that happens.
*
@@ -4478,15 +4621,15 @@ static PyObject *
posix_getlogin(PyObject *self, PyObject *noargs)
{
PyObject *result = NULL;
-#ifdef MS_WINDOWS
+#ifdef MS_WINDOWS
wchar_t user_name[UNLEN + 1];
DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
if (GetUserNameW(user_name, &num_chars)) {
/* num_chars is the number of unicode chars plus null terminator */
result = PyUnicode_FromWideChar(user_name, num_chars - 1);
- }
- else
+ }
+ else
result = PyErr_SetFromWindowsErr(GetLastError());
#else
char *name;
@@ -5170,12 +5313,12 @@ win_readlink(PyObject *self, PyObject *args)
FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
0);
Py_END_ALLOW_THREADS
-
+
if (reparse_point_handle==INVALID_HANDLE_VALUE)
{
return win32_error_unicode("readlink", path);
}
-
+
Py_BEGIN_ALLOW_THREADS
/* New call DeviceIoControl to read the reparse point */
io_result = DeviceIoControl(
@@ -5246,7 +5389,7 @@ win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
int target_is_directory = 0;
DWORD res;
WIN32_FILE_ATTRIBUTE_DATA src_info;
-
+
if (!check_CreateSymbolicLinkW())
{
/* raise NotImplementedError */
@@ -5265,7 +5408,7 @@ win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Py_DECREF(src);
return NULL;
}
-
+
/* if src is a directory, ensure target_is_directory==1 */
if(
GetFileAttributesExW(
@@ -5288,7 +5431,7 @@ win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
{
return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
}
-
+
Py_INCREF(Py_None);
return Py_None;
}
@@ -5628,8 +5771,7 @@ posix_lseek(PyObject *self, PyObject *args)
#if !defined(HAVE_LARGEFILE_SUPPORT)
pos = PyLong_AsLong(posobj);
#else
- pos = PyLong_Check(posobj) ?
- PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
+ pos = PyLong_AsLongLong(posobj);
#endif
if (PyErr_Occurred())
return NULL;
@@ -5723,6 +5865,196 @@ posix_write(PyObject *self, PyObject *args)
return PyLong_FromSsize_t(size);
}
+#ifdef HAVE_SENDFILE
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+static Py_ssize_t
+iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
+{
+ int i, j;
+ Py_ssize_t blen, total = 0;
+
+ *iov = PyMem_New(struct iovec, cnt);
+ if (*iov == NULL) {
+ PyErr_NoMemory();
+ return total;
+ }
+
+ *buf = PyMem_New(Py_buffer, cnt);
+ if (*buf == NULL) {
+ PyMem_Del(*iov);
+ PyErr_NoMemory();
+ return total;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ if (PyObject_GetBuffer(PySequence_GetItem(seq, i),
+ &(*buf)[i], type) == -1) {
+ PyMem_Del(*iov);
+ for (j = 0; j < i; j++) {
+ PyBuffer_Release(&(*buf)[j]);
+ }
+ PyMem_Del(*buf);
+ total = 0;
+ return total;
+ }
+ (*iov)[i].iov_base = (*buf)[i].buf;
+ blen = (*buf)[i].len;
+ (*iov)[i].iov_len = blen;
+ total += blen;
+ }
+ return total;
+}
+
+static void
+iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
+{
+ int i;
+ PyMem_Del(iov);
+ for (i = 0; i < cnt; i++) {
+ PyBuffer_Release(&buf[i]);
+ }
+ PyMem_Del(buf);
+}
+#endif
+
+PyDoc_STRVAR(posix_sendfile__doc__,
+"sendfile(out, in, offset, nbytes) -> byteswritten\n\
+sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
+ -> byteswritten\n\
+Copy nbytes bytes from file descriptor in to file descriptor out.");
+
+static PyObject *
+posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ int in, out;
+ Py_ssize_t ret;
+ off_t offset;
+
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+#ifndef __APPLE__
+ Py_ssize_t len;
+#endif
+ PyObject *headers = NULL, *trailers = NULL;
+ Py_buffer *hbuf, *tbuf;
+ off_t sbytes;
+ struct sf_hdtr sf;
+ int flags = 0;
+ sf.headers = NULL;
+ sf.trailers = NULL;
+ static char *keywords[] = {"out", "in",
+ "offset", "count",
+ "headers", "trailers", "flags", NULL};
+
+#ifdef __APPLE__
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
+ keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
+#else
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
+ keywords, &out, &in, _parse_off_t, &offset, &len,
+#endif
+ &headers, &trailers, &flags))
+ return NULL;
+ if (headers != NULL) {
+ if (!PySequence_Check(headers)) {
+ PyErr_SetString(PyExc_TypeError,
+ "sendfile() headers must be a sequence or None");
+ return NULL;
+ } else {
+ Py_ssize_t i = 0; /* Avoid uninitialized warning */
+ sf.hdr_cnt = PySequence_Size(headers);
+ if (sf.hdr_cnt > 0 &&
+ !(i = iov_setup(&(sf.headers), &hbuf,
+ headers, sf.hdr_cnt, PyBUF_SIMPLE)))
+ return NULL;
+#ifdef __APPLE__
+ sbytes += i;
+#endif
+ }
+ }
+ if (trailers != NULL) {
+ if (!PySequence_Check(trailers)) {
+ PyErr_SetString(PyExc_TypeError,
+ "sendfile() trailers must be a sequence or None");
+ return NULL;
+ } else {
+ Py_ssize_t i = 0; /* Avoid uninitialized warning */
+ sf.trl_cnt = PySequence_Size(trailers);
+ if (sf.trl_cnt > 0 &&
+ !(i = iov_setup(&(sf.trailers), &tbuf,
+ trailers, sf.trl_cnt, PyBUF_SIMPLE)))
+ return NULL;
+#ifdef __APPLE__
+ sbytes += i;
+#endif
+ }
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+#ifdef __APPLE__
+ ret = sendfile(in, out, offset, &sbytes, &sf, flags);
+#else
+ ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
+#endif
+ Py_END_ALLOW_THREADS
+
+ if (sf.headers != NULL)
+ iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
+ if (sf.trailers != NULL)
+ iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
+
+ if (ret < 0) {
+ if ((errno == EAGAIN) || (errno == EBUSY)) {
+ if (sbytes != 0) {
+ // some data has been sent
+ goto done;
+ }
+ else {
+ // no data has been sent; upper application is supposed
+ // to retry on EAGAIN or EBUSY
+ return posix_error();
+ }
+ }
+ return posix_error();
+ }
+ goto done;
+
+done:
+ #if !defined(HAVE_LARGEFILE_SUPPORT)
+ return Py_BuildValue("l", sbytes);
+ #else
+ return Py_BuildValue("L", sbytes);
+ #endif
+
+#else
+ Py_ssize_t count;
+ PyObject *offobj;
+ static char *keywords[] = {"out", "in",
+ "offset", "count", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
+ keywords, &out, &in, &offobj, &count))
+ return NULL;
+#ifdef linux
+ if (offobj == Py_None) {
+ Py_BEGIN_ALLOW_THREADS
+ ret = sendfile(out, in, NULL, count);
+ Py_END_ALLOW_THREADS
+ if (ret < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_BuildValue("nO", ret, Py_None);
+ }
+#endif
+ if (!_parse_off_t(offobj, &offset))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ ret = sendfile(out, in, &offset, count);
+ Py_END_ALLOW_THREADS
+ if (ret < 0)
+ return posix_error();
+ return Py_BuildValue("n", ret);
+#endif
+}
+#endif
PyDoc_STRVAR(posix_fstat__doc__,
"fstat(fd) -> stat result\n\n\
@@ -7762,6 +8094,552 @@ posix_getresgid (PyObject *self, PyObject *noargs)
}
#endif
+/* Posix *at family of functions:
+ faccessat, fchmodat, fchownat, fstatat, futimesat,
+ linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
+ unlinkat, utimensat, mkfifoat */
+
+#ifdef HAVE_FACCESSAT
+PyDoc_STRVAR(posix_faccessat__doc__,
+"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
+Like access() but if path is relative, it is taken as relative to dirfd.\n\
+flags is optional and can be constructed by ORing together zero or more\n\
+of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_faccessat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *path;
+ int mode;
+ int res;
+ int dirfd, flags = 0;
+ if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
+ &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ Py_BEGIN_ALLOW_THREADS
+ res = faccessat(dirfd, path, mode, flags);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ return PyBool_FromLong(res == 0);
+}
+#endif
+
+#ifdef HAVE_FCHMODAT
+PyDoc_STRVAR(posix_fchmodat__doc__,
+"fchmodat(dirfd, path, mode, flags=0)\n\n\
+Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
+flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_fchmodat(PyObject *self, PyObject *args)
+{
+ int dirfd, mode, res;
+ int flags = 0;
+ PyObject *opath;
+ char *path;
+
+ if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
+ &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
+ return NULL;
+
+ path = PyBytes_AsString(opath);
+
+ Py_BEGIN_ALLOW_THREADS
+ res = fchmodat(dirfd, path, mode, flags);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FCHMODAT */
+
+#ifdef HAVE_FCHOWNAT
+PyDoc_STRVAR(posix_fchownat__doc__,
+"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
+Like chown() but if path is relative, it is taken as relative to dirfd.\n\
+flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_fchownat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ int dirfd, res;
+ long uid, gid;
+ int flags = 0;
+ char *path;
+
+ if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
+ &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
+ return NULL;
+
+ path = PyBytes_AsString(opath);
+
+ Py_BEGIN_ALLOW_THREADS
+ res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FCHOWNAT */
+
+#ifdef HAVE_FSTATAT
+PyDoc_STRVAR(posix_fstatat__doc__,
+"fstatat(dirfd, path, flags=0) -> stat result\n\n\
+Like stat() but if path is relative, it is taken as relative to dirfd.\n\
+flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_fstatat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *path;
+ STRUCT_STAT st;
+ int dirfd, res, flags = 0;
+
+ if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
+ &dirfd, PyUnicode_FSConverter, &opath, &flags))
+ return NULL;
+ path = PyBytes_AsString(opath);
+
+ Py_BEGIN_ALLOW_THREADS
+ res = fstatat(dirfd, path, &st, flags);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res != 0)
+ return posix_error();
+
+ return _pystat_fromstructstat(&st);
+}
+#endif
+
+#ifdef HAVE_FUTIMESAT
+PyDoc_STRVAR(posix_futimesat__doc__,
+"futimesat(dirfd, path, (atime, mtime))\n\
+futimesat(dirfd, path, None)\n\n\
+Like utime() but if path is relative, it is taken as relative to dirfd.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_futimesat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *path;
+ int res, dirfd;
+ PyObject* arg;
+
+ struct timeval buf[2];
+
+ if (!PyArg_ParseTuple(args, "iO&O:futimesat",
+ &dirfd, PyUnicode_FSConverter, &opath, &arg))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ if (arg == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = futimesat(dirfd, path, NULL);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "futimesat() arg 3 must be a tuple (atime, mtime)");
+ Py_DECREF(opath);
+ return NULL;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ res = futimesat(dirfd, path, buf);
+ Py_END_ALLOW_THREADS
+ }
+ Py_DECREF(opath);
+ if (res < 0) {
+ return posix_error();
+ }
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_LINKAT
+PyDoc_STRVAR(posix_linkat__doc__,
+"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
+Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
+and if dstpath is relative, it is taken as relative to dstfd.\n\
+flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
+If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
+srcpath is interpreted relative to the current working directory. This\n\
+also applies for dstpath.");
+
+static PyObject *
+posix_linkat(PyObject *self, PyObject *args)
+{
+ PyObject *osrc, *odst;
+ char *src, *dst;
+ int res, srcfd, dstfd;
+ int flags = 0;
+
+ if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
+ &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
+ return NULL;
+ src = PyBytes_AsString(osrc);
+ dst = PyBytes_AsString(odst);
+ Py_BEGIN_ALLOW_THREADS
+ res = linkat(srcfd, src, dstfd, dst, flags);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(osrc);
+ Py_DECREF(odst);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_LINKAT */
+
+#ifdef HAVE_MKDIRAT
+PyDoc_STRVAR(posix_mkdirat__doc__,
+"mkdirat(dirfd, path, mode=0o777)\n\n\
+Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_mkdirat(PyObject *self, PyObject *args)
+{
+ int res, dirfd;
+ PyObject *opath;
+ char *path;
+ int mode = 0777;
+
+ if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
+ &dirfd, PyUnicode_FSConverter, &opath, &mode))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ Py_BEGIN_ALLOW_THREADS
+ res = mkdirat(dirfd, path, mode);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
+PyDoc_STRVAR(posix_mknodat__doc__,
+"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
+Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_mknodat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *filename;
+ int mode = 0600;
+ int device = 0;
+ int res, dirfd;
+ if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
+ PyUnicode_FSConverter, &opath, &mode, &device))
+ return NULL;
+ filename = PyBytes_AS_STRING(opath);
+ Py_BEGIN_ALLOW_THREADS
+ res = mknodat(dirfd, filename, mode, device);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_OPENAT
+PyDoc_STRVAR(posix_openat__doc__,
+"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
+Like open() but if path is relative, it is taken as relative to dirfd.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_openat(PyObject *self, PyObject *args)
+{
+ PyObject *ofile;
+ char *file;
+ int flag, dirfd, fd;
+ int mode = 0777;
+
+ if (!PyArg_ParseTuple(args, "iO&i|i:openat",
+ &dirfd, PyUnicode_FSConverter, &ofile,
+ &flag, &mode))
+ return NULL;
+ file = PyBytes_AsString(ofile);
+ Py_BEGIN_ALLOW_THREADS
+ fd = openat(dirfd, file, flag, mode);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(ofile);
+ if (fd < 0)
+ return posix_error();
+ return PyLong_FromLong((long)fd);
+}
+#endif
+
+#ifdef HAVE_READLINKAT
+PyDoc_STRVAR(posix_readlinkat__doc__,
+"readlinkat(dirfd, path) -> path\n\n\
+Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_readlinkat(PyObject *self, PyObject *args)
+{
+ PyObject *v, *opath;
+ char buf[MAXPATHLEN];
+ char *path;
+ int n, dirfd;
+ int arg_is_unicode = 0;
+
+ if (!PyArg_ParseTuple(args, "iO&:readlinkat",
+ &dirfd, PyUnicode_FSConverter, &opath))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ v = PySequence_GetItem(args, 1);
+ if (v == NULL) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+
+ if (PyUnicode_Check(v)) {
+ arg_is_unicode = 1;
+ }
+ Py_DECREF(v);
+
+ Py_BEGIN_ALLOW_THREADS
+ n = readlinkat(dirfd, path, buf, (int) sizeof buf);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (n < 0)
+ return posix_error();
+
+ if (arg_is_unicode)
+ return PyUnicode_DecodeFSDefaultAndSize(buf, n);
+ else
+ return PyBytes_FromStringAndSize(buf, n);
+}
+#endif /* HAVE_READLINKAT */
+
+#ifdef HAVE_RENAMEAT
+PyDoc_STRVAR(posix_renameat__doc__,
+"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
+Like rename() but if oldpath is relative, it is taken as relative to\n\
+olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
+If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
+oldpath is interpreted relative to the current working directory. This\n\
+also applies for newpath.");
+
+static PyObject *
+posix_renameat(PyObject *self, PyObject *args)
+{
+ int res;
+ PyObject *opathold, *opathnew;
+ char *opath, *npath;
+ int oldfd, newfd;
+
+ if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
+ &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
+ return NULL;
+ opath = PyBytes_AsString(opathold);
+ npath = PyBytes_AsString(opathnew);
+ Py_BEGIN_ALLOW_THREADS
+ res = renameat(oldfd, opath, newfd, npath);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opathold);
+ Py_DECREF(opathnew);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#if HAVE_SYMLINKAT
+PyDoc_STRVAR(posix_symlinkat__doc__,
+"symlinkat(src, dstfd, dst)\n\n\
+Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
+If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_symlinkat(PyObject *self, PyObject *args)
+{
+ int res, dstfd;
+ PyObject *osrc, *odst;
+ char *src, *dst;
+
+ if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
+ PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
+ return NULL;
+ src = PyBytes_AsString(osrc);
+ dst = PyBytes_AsString(odst);
+ Py_BEGIN_ALLOW_THREADS
+ res = symlinkat(src, dstfd, dst);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(osrc);
+ Py_DECREF(odst);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_SYMLINKAT */
+
+#ifdef HAVE_UNLINKAT
+PyDoc_STRVAR(posix_unlinkat__doc__,
+"unlinkat(dirfd, path, flags=0)\n\n\
+Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
+flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
+specified, unlinkat() behaves like rmdir().\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_unlinkat(PyObject *self, PyObject *args)
+{
+ int dirfd, res, flags = 0;
+ PyObject *opath;
+ char *path;
+
+ if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
+ &dirfd, PyUnicode_FSConverter, &opath, &flags))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ Py_BEGIN_ALLOW_THREADS
+ res = unlinkat(dirfd, path, flags);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_UTIMENSAT
+PyDoc_STRVAR(posix_utimensat__doc__,
+"utimensat(dirfd, path, (atime_sec, atime_nsec),\n\
+ (mtime_sec, mtime_nsec), flags)\n\
+utimensat(dirfd, path, None, None, flags)\n\n\
+Updates the timestamps of a file with nanosecond precision. If path is\n\
+relative, it is taken as relative to dirfd.\n\
+The second form sets atime and mtime to the current time.\n\
+flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.\n\
+If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
+current time.\n\
+If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
+
+static PyObject *
+posix_utimensat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *path;
+ int res, dirfd, flags = 0;
+ PyObject *atime, *mtime;
+
+ struct timespec buf[2];
+
+ if (!PyArg_ParseTuple(args, "iO&OO|i:utimensat",
+ &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
+ return NULL;
+ path = PyBytes_AsString(opath);
+ if (atime == Py_None && mtime == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = utimensat(dirfd, path, NULL, flags);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
+ Py_DECREF(opath);
+ return NULL;
+ }
+ else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
+ Py_DECREF(opath);
+ return NULL;
+ }
+ else {
+ if (!PyArg_ParseTuple(atime, "ll:utimensat",
+ &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(mtime, "ll:utimensat",
+ &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
+ Py_DECREF(opath);
+ return NULL;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ res = utimensat(dirfd, path, buf, flags);
+ Py_END_ALLOW_THREADS
+ }
+ Py_DECREF(opath);
+ if (res < 0) {
+ return posix_error();
+ }
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_MKFIFOAT
+PyDoc_STRVAR(posix_mkfifoat__doc__,
+"mkfifoat(dirfd, path, mode=0o666)\n\n\
+Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
+If path is relative and dirfd is the special value AT_FDCWD, then path\n\
+is interpreted relative to the current working directory.");
+
+static PyObject *
+posix_mkfifoat(PyObject *self, PyObject *args)
+{
+ PyObject *opath;
+ char *filename;
+ int mode = 0666;
+ int res, dirfd;
+ if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
+ &dirfd, PyUnicode_FSConverter, &opath, &mode))
+ return NULL;
+ filename = PyBytes_AS_STRING(opath);
+ Py_BEGIN_ALLOW_THREADS
+ res = mkfifoat(dirfd, filename, mode);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(opath);
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
static PyMethodDef posix_methods[] = {
{"access", posix_access, METH_VARARGS, posix_access__doc__},
#ifdef HAVE_TTYNAME
@@ -7806,11 +8684,20 @@ static PyMethodDef posix_methods[] = {
{"link", posix_link, METH_VARARGS, posix_link__doc__},
#endif /* HAVE_LINK */
{"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
+#ifdef HAVE_FDOPENDIR
+ {"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
+#endif
{"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
{"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
#ifdef HAVE_NICE
{"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
#endif /* HAVE_NICE */
+#ifdef HAVE_GETPRIORITY
+ {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
+#endif /* HAVE_GETPRIORITY */
+#ifdef HAVE_SETPRIORITY
+ {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
+#endif /* HAVE_SETPRIORITY */
#ifdef HAVE_READLINK
{"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
#endif /* HAVE_READLINK */
@@ -7971,6 +8858,10 @@ static PyMethodDef posix_methods[] = {
{"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
{"read", posix_read, METH_VARARGS, posix_read__doc__},
{"write", posix_write, METH_VARARGS, posix_write__doc__},
+#ifdef HAVE_SENDFILE
+ {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
+ posix_sendfile__doc__},
+#endif
{"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
{"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
#ifdef HAVE_PIPE
@@ -8078,6 +8969,52 @@ static PyMethodDef posix_methods[] = {
{"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
#endif
+/* posix *at family of functions */
+#ifdef HAVE_FACCESSAT
+ {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
+#endif
+#ifdef HAVE_FCHMODAT
+ {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
+#endif /* HAVE_FCHMODAT */
+#ifdef HAVE_FCHOWNAT
+ {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
+#endif /* HAVE_FCHOWNAT */
+#ifdef HAVE_FSTATAT
+ {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
+#endif
+#ifdef HAVE_FUTIMESAT
+ {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
+#endif
+#ifdef HAVE_LINKAT
+ {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
+#endif /* HAVE_LINKAT */
+#ifdef HAVE_MKDIRAT
+ {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
+#endif
+#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
+ {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
+#endif
+#ifdef HAVE_OPENAT
+ {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
+#endif
+#ifdef HAVE_READLINKAT
+ {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
+#endif /* HAVE_READLINKAT */
+#ifdef HAVE_RENAMEAT
+ {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
+#endif
+#if HAVE_SYMLINKAT
+ {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
+#endif /* HAVE_SYMLINKAT */
+#ifdef HAVE_UNLINKAT
+ {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
+#endif
+#ifdef HAVE_UTIMENSAT
+ {"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
+#endif
+#ifdef HAVE_MKFIFOAT
+ {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
+#endif
{NULL, NULL} /* Sentinel */
};
@@ -8254,6 +9191,38 @@ all_ins(PyObject *d)
#ifdef O_EXLOCK
if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
#endif
+#ifdef PRIO_PROCESS
+ if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
+#endif
+#ifdef PRIO_PGRP
+ if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
+#endif
+#ifdef PRIO_USER
+ if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
+#endif
+/* posix - constants for *at functions */
+#ifdef AT_SYMLINK_NOFOLLOW
+ if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
+#endif
+#ifdef AT_EACCESS
+ if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
+#endif
+#ifdef AT_FDCWD
+ if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
+#endif
+#ifdef AT_REMOVEDIR
+ if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
+#endif
+#ifdef AT_SYMLINK_FOLLOW
+ if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
+#endif
+#ifdef UTIME_NOW
+ if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
+#endif
+#ifdef UTIME_OMIT
+ if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
+#endif
+
/* MS Windows */
#ifdef O_NOINHERIT
@@ -8362,6 +9331,17 @@ all_ins(PyObject *d)
if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
#endif /* ST_NOSUID */
+ /* FreeBSD sendfile() constants */
+#ifdef SF_NODISKIO
+ if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
+#endif
+#ifdef SF_MNOWAIT
+ if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
+#endif
+#ifdef SF_SYNC
+ if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
+#endif
+
#ifdef HAVE_SPAWNV
#if defined(PYOS_OS2) && defined(PYCC_GCC)
if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 327e470..687d964 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -3135,6 +3135,37 @@ PyDoc_STRVAR(gethostname_doc,
\n\
Return the current host name.");
+#ifdef HAVE_SETHOSTNAME
+PyDoc_STRVAR(sethostname_doc,
+"sethostname(name)\n\n\
+Sets the hostname to name.");
+
+static PyObject *
+socket_sethostname(PyObject *self, PyObject *args)
+{
+ PyObject *hnobj;
+ Py_buffer buf;
+ int res, flag = 0;
+
+ if (!PyArg_ParseTuple(args, "S:sethostname", &hnobj)) {
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "O&:sethostname",
+ PyUnicode_FSConverter, &hnobj))
+ return NULL;
+ flag = 1;
+ }
+ res = PyObject_GetBuffer(hnobj, &buf, PyBUF_SIMPLE);
+ if (!res) {
+ res = sethostname(buf.buf, buf.len);
+ PyBuffer_Release(&buf);
+ }
+ if (flag)
+ Py_DECREF(hnobj);
+ if (res)
+ return set_error();
+ Py_RETURN_NONE;
+}
+#endif
/* Python interface to gethostbyname(name). */
@@ -3407,7 +3438,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
goto finally;
af = sa->sa_family;
ap = NULL;
- al = 0;
+ /* al = 0; */
switch (af) {
case AF_INET:
ap = (char *)&((struct sockaddr_in *)sa)->sin_addr;
@@ -4233,6 +4264,10 @@ static PyMethodDef socket_methods[] = {
METH_VARARGS, gethostbyaddr_doc},
{"gethostname", socket_gethostname,
METH_NOARGS, gethostname_doc},
+#ifdef HAVE_SETHOSTNAME
+ {"sethostname", socket_sethostname,
+ METH_VARARGS, sethostname_doc},
+#endif
{"getservbyname", socket_getservbyname,
METH_VARARGS, getservbyname_doc},
{"getservbyport", socket_getservbyport,