summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2008-05-21 21:13:05 +0200
committerRené 'Necoro' Neumann <necoro@necoro.net>2008-05-21 21:13:05 +0200
commitf4368fbfb9fd0de6f1d1625ffddee17b67926c89 (patch)
tree274c6fe882a2f22aa99d0c301fb90a882e379900
parent43509c27dd08219147e4bcdb0897ebb2f5ec22cc (diff)
parentc24b4970e48771a32155cbc79060c76d218fdd85 (diff)
downloadportato-f4368fbfb9fd0de6f1d1625ffddee17b67926c89.tar.gz
portato-f4368fbfb9fd0de6f1d1625ffddee17b67926c89.tar.bz2
portato-f4368fbfb9fd0de6f1d1625ffddee17b67926c89.zip
Merged from trunk
-rw-r--r--_shm/__init__.py0
-rw-r--r--_shm/shm_wrapper.py302
-rw-r--r--_shm/shmmodule.c1409
-rw-r--r--doc/Changelog2
-rw-r--r--doc/TRANSLATORS2
-rw-r--r--icons/pausing.pngbin0 -> 3121 bytes
-rw-r--r--icons/pausing.svg171
-rwxr-xr-xportato.py8
-rw-r--r--portato/backend/portage/system.py18
-rw-r--r--portato/gui/exception_handling.py1
-rw-r--r--portato/gui/templates/AboutWindow.glade4
-rw-r--r--portato/gui/templates/MainWindow.glade194
-rw-r--r--portato/gui/templates/UpdateWindow.glade4
-rw-r--r--portato/gui/utils.py2
-rw-r--r--portato/gui/windows/main.py6
-rw-r--r--portato/plistener.py8
-rw-r--r--portato/plugins/dbus_init.py10
-rw-r--r--setup.py116
18 files changed, 308 insertions, 1949 deletions
diff --git a/_shm/__init__.py b/_shm/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/_shm/__init__.py
+++ /dev/null
diff --git a/_shm/shm_wrapper.py b/_shm/shm_wrapper.py
deleted file mode 100644
index 851f588..0000000
--- a/_shm/shm_wrapper.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# shm_wrapper - A wrapper for the shm module which provides access
-# to System V shared memory and semaphores on *nix systems.
-#
-# Copyright (c) 2007 by Philip Semanchuk
-# Contact info at http://NikitaTheSpider.com/
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-# Python modules
-import random
-import sys
-
-# Third party modules
-import shm
-from shm import error as shmerror
-
-r"""shm_wrapper - A wrapper for the shm module which provides access
-to System V shared memory and semaphores on *nix systems.
-
-The module shm is a Python wrapper around system functions like shmget. This
-module in turn offers higher-level, more Pythonic access to shared memory and
-semaphores.
-
-Full documentation is online at http://NikitaTheSpider.com/python/shm/
-
-"""
-
-def create_memory(size, permissions = 0666, InitCharacter = ' '):
- """ Creates a new shared memory segment. One can destroy it either by calling the
- module-level method remove_memory() or by calling the .remove() method of a handle to
- said memory.
- """
- memory = None
-
- # I create the memory using a randomly-generated key. I keep trying until I find one
- # that works or until I hit an error.
- while not memory:
- key = random.randint(1, sys.maxint - 1)
- try:
- memory = shm.create_memory(key, size, permissions)
- except shmerror, ExtraData:
- if shm.memory_haskey(key):
- # Oops, bad luck, the key exists. I'll try another. I can't call
- # memory_haskey() before calling create_memory() because that would create
- # a race condition where I could verify a key is not used but then another
- # process could call create_memory() with that key before I got a chance to
- # do so.
- pass
- else:
- # Uh-oh, something fundamental is wrong.
- raise shmerror, ExtraData
-
- # Here I implicitly discard the memory handle object returned to me by shm and instead
- # return my own handle to the shared memory segment.
- memory = SharedMemoryHandle(key)
-
- memory.write(InitCharacter[0] * memory.size)
-
- return memory
-
-
-def remove_memory(key):
- # Destroys the shared memory segment. Raises KeyError if the key doesn't exist.
- shm.remove_memory(shm.getshmid(key))
-
-
-class SharedMemoryHandle(object):
- def __init__(self, key):
- self._MemoryHandle = None
-
- # getshmid will raise a KeyError if there's no memory segment with this key.
- shmid = shm.getshmid(key)
- self._MemoryHandle = shm.memory(shmid)
-
-
- def __del__(self):
- if self._MemoryHandle:
- # This will raise an error if the memory has been destroyed.
- try:
- if self._MemoryHandle.attached:
- self._MemoryHandle.detach()
- except shmerror:
- pass
-
-
- def remove(self):
- if self._MemoryHandle:
- if self._MemoryHandle.attached:
- self._MemoryHandle.detach()
-
- shm.remove_memory(self._MemoryHandle.shmid)
- self._MemoryHandle = None
-
-
- def read(self, NumberOfBytes = 0, offset = 0):
- if not self._MemoryHandle.attached:
- self._MemoryHandle.attach()
-
- if not NumberOfBytes:
- NumberOfBytes = self._MemoryHandle.size - offset
-
- return self._MemoryHandle.read(NumberOfBytes, offset)
-
-
- def write(self, s, offset = 0):
- if not self._MemoryHandle.attached:
- self._MemoryHandle.attach()
-
- self._MemoryHandle.write(s, offset)
-
-
- # Properties start here ================================================================
-
- # key
- def __get_key(self): return self._MemoryHandle.key
- def __set_key(self, foo): raise AttributeError
- key = property(__get_key, __set_key)
-
- # size of segment
- def __get_size(self): return self._MemoryHandle.size
- def __set_size(self, foo): raise AttributeError
- size = property(__get_size, __set_size)
-
- # permissions
- def __get_permissions(self): return self._MemoryHandle.perm
- def __set_permissions(self, permissions): self._MemoryHandle.setperm(permissions)
- permissions = property(__get_permissions, __set_permissions)
-
- # The number of processes currently attached to this memory segment.
- def __get_number_attached(self): return self._MemoryHandle.nattch
- def __set_number_attached(self, foo): raise AttributeError
- number_attached = property(__get_number_attached, __set_number_attached)
-
- # segment's uid
- def __get_uid(self): return self._MemoryHandle.uid
- def __set_uid(self, uid): self._MemoryHandle.setuid(uid)
- uid = property(__get_uid, __set_uid)
-
- # segment's gid
- def __get_gid(self): return self._MemoryHandle.gid
- def __set_gid(self, gid): self._MemoryHandle.setgid(gid)
- gid = property(__get_gid, __set_gid)
-
- # Creator uid (read-only)
- def __get_creator_uid(self): return self._MemoryHandle.cuid
- def __set_creator_uid(self, foo): raise AttributeError
- creator_uid = property(__get_creator_uid, __set_creator_uid)
-
- # Creator gid (read-only)
- def __get_creator_gid(self): return self._MemoryHandle.cgid
- def __set_creator_gid(self, foo): raise AttributeError
- creator_gid = property(__get_creator_gid, __set_creator_gid)
-
- # Creator pid (read-only)
- def __get_creator_pid(self): return self._MemoryHandle.cpid
- def __set_creator_pid(self, foo): raise AttributeError
- creator_pid = property(__get_creator_pid, __set_creator_pid)
-
- # pid of last process to operate on this segment (read-only)
- def __get_last_pid(self): return self._MemoryHandle.lpid
- def __set_last_pid(self, foo): raise AttributeError
- last_pid = property(__get_last_pid, __set_last_pid)
-
-
-
-def create_semaphore(InitialValue = 1, permissions = 0666):
- """ Creates a new semaphore. One can destroy it either by calling the
- module-level method remove_semaphore() or by calling the .remove() method of a
- handle to said semaphore.
- """
- semaphore = None
-
- # I create the semaphore using a randomly-generated key. I keep trying until I find one
- # that works or until I hit an error.
- while not semaphore:
- key = random.randint(1, sys.maxint - 1)
- try:
- semaphore = shm.create_semaphore(key, InitialValue, permissions)
- except shmerror, ExtraData:
- if shm.semaphore_haskey(key):
- # Oops, bad luck, the key exists. I'll try another. I can't call
- # memory_haskey() before calling create_semaphore() because that would create
- # a race condition where I could verify a key is not used but then another
- # process could call create_semaphore() with that key before I got a chance to
- # do so.
- pass
- else:
- # Uh-oh, something fundamental is wrong.
- raise ExtraData
-
- # Here I implicitly discard the semaphore object returned to me by shm and instead
- # return my own handle to the semaphore.
- return SemaphoreHandle(key)
-
-
-def remove_semaphore(key):
- # Destroys the semaphore. Raises KeyError if the key doesn't exist.
- shm.remove_semaphore(shm.getsemid(key))
-
-
-class SemaphoreHandle(object):
- def __init__(self, key):
- # getsemid will raise a KeyError if appropriate.
- self._SemaphoreHandle = shm.semaphore(shm.getsemid(key))
-
-
- def remove(self):
- shm.remove_semaphore(self._SemaphoreHandle.semid)
- self._SemaphoreHandle = None
-
-
- def P(self):
- # P = prolaag = probeer te verlagen (try to decrease)
- self._SemaphoreHandle.P()
-
-
- def V(self):
- # V = verhoog (increase)
- self._SemaphoreHandle.V()
-
-
- def Z(self):
- # Z = block until Zee semaphore is Zero
- self._SemaphoreHandle.Z()
-
-
- # Properties start here ================================================================
- def __get_key(self): return self._SemaphoreHandle.key
- def __set_key(self, foo): raise AttributeError
- key = property(__get_key, __set_key)
-
-
- def __get_value(self): return self._SemaphoreHandle.val
- def __set_value(self, value): self._semaphore.setval(value)
- value = property(__get_value, __set_value)
-
-
- def __get_WaitingForZero(self): return self._SemaphoreHandle.zcnt
- def __set_WaitingForZero(self, foo): raise AttributeError
- WaitingForZero = property(__get_WaitingForZero, __set_WaitingForZero)
-
-
- def __get_WaitingForNonZero(self): return self._SemaphoreHandle.ncnt
- def __set_WaitingForNonZero(self, foo): raise AttributeError
- WaitingForNonZero = property(__get_WaitingForNonZero, __set_WaitingForNonZero)
-
-
- def __get_blocking(self): return self._SemaphoreHandle.blocking
- def __set_blocking(self, block): self._SemaphoreHandle.setblocking(block)
- blocking = property(__get_blocking, __set_blocking)
-
-
- def __get_undo(self): raise AttributeError
- def __set_undo(self, undo): self._SemaphoreHandle.setundo(undo)
- undo = property(__get_undo, __set_undo)
-
-
- # segment's uid
- def __get_uid(self): return self._SemaphoreHandle.uid
- def __set_uid(self, uid): self._SemaphoreHandle.setuid(uid)
- uid = property(__get_uid, __set_uid)
-
-
- # segment's gid
- def __get_gid(self): return self._SemaphoreHandle.gid
- def __set_gid(self, gid): self._SemaphoreHandle.setgid(gid)
- gid = property(__get_gid, __set_gid)
-
-
- # Creator uid (read-only)
- def __get_creator_uid(self): return self._SemaphoreHandle.cuid
- def __set_creator_uid(self, foo): raise AttributeError
- creator_uid = property(__get_creator_uid, __set_creator_uid)
-
-
- # Creator gid (read-only)
- def __get_creator_gid(self): return self._SemaphoreHandle.cgid
- def __set_creator_gid(self, foo): raise AttributeError
- creator_gid = property(__get_creator_gid, __set_creator_gid)
-
-
- # Creator pid -- since semaphores have a lot of the same properties as memory
- # objects, one would expect creator PID to be exposed here, but it isn't
- # made available by the system (true AFAICT for BSDs, OS X and Solaris).
-
-
- # pid of last process to operate on this segment (read-only)
- def __get_last_pid(self): return self._SemaphoreHandle.lpid
- def __set_last_pid(self, foo): raise AttributeError
- last_pid = property(__get_last_pid, __set_last_pid)
diff --git a/_shm/shmmodule.c b/_shm/shmmodule.c
deleted file mode 100644
index c214430..0000000
--- a/_shm/shmmodule.c
+++ /dev/null
@@ -1,1409 +0,0 @@
-/****************************************************************************
- *
- * shmmodule.c Copyright 1997, 1998 by INRIA. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY WARRANTIES, EXPRESS OR IMPLIED,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *
- * IN NO EVENT SHALL THE INRIA OR THE AUTHORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES,
- * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
- * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION, HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT,
- * INCLUDING NEGLIGENCE OR OTHERWISE, ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ***************************************************************************/
-
-/* Python Shared Memory module
- Written by Vladimir Marangozov
- Adopted by Philip Semanchuk
-
- This module provides an interface to System V shared memory IPC.
-
- Version history:
- - 1.0 (sometime in the 1990s) - Released by Mr. Marangozov
- - 1.1 (Feb 2007) - Released by me, Philip Semanchuk. Fixes a few bugs (including some
- memory leaks) and adds the ability to read the blocking flag on semaphores.
- - 1.1.1 (Mar 2007)- Updated setup.py to handle compile options for Linux users.
- - 1.1.2 (Nov 2007) - Fixed a sprintf() format in repr to handle size_t.
- - 1.1.3 (Nov 2007) - Changed #define of key to _key instead of __key for OS X Leopard.
- Thanks to Bill Hart.
- - 1.1.4 (Jan 2008) - Changed the reference to key in the ipc_perm structure to the
- explicit #define IPC_PERM_KEY_NAME.
- - 1.2 (Jan 2008) - Surrounded semop() calls with Py_BEGIN/END_ALLOW_THREADS for
- thread-friendly code. Patch provided by James Teh (thanks!).
- Fixed some int/long/ulong sloppiness pointed out by kAbY that could cause
- crashes on 64-bit platforms.
-
-
- See http://NikitaTheSpider.com/python/shm/ for more thorough documentation, a more Pythonic
- wrapper, updates, contact info, setup.py, etc.
-
-
- Module interface:
-
- - shm.create_memory(int Key, int Size [,int Perm=0666]) --> object
- - shm.create_semaphore(int Key [,int Value=1 [,int Perm=0666]]) --> object
- - shm.error
- - shm.ftok(string Path, int ProjId) --> int
- - shm.getsemid(int Key) --> int
- - shm.getshmid(int Key) --> int
- - shm.memory(int Shmid) --> object
- - shm.memory_haskey(int Key) --> int
- - shm.remove_memory(int Shmid) --> None
- - shm.remove_semaphore(int Semid) --> None
- - shm.semaphore(int Semid) --> object
- - shm.semaphore_haskey(int Key) --> int
-
- Memory Objects:
-
- + Members:
-
- - m.addr - attachment address in the process address space
- - m.attached - 0|1
- - m.cgid - gid of creator
- - m.cpid - pid of creator
- - m.cuid - uid of creator
- - m.gid - gid of owner
- - m.key - segment key or IPC_PRIVATE (=0)
- - m.lpid - pid of last shmop
- - m.nattch - current # of attached processes
- - m.perm - operation permission
- - m.shmid - shared memory segment id
- - m.size - segment size
- - m.uid - uid of owner
-
- + Methods:
-
- - m.attach([int Addr=0 [,int How=0]]) --> None
- - m.detach() --> None
- - m.read(int Nbytes [,int Offset=0]) --> string
- - m.setgid(int Gid) --> None
- - m.setperm(int Perm) --> None
- - m.setuid(int Uid) --> None
- - m.write(string Data [,int Offset=0]) --> None
-
- Semaphore Objects:
-
- + Members:
-
- - s.cgid - gid of creator
- - s.cuid - uid of creator
- - s.gid - gid of owner
- - s.key - semaphore key or IPC_PRIVATE (=0)
- - s.lpid - pid of last semop
- - s.ncnt - current # of processes waiting for s.val > 0
- - s.perm - operation permission
- - s.semid - semaphore id
- - s.uid - uid of owner
- - s.val - value of the semaphore counter
- - s.zcnt - current # of processes waiting for s.val == 0
- - s.blocking - whether or not the semaphore is in blocking mode
-
- + Methods:
-
- - s.P() --> None - blocks if s.val == 0; decrements s.val
- - s.V() --> None - increments s.val
- - s.Z() --> None - blocks until s.val == 0
- - s.setblocking(0|1) --> None
- - s.setgid(int Gid) --> None
- - s.setperm(int Perm) --> None
- - s.setuid(int Uid) --> None
- - s.setundo(0|1) --> None
- - s.setval(int Value) --> None
-
-*/
-
-/* ------------------------------------------------------------------------- */
-#include "Python.h"
-#include "structmember.h"
-
-/* v1.1 - added */
-#ifdef __FreeBSD__
-#include <machine/param.h> /* for system definition of PAGE_SIZE */
-#endif
-
-#include <sys/types.h>
-#include <sys/ipc.h> /* for system's IPC_xxx definitions */
-#include <sys/shm.h> /* for shmget, shmat, shmdt, shmctl */
-#include <sys/sem.h> /* for semget, semctl, semop */
-
-/* v1.1.4 - The name of this member varies and is sniffed out by setup.py. */
-#if defined(ZERO_UNDERSCORE_KEY)
-#define IPC_PERM_KEY_NAME key
-#elif defined(ONE_UNDERSCORE_KEY)
-#define IPC_PERM_KEY_NAME _key
-#elif defined(TWO_UNDERSCORE_KEY)
-#define IPC_PERM_KEY_NAME __key
-#endif
-
-/*
--- Exception type for errors detected by this module.
-*/
-
-static PyObject *PyShm_Error;
-
-/*
--- Convenience function to raise an error according to errno.
-*/
-
-static PyObject *
-PyShm_Err(void)
-{
- return PyErr_SetFromErrno(PyShm_Error);
-}
-
-/*
--- The object holding a shared memory segment
-*/
-
-typedef struct {
- PyObject_HEAD
- int shmid; /* shared memory id */
- int mode; /* attachment mode */
- void *addr; /* shmseg start address */
- struct shmid_ds ds; /* data structure */
-} PyShmMemoryObject;
-
-staticforward PyTypeObject PyShmMemory_Type;
-
-#define PyShmObj PyShmMemoryObject
-#define PyShmMemory_Check(op) ((op)->ob_type == &PyShmMemory_Type)
-
-/*
--- The object holding a semaphore
-*/
-
-typedef struct {
- PyObject_HEAD
- int semid; /* semaphore id */
- short opflag; /* IPC_NOWAIT, SEM_UNDO */
- struct semid_ds ds; /* data structure */
-} PyShmSemaphoreObject;
-
-#ifndef HAVE_UNION_SEMUN
-union semun {
- int val; /* used for SETVAL only */
- struct semid_ds *buf; /* for IPC_STAT and IPC_SET */
- unsigned short *array; /* used for GETALL and SETALL */
-};
-#endif
-
-typedef union semun semctl_arg;
-
-staticforward PyTypeObject PyShmSemaphore_Type;
-
-#define PyShmSemObj PyShmSemaphoreObject
-#define PyShmSemaphore_Check(op) ((op)->ob_type == &PyShmSemaphore_Type)
-
-/*
--- Internal dictionaries for Python memory and semaphore objects
-*/
-
-static PyObject *shm_dict = NULL;
-static PyObject *sem_dict = NULL;
-
-/************************************************************/
-/* Memory Objects */
-/************************************************************/
-
-/* This is to check the validity of a Python memory object
- (and to refresh its data status structure). Notably, we
- have to check that the real memory segment it points to
- is still in memory and hasn't changed (test its id and
- size). It could be that the segment has been removed and
- created again by someone else with the same key. This is
- fine as far as the segment (1) has the same id and size,
- and (2) is accessible via shmctl. If you have a better
- test, you're welcome :-) */
-
-static int
-check_memory_identity(PyShmObj *o)
-{
- int new_shmid;
- int old_shmid = o->shmid;
- int old_size = o->ds.shm_segsz;
- key_t old_key = o->ds.shm_perm.IPC_PERM_KEY_NAME;
-
- /*
- -- 1. Try to get the segment identified by the old key (if not IPC_PRIVATE)
- -- 2. On failure or on mismatch of the new and the old id -> fail.
- -- 3. Try to refresh the object's status using the new id.
- -- 4. On failure (the segment cannot be accessed) -> fail.
- -- 5. Finaly, compare the old size and the one we got via the new id.
- */
- if (old_key != IPC_PRIVATE) {
- new_shmid = shmget(old_key, 0, 0);
- if (new_shmid != old_shmid)
- return 0;
- }
- else
- new_shmid = old_shmid;
- if ((shmctl(new_shmid, IPC_STAT, &(o->ds)) != -1) &&
- (old_size == o->ds.shm_segsz) &&
- (old_key == o->ds.shm_perm.IPC_PERM_KEY_NAME))
- return 1;
- return 0;
-}
-
-/* Convenience macro for updating the shared memory data status structure */
-
-#define refresh_memory_status(o) \
- if (!check_memory_identity(o)) { \
- PyErr_SetString(PyShm_Error, "can't access shared memory segment"); \
- return NULL; \
- }
-
-/*
--- attach([,address=0 [,how=0]])
-*/
-
-/* Attach the shared memory segment to the process address space */
-
-static PyObject *
-PyShmMemory_attach(PyShmObj *self, PyObject *args)
-{
- long address = 0;
- int mode = 0;
- void *addr, *old_addr;
-
- if (!PyArg_ParseTuple(args, "|li", &address, &mode))
- return NULL;
- refresh_memory_status(self);
- /* return if already attached with the same mode to the same address */
- if ((self->addr != NULL) && (self->mode == mode) &&
- ((address == 0) || (self->addr == (void *)address))) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- /* perform the attach */
- addr = (void *)shmat(self->shmid, (void *)address, mode);
- if (addr == (void *)-1)
- return PyShm_Err();
- old_addr = self->addr;
- self->addr = addr;
- self->mode = mode;
- /* XXX - multiple attachments of the same shared memory segment
- to different locations of the process address space is
- not supported. */
- shmdt(old_addr);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
--- detach()
-*/
-
-/* Detach the memory object from the process address space */
-
-static PyObject *
-PyShmMemory_detach(PyShmObj *self, PyObject *args)
-{
- if (!PyArg_NoArgs(args))
- return NULL;
- if (self->addr != NULL) {
- refresh_memory_status(self);
- if (shmdt(self->addr) != 0)
- return PyShm_Err();
- self->addr = NULL; /* mark as detached */
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
--- read(int Nbytes [,int Offset=0]) --> string
-*/
-
-/* Return a string of n bytes peeked from the shared memory segment */
-
-static PyObject *
-PyShmMemory_read(PyShmObj *self, PyObject *args)
-{
- long n;
- long offset = 0;
- char buf[128];
- char *addr;
-
- if (!PyArg_ParseTuple(args, "l|l", &n, &offset))
- return NULL;
- refresh_memory_status(self);
- if (self->addr == NULL) {
- PyErr_SetString(PyShm_Error, "R/W operation on detached memory");
- return NULL;
- }
- if ((unsigned long)self->ds.shm_segsz < (n + offset)) {
- sprintf(buf, "read() argument%s exceed%s upper memory limit",
- offset ? "s" : "", offset ? "" : "s");
- PyErr_SetString(PyShm_Error, buf);
- return NULL;
- }
- addr = (char *)((unsigned long)self->addr + offset);
- return PyString_FromStringAndSize(addr, n);
-}
-
-/*
--- setgid(int Gid)
-*/
-
-static PyObject *
-PyShmMemory_setgid(PyShmObj *self, PyObject *args)
-{
- long newgid, oldgid;
-
- if (!PyArg_ParseTuple(args, "l", &newgid))
- return NULL;
- refresh_memory_status(self);
- oldgid = (long)self->ds.shm_perm.gid;
- self->ds.shm_perm.gid = (gid_t)newgid;
- if (shmctl(self->shmid, IPC_SET, &(self->ds)) == -1) {
- self->ds.shm_perm.gid = (gid_t)oldgid;
- return PyShm_Err();
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
--- setperm(int Perm)
-*/
-
-static PyObject *
-PyShmMemory_setperm(PyShmObj *self, PyObject *args)
-{
- long newmode, oldmode;
-
- if (!PyArg_ParseTuple(args, "l", &newmode))
- return NULL;
- refresh_memory_status(self);
- newmode &= 0777; /* permission bits only */
- oldmode = (mode_t)self->ds.shm_perm.mode;
- self->ds.shm_perm.mode ^= 0777;
- self->ds.shm_perm.mode |= (mode_t)newmode;
- if (shmctl(self->shmid, IPC_SET, &(self->ds)) == -1) {
- self->ds.shm_perm.mode = (mode_t)oldmode;
- return PyShm_Err();
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
--- setuid(int Uid)
-*/
-
-static PyObject *
-PyShmMemory_setuid(PyShmObj *self, PyObject *args)
-{
- long newuid, olduid;
-
- if (!PyArg_ParseTuple(args, "l", &newuid))
- return NULL;
- refresh_memory_status(self);
- olduid = (long)self->ds.shm_perm.uid;
- /* v1.1 - fixed typo that set the group id rather than the user id */
- self->ds.shm_perm.uid = (uid_t)newuid;
- if (shmctl(self->shmid, IPC_SET, &(self->ds)) == -1) {
- self->ds.shm_perm.uid = (uid_t)olduid;
- return PyShm_Err();
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/*
--- write(string Data [, int Offset=0])
-*/
-
-/* Write a string to the shared memory segment. */
-
-static PyObject *
-PyShmMemory_write(PyShmObj *self, PyObject *args)
-{
- char *data;
- int n;
- long offset = 0;
- char buf[128];
- char *addr;
-
- if (!PyArg_ParseTuple(args, "s#|l", &data, &n, &offset))
- return NULL;
- refresh_memory_status(self);
- if (self->addr == NULL) {
- PyErr_SetString(PyShm_Error, "R/W operation on detached memory");
- return NULL;
- }
- if (self->mode & SHM_RDONLY) {
- PyErr_SetString(PyShm_Error,
- "can't write on read-only attached memory");
- return NULL;
- }
- if ((unsigned long)self->ds.shm_segsz < (n + offset)) {
- sprintf(buf, "write() argument%s exceed%s upper memory limit",
- offset ? "s" : "", offset ? "" : "s");
- PyErr_SetString(PyShm_Error, buf);
- return NULL;
- }
- addr = (void *)((unsigned long)self->addr + offset);
- memcpy(addr, data, n);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* List of methods for shared memory objects */
-
-static PyMethodDef memory_methods[] = {
- {"attach", (PyCFunction)PyShmMemory_attach, 1,
- "attach([int Addr=0 [,int How=0]]) --> None | except shm.error"},
- {"detach", (PyCFunction)PyShmMemory_detach, 0,
- "detach() --> None | except shm.error"},
- {"read", (PyCFunction)PyShmMemory_read, 1,
- "read(int Nbytes [,int Offset=0]) --> string | except shm.error"},
- {"setgid", (PyCFunction)PyShmMemory_setgid, 1,
- "setgid(int Gid) --> None | except shm.error"},
- {"setperm", (PyCFunction)PyShmMemory_setperm, 1,
- "setperm(int Perm) --> None | except shm.error"},
- {"setuid", (PyCFunction)PyShmMemory_setuid, 1,
- "setuid(int Uid) --> None | except shm.error"},
- {"write", (PyCFunction)PyShmMemory_write, 1,
- "write(string Data [,int Offset=0]) --> None | except shm.error"},
- {NULL, NULL} /* sentinel */
-};
-
-#define OFF(x) offsetof(PyShmMemoryObject, x)
-#define OFF1(x) OFF(ds) + offsetof(struct shmid_ds, x)
-#define OFF2(x) OFF1(shm_perm) + offsetof(struct ipc_perm, x)
-
-/* List of members for shared memory objects */
-
-/* Note: member types are set in the initshm function.
- Members which need separate processing are:
- - addr --> it is not part of the shmid_ds structure
- - attached --> function depending on addr
- - nattch --> system dependent declaration in shmid_ds (unknown type)
- - perm --> return permission (lower 9) bits only of ds.shm_perm.mode
-*/
-
-static struct memberlist memory_memberlist[] = {
- {"cgid", T_INT, OFF2(cgid), RO}, /* 0 (gid_t) */
- {"cpid", T_INT, OFF1(shm_cpid), RO}, /* 1 (pid_t) */
- {"cuid", T_INT, OFF2(cuid), RO}, /* 2 (uid_t) */
- {"key", T_INT, OFF2(IPC_PERM_KEY_NAME), RO}, /* 3 (key_t) */
- {"lpid", T_INT, OFF1(shm_lpid), RO}, /* 4 (pid_t) */
- {"shmid", T_INT, OFF(shmid), RO}, /* 5 (int) */
- {"size", T_INT, OFF1(shm_segsz), RO}, /* 6 (int) */
- {"gid", T_INT, OFF2(gid), RO}, /* 7 (gid_t) */
- {"uid", T_INT, OFF2(uid), RO}, /* 8 (uid_t) */
- /* The following members are implemented without this table */
- {"addr", T_INT, 0, RO}, /* 9 (void *) */
- {"attached",T_INT, 0, RO}, /* 10 (int) */
- {"nattch", T_INT, 0, RO}, /* 11 sys.dep. */
- {"perm", T_INT, 0, RO}, /* 12 (mode_t) */
- {NULL} /* sentinel */
-};
-
-#undef OFF
-#undef OFF1
-#undef OFF2
-
-static void
-PyShmMemory_dealloc(PyShmObj *self)
-{
- /* del shm_dict[key], ignore if it fails */
- if (PyDict_DelItem(shm_dict, PyInt_FromLong(self->shmid)) == -1)
- PyErr_Clear();
- /* all references in the current process to the shared
- memory segment are lost, so if attached, detach it.
- XXX: This is not true when Python is embedded.
-
- if (self->addr != NULL) {
- shmdt(self->addr);
- }
- */
- /* v1.1 - changed the reference below from PyMem_DEL to PyObject_Del. */
- PyObject_Del(self);
-}
-
-static PyObject *
-PyShmMemory_getattr(PyShmObj *self, char *name)
-{
- PyObject *res;
-
- res = Py_FindMethod(memory_methods, (PyObject *)self, name);
- if (res != NULL)
- return res;
- PyErr_Clear();
- refresh_memory_status(self);
- if (strcmp(name, "attached") == 0)
- return PyInt_FromLong((self->addr == NULL) ? 0 : 1);
- if (strcmp(name, "addr") == 0) {
- if (self->addr != NULL)
- return PyInt_FromLong((unsigned long)self->addr);
- else {
- Py_INCREF(Py_None);
- return Py_None;
- }
- }
- if (strcmp(name, "nattch") == 0)
- return PyInt_FromLong(self->ds.shm_nattch);
- if (strcmp(name, "perm") == 0)
- return PyInt_FromLong(self->ds.shm_perm.mode & 0777);
- return PyMember_Get((char *)self, memory_memberlist, name);
-}
-
-static PyObject *
-PyShmMemory_repr(PyShmObj *self, char *name)
-{
- char buf[100];
- char buf2[20];
-
- refresh_memory_status(self);
- if (self->addr == NULL)
- sprintf(buf2, "None");
- else
- /* v 1.1 - changed format from %lx to %p. */
- /* v 1.1.2 - changed %u to %zu. */
- sprintf(buf2, "0x%p", self->addr);
- sprintf(buf, "<%s shared memory object, id=%d, size=%zu, addr=%s>",
- (self->addr == NULL) ? "detached" : (self->mode & SHM_RDONLY) ?
- "attached RO" : "attached R/W",
- self->shmid,
- self->ds.shm_segsz,
- buf2);
- return PyString_FromString(buf);
-}
-
-/* Type object for shared memory objects */
-
-static PyTypeObject PyShmMemory_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /*ob_size*/
- "shared memory", /*tp_name*/
- sizeof(PyShmObj), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)PyShmMemory_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)PyShmMemory_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- (reprfunc)PyShmMemory_