view Python/structmember.c @ 23252:4f335ca3f11c legacy-trunk

Ignore SIGXFSZ. The SIGXFSZ signal is sent when the maximum file size limit is exceeded (RLIMIT_FSIZE). Apparently, it is also sent when the 2GB file limit is reached on platforms without large file support. The default action for SIGXFSZ is to terminate the process and dump core. When it is ignored, the system call that caused the limit to be exceeded returns an error and sets errno to EFBIG. Python always checks errno on I/O syscalls, so there is nothing to do with the signal.
author Jeremy Hylton <jeremy@alum.mit.edu>
date Tue, 23 Apr 2002 20:31:01 +0000
parents ef6f692c76e2
children 86fdf8fe7f17
line wrap: on
line source


/* Map C struct members to Python object attributes */

#include "Python.h"

#include "structmember.h"

static PyObject *
listmembers(struct memberlist *mlist)
{
	int i, n;
	PyObject *v;
	for (n = 0; mlist[n].name != NULL; n++)
		;
	v = PyList_New(n);
	if (v != NULL) {
		for (i = 0; i < n; i++)
			PyList_SetItem(v, i,
				       PyString_FromString(mlist[i].name));
		if (PyErr_Occurred()) {
			Py_DECREF(v);
			v = NULL;
		}
		else {
			PyList_Sort(v);
		}
	}
	return v;
}

PyObject *
PyMember_Get(char *addr, struct memberlist *mlist, char *name)
{
	struct memberlist *l;

	if (strcmp(name, "__members__") == 0)
		return listmembers(mlist);
	for (l = mlist; l->name != NULL; l++) {
		if (strcmp(l->name, name) == 0) {
			PyMemberDef copy;
			copy.name = l->name;
			copy.type = l->type;
			copy.offset = l->offset;
			copy.flags = l->flags;
			copy.doc = NULL;
			return PyMember_GetOne(addr, &copy);
		}
	}
	PyErr_SetString(PyExc_AttributeError, name);
	return NULL;
}

PyObject *
PyMember_GetOne(char *addr, PyMemberDef *l)
{
	PyObject *v;
	if ((l->flags & READ_RESTRICTED) &&
	    PyEval_GetRestricted()) {
		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
		return NULL;
	}
	addr += l->offset;
	switch (l->type) {
	case T_BYTE:
		v = PyInt_FromLong(
			(long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80));
		break;
	case T_UBYTE:
		v = PyInt_FromLong((long) *(char*)addr & 0xff);
		break;
	case T_SHORT:
		v = PyInt_FromLong((long) *(short*)addr);
		break;
	case T_USHORT:
		v = PyInt_FromLong((long) *(unsigned short*)addr);
		break;
	case T_INT:
		v = PyInt_FromLong((long) *(int*)addr);
		break;
	case T_UINT:
		v = PyInt_FromLong((long) *(unsigned int*)addr);
		break;
	case T_LONG:
		v = PyInt_FromLong(*(long*)addr);
		break;
	case T_ULONG:
		v = PyLong_FromDouble((double) *(unsigned long*)addr);
		break;
	case T_FLOAT:
		v = PyFloat_FromDouble((double)*(float*)addr);
		break;
	case T_DOUBLE:
		v = PyFloat_FromDouble(*(double*)addr);
		break;
	case T_STRING:
		if (*(char**)addr == NULL) {
			Py_INCREF(Py_None);
			v = Py_None;
		}
		else
			v = PyString_FromString(*(char**)addr);
		break;
	case T_STRING_INPLACE:
		v = PyString_FromString((char*)addr);
		break;
#ifdef macintosh
	case T_PSTRING:
		if (*(char**)addr == NULL) {
			Py_INCREF(Py_None);
			v = Py_None;
		}
		else
			v = PyString_FromStringAndSize(
				(*(char**)addr)+1,
				**(unsigned char**)addr);
		break;
	case T_PSTRING_INPLACE:
		v = PyString_FromStringAndSize(
			((char*)addr)+1,
			*(unsigned char*)addr);
		break;
#endif /* macintosh */
	case T_CHAR:
		v = PyString_FromStringAndSize((char*)addr, 1);
		break;
	case T_OBJECT:
		v = *(PyObject **)addr;
		if (v == NULL)
			v = Py_None;
		Py_INCREF(v);
		break;
	case T_OBJECT_EX:
		v = *(PyObject **)addr;
		if (v == NULL)
			PyErr_SetString(PyExc_AttributeError, l->name);
		Py_XINCREF(v);
		break;
	default:
		PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
		v = NULL;
	}
	return v;
}

int
PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
{
	struct memberlist *l;

	for (l = mlist; l->name != NULL; l++) {
		if (strcmp(l->name, name) == 0) {
			PyMemberDef copy;
			copy.name = l->name;
			copy.type = l->type;
			copy.offset = l->offset;
			copy.flags = l->flags;
			copy.doc = NULL;
			return PyMember_SetOne(addr, &copy, v);
		}
	}

	PyErr_SetString(PyExc_AttributeError, name);
	return -1;
}

int
PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
{
	PyObject *oldv;

	if ((l->flags & READONLY) || l->type == T_STRING
#ifdef macintosh
	    || l->type == T_PSTRING
#endif
		)
	{
		PyErr_SetString(PyExc_TypeError, "readonly attribute");
		return -1;
	}
	if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
		return -1;
	}
	if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
		PyErr_SetString(PyExc_TypeError,
				"can't delete numeric/char attribute");
		return -1;
	}
	addr += l->offset;
	switch (l->type) {
	case T_BYTE:
	case T_UBYTE:
		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			return -1;
		}
		*(char*)addr = (char) PyInt_AsLong(v);
		break;
	case T_SHORT:
	case T_USHORT:
		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			return -1;
		}
		*(short*)addr = (short) PyInt_AsLong(v);
		break;
	case T_UINT:
	case T_INT:
		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			return -1;
		}
		*(int*)addr = (int) PyInt_AsLong(v);
		break;
	case T_LONG:
		if (!PyInt_Check(v)) {
			PyErr_BadArgument();
			return -1;
		}
		*(long*)addr = PyInt_AsLong(v);
		break;
	case T_ULONG:
		if (PyInt_Check(v))
			*(long*)addr = PyInt_AsLong(v);
		else if (PyLong_Check(v))
			*(long*)addr = PyLong_AsLong(v);
		else {
			PyErr_BadArgument();
			return -1;
		}
		break;
	case T_FLOAT:
		if (PyInt_Check(v))
			*(float*)addr =
				(float) PyInt_AsLong(v);
		else if (PyFloat_Check(v))
			*(float*)addr =
				(float) PyFloat_AsDouble(v);
		else {
			PyErr_BadArgument();
			return -1;
		}
		break;
	case T_DOUBLE:
		if (PyInt_Check(v))
			*(double*)addr = (double) PyInt_AsLong(v);
		else if (PyFloat_Check(v))
			*(double*)addr = PyFloat_AsDouble(v);
		else {
			PyErr_BadArgument();
			return -1;
		}
		break;
	case T_OBJECT:
	case T_OBJECT_EX:
		Py_XINCREF(v);
		oldv = *(PyObject **)addr;
		*(PyObject **)addr = v;
		Py_XDECREF(oldv);
		break;
	case T_CHAR:
		if (PyString_Check(v) && PyString_Size(v) == 1) {
			*(char*)addr = PyString_AsString(v)[0];
		}
		else {
			PyErr_BadArgument();
			return -1;
		}
		break;
	default:
		PyErr_Format(PyExc_SystemError,
			     "bad memberdescr type for %s", l->name);
		return -1;
	}
	return 0;
}