gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash NEWS server/shm.cpp server/shm.h server/a...


From: Rob Savoye
Subject: [Gnash-commit] gnash NEWS server/shm.cpp server/shm.h server/a...
Date: Sun, 22 Oct 2006 01:00:55 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    06/10/22 01:00:55

Modified files:
        .              : NEWS 
        server         : shm.cpp shm.h 
        server/asobj   : LocalConnection.cpp LocalConnection.h 
        testsuite/actionscript.all: LocalConnection.as 
        utilities      : Makefile.am 
Added files:
        utilities      : dumpshm.cpp 

Log message:
                * gnash/NEWS: Update with new fetures.
                * server/shm.cpp: Don't core dump anymore by not trying to open
                the same memory segment twice.
                * utilities/dumpshm.cpp: Shared memory utility. Lists, deletes,
                and dumps internal data from Gnash shared memory segments.
                * server/shm.h: Add more accessors for private data.
                * server/asobj/LocalConnection.cpp: Dump all the networking 
crap,
                that's for NetConnection.
                * server/asobj/LocalConnection.h: Derive class from Shm base 
class 
                instead of Network base class.
                * testsuite/actionscript.all/LocalConnection.as: Use dejagnu.as.
                * utilities/Makefile.am: Add dumpshm program.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/NEWS?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/shm.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/server/shm.h?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/LocalConnection.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/LocalConnection.h?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/LocalConnection.as?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/Makefile.am?cvsroot=gnash&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/dumpshm.cpp?cvsroot=gnash&rev=1.1

Patches:
Index: NEWS
===================================================================
RCS file: /sources/gnash/gnash/NEWS,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- NEWS        20 Dec 2005 21:03:23 -0000      1.1
+++ NEWS        22 Oct 2006 01:00:54 -0000      1.2
@@ -1,3 +1,24 @@
+2006-09-10  Rob Savoye  <address@hidden>
+
+The second alpha release of Gnash is coming soon. Improvements since
+the 0.7.1 alpha release are:
+
+* Polling main loop replaced with event driven framework.
+* New GUI abstraction layer supporting GTK2, KDE, SDL, and just a
+framebuffer. 
+* Movies are parsed by a background thread, so they start playing
+while still loading.
+* Plugin supports web navigation and starts playing while the stream
+is loading.
+* New AntiGrain (AGG) 2D backend added for framebuffer devices.
+* Sound now works.
+* A whole slew of minor bugs that kept various movies from playing.
+
+2006-04-20  Rob Savoye  <address@hidden>
+
+The first alpha release of Gnash! Version 0.7.1 is released with a
+working browser plugin.
+
 2005-12-10  Rob Savoye  <address@hidden>
 
 GameSWF has been turned into Gnash! Gnash's goals are to turn this

Index: server/shm.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/shm.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/shm.cpp      2 Oct 2006 16:28:11 -0000       1.21
+++ server/shm.cpp      22 Oct 2006 01:00:54 -0000      1.22
@@ -67,7 +67,6 @@
 namespace gnash {
 
 const int DEFAULT_SHM_SIZE = 10240;
-//const int MAX_FILESPEC_SIZE = 20;
 
 #ifdef darwin
 # ifndef MAP_INHERIT
@@ -86,6 +85,7 @@
 
   Shm::Shm() :_addr(0), _alloced(0), _size(0), _shmkey(0), _shmfd(0)
 {
+    memset(_filespec, 0, MAX_SHM_NAME_SIZE);
 }
 
 Shm::~Shm()
@@ -114,9 +114,12 @@
     absfilespec = "/";
 #endif
     absfilespec += filespec;
-    _filespec = absfilespec;
     filespec = absfilespec.c_str();
-    
+    strncpy(_filespec, absfilespec.c_str(), MAX_SHM_NAME_SIZE);
+    if (static_cast<int>(absfilespec.size()) > MAX_SHM_NAME_SIZE) {
+       log_error("Shared Memory segment name is %d bytes too long!\n",
+                 absfilespec.size() - MAX_SHM_NAME_SIZE);
+    }    
     
     //     log_msg("%s: Initializing %d bytes of memory for \"%s\"\n",
     //             __PRETTY_FUNCTION__, DEFAULT_SHM_SIZE, absfilespec.c_str());
@@ -128,6 +131,7 @@
     long pageSize = sysconf(_SC_PAGESIZE);
     if (_size % pageSize) {
        _size += pageSize - _size % pageSize;
+//     log_msg("Adjusting segment size to %d to be page aligned.\n", _size);
     }
 #endif
     
@@ -136,6 +140,7 @@
     // Create the shared memory segment
     _shmfd = shm_open(filespec, O_RDWR|O_CREAT|O_EXCL|O_TRUNC,
                      S_IRUSR|S_IWUSR);
+    if (_shmfd < 0 && errno == EEXIST)
 #else
 # ifdef HAVE_SHMGET
     const int shmflg = 0660 | IPC_CREAT | IPC_EXCL;
@@ -148,14 +153,15 @@
                                        PAGE_READWRITE, 0,
                                        _size, filespec);
     if (_shmhandle <= 0)
-# endif
-#endif
+# endif        // end of HAVE_SHMGET
+#endif // end of HAVE_SHM_OPEN
        {
     // If it already exists, then just attach to it.
        exists = true;
        log_msg("Shared Memory segment \"%s\" already exists\n",
                filespec);
 #ifdef HAVE_SHM_OPEN
+//     shm_unlink(filespec);
        _shmfd = shm_open(filespec, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
 #else
 # ifdef HAVE_SHMGET
@@ -225,6 +231,7 @@
                                       0, 0, _size);
 # endif
 #endif
+//     log_msg("The address to the shared memory segment is: %p", _addr);
         if (exists && !nuke) {
            // If there is an existing memory segment that we don't
            // want to trash, we just want to attach to it. We know
@@ -248,31 +255,34 @@
 #ifdef HAVE_SHM_OPEN
            munmap(_addr, _size);
            log_msg("Unmapped address %p\n", _addr);
+#ifdef darwin
            _addr = static_cast<char *>(mmap(reinterpret_cast<char *>(addr),
                                             _size, PROT_READ|PROT_WRITE,
                                             
MAP_SHARED|MAP_FIXED|MAP_INHERIT|MAP_HASSEMAPHORE,
                                             _shmfd, static_cast<off_t>(0)));
+#else
            //                 off = (off_t)((long)addr - (long)_addr);
            _addr = static_cast<char *>(mmap((char *)addr,
                                             _size, 
PROT_READ|PROT_WRITE|PROT_EXEC,
                                             MAP_FIXED|MAP_SHARED, _shmfd, 0));
-           
+#endif
            if (_addr == MAP_FAILED) {
                log_msg("WARNING: MMAP failed: %s\n", strerror(errno));
                return static_cast<Shm *>(0);
            }
         }
-#else
-#ifdef HAVE_SHMAT          
+#else  // HAVE_SHM_OPEN
+# ifdef HAVE_SHMAT         
        shmdt(_addr);
        _addr = (char *)shmat(_shmfd, (void *)addr, 0);
-#else
+# else
        CloseHandle(_shmhandle);        
        _addr = (char *)MapViewOfFile (_shmhandle, FILE_MAP_ALL_ACCESS,
                               0, 0, _size);
-#endif // end of HAVE_SHMAT
+# endif // end of HAVE_SHMAT
        }
 #endif // end of HAVE_SHM_OPEN
+#else // else of FLAT_ADDR_SPACE
 #endif // end of FLAT_ADDR_SPACE
     
        log_msg("Opened Shared Memory segment \"%s\": " SIZET_FMT " bytes at 
%p.\n",
@@ -399,8 +409,8 @@
 {
     // Only nuke the shared memory segement if we're the last one.
 #ifdef HAVE_SHM_OPEN
-    if (_filespec.size() != 0) {
-        shm_unlink(_filespec.c_str());
+    if (strlen(_filespec) != 0) {
+        shm_unlink(_filespec);
     }
     
      // flush the shared memory to disk
@@ -418,11 +428,12 @@
     
     _addr = 0;
     _alloced = 0;
+    memset(_filespec, 0, MAX_SHM_NAME_SIZE);
 
     return true;    
 }
 
-#ifdef ENABLE_TESTING
+//#ifdef ENABLE_TESTING
 bool
 Shm::exists()
 {
@@ -455,11 +466,14 @@
         }
     }
     
+    if (strlen(_filespec)) {
     realname += _filespec;
     
     if (stat(realname.c_str(), &stats) == 0) {
         return true;
     }
+    }
+    
     return false;
 }
 
@@ -470,7 +484,7 @@
 {
     shm_as_object *ptr = (shm_as_object*)fn.this_ptr;
     assert(ptr);
-    fn.result->set_tu_string(ptr->obj.getName().c_str());
+    fn.result->set_tu_string(ptr->obj.getName());
 }
 void shm_getsize(const fn_call& fn)
 {
@@ -490,7 +504,7 @@
     assert(ptr);
     fn.result->set_bool(ptr->obj.exists());
 }
-#endif
+//#endif
 
 } // end of gnash namespace
 

Index: server/shm.h
===================================================================
RCS file: /sources/gnash/gnash/server/shm.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- server/shm.h        29 Aug 2006 10:52:09 -0000      1.8
+++ server/shm.h        22 Oct 2006 01:00:54 -0000      1.9
@@ -66,6 +66,8 @@
 const int MAP_HASSEMAPHORE = 0;
 #endif
 
+const int MAX_SHM_NAME_SIZE = 48;
+
 class Shm {
 public:
     Shm();
@@ -86,19 +88,17 @@
     
     Shm *cloneSelf(void);
 
-#ifdef ENABLE_TESTING 
     // Accessors for testing
-    std::string getName()       { return _filespec; };
+    char *getAddr()             { return _addr; };
+    char *getName()             { return _filespec; };
     size_t getSize()            { return _size; };
     int getAllocated()          { return _alloced; };
     bool exists();
-#endif
-
 protected:
     char        *_addr;
     long        _alloced;
     size_t      _size;
-    std::string _filespec;
+    char        _filespec[MAX_SHM_NAME_SIZE];
 #ifndef HAVE_WINSOCK_H
     key_t      _shmkey;
 #else
@@ -186,12 +186,12 @@
     Shm obj;
 };
 
-#ifdef ENABLE_TESTING 
+//#ifdef ENABLE_TESTING 
 void shm_getname(const fn_call& fn);
 void shm_getsize(const fn_call& fn);
 void shm_getallocated(const fn_call& fn);
 void shm_exists(const fn_call& fn);
-#endif
+//#endif
 
 } // end of gnash namespace
 

Index: server/asobj/LocalConnection.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/LocalConnection.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/asobj/LocalConnection.cpp    25 Aug 2006 16:49:35 -0000      1.2
+++ server/asobj/LocalConnection.cpp    22 Oct 2006 01:00:54 -0000      1.3
@@ -63,11 +63,7 @@
 void
 LocalConnection::close()
 {
-#ifdef NETWORK_CONN
-    closeNet();
-#else
     closeMem();
-#endif
 }
 
 /// \brief Prepares the LocalConnection object to receive commands from a
@@ -79,53 +75,9 @@
 bool
 LocalConnection::connect(const char *name)
 {
-#ifdef NETWORK_CONN
-    short lastport;
-    const char *lcname;
-
-    std::map<const char *, short>::const_iterator it;
-    for (it = _allocated.begin(); it != _allocated.end(); it++) {
-        lcname = it->first;
-        lastport  = it->second;
-        if (strcmp(name, lcname) == 0) {
-            log_msg("ERROR: %s already allocated!\n", name);
-            return false;
-        }
-    }
-
-    // Allocate the tcp/ip port adfter the last allocated one.
-    if (lastport != 0) {
-        _allocated[name] = lastport+1;
-    }
-
-    // Create the socket
-    if (createServer(lastport+1)) {
-        log_msg("New server started for \"%s\" connections.\n", name);
-    } else {
-        log_msg("ERROR: Couldn't create a new server for \"%s\"!\n");
-        return false;
-    }
-
-    if (newConnection(false)) {
-        log_msg("New connection started for \"%s\" connections.\n", name);
-//        writeNet(heloCreate(_version));
-        return true;
-    } else {
-        if (errno == EAGAIN) {
-            log_msg("No clients tried to connect within the allocated time 
limit\n");
-            return false;
-        }
-        else {
-            log_msg("ERROR: Couldn't create a new connection!\n");
-        }
-            
-        return false;
-    }
-#else
     if (attach(name, true) == false) {
         return false;
     }
-#endif
     _name = name;
 
     return true;
@@ -169,18 +121,12 @@
     localconnection_obj->set_member("connect", &localconnection_connect);
     localconnection_obj->set_member("domain", &localconnection_domain);
     localconnection_obj->set_member("send", &localconnection_send);
-#ifdef ENABLE_TESTING
-#ifdef NETWORK_CONN
-    localconnection_obj->set_member("connected",  &network_connected);
-    localconnection_obj->set_member("getfilefd",  &network_getfilefd);
-    localconnection_obj->set_member("getlistenfd",  &network_getlistenfd);
-#else
+//#ifdef ENABLE_TESTING
     localconnection_obj->set_member("getname",  &shm_getname);
     localconnection_obj->set_member("getsize",  &shm_getsize);
     localconnection_obj->set_member("getallocated",  &shm_getallocated);
     localconnection_obj->set_member("exists",  &shm_exists);
-#endif
-#endif
+//#endif
 
     fn.result->set_as_object(localconnection_obj);
 }
@@ -229,5 +175,5 @@
     log_msg("%s:unimplemented \n", __FUNCTION__);
 }
 
-} // end of gnaash namespace
+} // end of gnash namespace
 

Index: server/asobj/LocalConnection.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/LocalConnection.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/asobj/LocalConnection.h      26 Aug 2006 13:09:53 -0000      1.3
+++ server/asobj/LocalConnection.h      22 Oct 2006 01:00:54 -0000      1.4
@@ -55,11 +55,7 @@
 
 namespace gnash {
   
-#ifdef NETWORK_CONN
-class LocalConnection : public Network {
-#else
 class LocalConnection : public Shm {
-#endif
 public:
     LocalConnection();
     ~LocalConnection();

Index: testsuite/actionscript.all/LocalConnection.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/LocalConnection.as,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- testsuite/actionscript.all/LocalConnection.as       24 Apr 2006 23:05:56 
-0000      1.4
+++ testsuite/actionscript.all/LocalConnection.as       22 Oct 2006 01:00:54 
-0000      1.5
@@ -40,47 +40,49 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
+#include "dejagnu.as"
+
 var tmp = new LocalConnection;
 
 // test the LocalConnection constuctor
 if (tmp) {
-       trace("PASSED: LocalConnection::LocalConnection() constructor");
+       pass("LocalConnection::LocalConnection() constructor");
 } else {
-       trace("FAILED: LocalConnection::LocalConnection()");            
+       fail("LocalConnection::LocalConnection()");             
 }
 
 // test the LocalConnection::close method
 if (tmp.close) {
-       trace("PASSED: LocalConnection::close() exists");
+       pass("LocalConnection::close() exists");
 } else {
-       trace("FAILED: LocalConnection::close() doesn't exist");
+       fail("LocalConnection::close() doesn't exist");
 }
 // test the LocalConnection::connect method
 if (tmp.connect) {
-       trace("PASSED: LocalConnection::connect() exists");
+       pass("LocalConnection::connect() exists");
 } else {
-       trace("FAILED: LocalConnection::connect() doesn't exist");
+       fail("LocalConnection::connect() doesn't exist");
 }
 // test the LocalConnection::domain method
 if (tmp.domain) {
-       trace("PASSED: LocalConnection::domain() exists");
+       pass("LocalConnection::domain() exists");
 } else {
-       trace("FAILED: LocalConnection::domain() doesn't exist");
+       fail("LocalConnection::domain() doesn't exist");
 }
 // test the LocalConnection::send method
 if (tmp.send) {
-       trace("PASSED: LocalConnection::send() exists");
+       pass("LocalConnection::send() exists");
 } else {
-       trace("FAILED: LocalConnection::send() doesn't exist");
+       fail("LocalConnection::send() doesn't exist");
 }
 
 // Get the domain. By default this should be "localhost" because we
 // haven't made any connections yet,
 var domain = tmp.domain();
 if (domain  == "localhost") {
-       trace("PASSED: LocalConnection::domain() returned localhost");
+       pass("LocalConnection::domain() returned localhost");
 } else {
-       trace("FAILED: LocalConnection::domain() returned localhost");
+       fail("LocalConnection::domain() returned localhost");
 }
 
 
@@ -89,7 +91,10 @@
 // initial file descriptor returned by bind is still fine, since we
 // could always (in a normal application) check later for incoming
 // connections.
+
+tmp.close();
 var ret = tmp.connect("lc_test");
+
 // NOTE: This test will fail if a shared memory segment of the same
 // name exists. So the first time it'll pass, then it'll fail.
 if ((tmp.getname() == "/lc_test") && (ret == true)) {
@@ -97,11 +102,6 @@
 } else {       
        trace("FAILED: LocalConnection::connect()");
 }
-//if ((tmp.getfilefd() == -1) && (tmp.getlistenfd() > 2)) {
-//     trace("PASSED: LocalConnection::connect()");
-//} else {
-//     trace("FAILED: LocalConnection::connect()");
-//}
 
 // Close the connection, and then check the state
 tmp.close();
@@ -110,3 +110,5 @@
 } else {
        trace("FAILED: LocalConnection::close()");
 }
+
+totals();

Index: utilities/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/utilities/Makefile.am,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- utilities/Makefile.am       18 Oct 2006 13:06:15 -0000      1.33
+++ utilities/Makefile.am       22 Oct 2006 01:00:54 -0000      1.34
@@ -53,17 +53,20 @@
 endif
 
 bin_PROGRAMS = gparser gprocessor
+noinst_PROGRAMS = dumpshm
 
-gparser_SOURCES = \
-       parser.cpp
+gparser_SOURCES = parser.cpp
 gparser_LDADD = $(GNASH_LIBS)
 #gparser_LDFLAGS = $(AM_LDFLAGS)
 
-gprocessor_SOURCES = \
-       processor.cpp
+gprocessor_SOURCES = processor.cpp
 gprocessor_LDADD = $(GNASH_LIBS)
 #gprocessor_LDFLAGS = $(AM_LDFLAGS)
 
+dumpshm_SOURCES = dumpshm.cpp
+dumpshm_LDADD = $(GNASH_LIBS)
+#gparser_LDFLAGS = $(AM_LDFLAGS)
+
 MUDFLAP_OPT = -fmudflap
 MUDFLAP_LIB =  /usr/local/lib/libmudflap.so
 

Index: utilities/dumpshm.cpp
===================================================================
RCS file: utilities/dumpshm.cpp
diff -N utilities/dumpshm.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ utilities/dumpshm.cpp       22 Oct 2006 01:00:54 -0000      1.1
@@ -0,0 +1,304 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+#include <map>
+#ifdef __STDC_HOSTED__
+#include <sstream>
+#else
+#include <strstream>
+#endif
+#include <cstdio>
+
+#include "log.h"
+#include "rc.h"
+#include "shm.h"
+
+using namespace std;
+using namespace gnash;
+
+static void usage (void);
+void dump_ctrl(void *ptr);
+
+const int PIDSTART = 20000;
+const int PIDEND   = 23000;
+const int LINELEN  = 80;
+const unsigned int LOOPCNT  = 5;
+const int DEFAULT_SHM_SIZE = 1024;
+
+int
+main(int argc, char *argv[])
+{
+    unsigned int          i;
+    int                   c;
+    bool                  dump  = false;
+    bool                  nuke  = false;
+    bool                  listfiles  = false;
+    bool                  force = false;
+    int                   size  = 0;
+    string                filespec, realname, tmpname;
+    struct dirent         *entry;
+    vector<const char *>  dirlist;
+    
+// #ifdef __STDC_HOSTED__
+//     ostringstream         *shmnames;
+// #else
+//     strstream             *shmnames;
+// #endif
+
+    /* This initializes the DBG_MSG macros */ 
+    while ((c = getopt (argc, argv, "hdnl:if")) != -1) {
+        switch (c) {
+          case 'h':
+            usage ();
+            break;
+            
+          case 'f':
+            force = true;
+            break;
+            
+          case 'i':
+            listfiles = true;
+            break;
+            
+          case 'd':
+            dump = true;
+            break;
+            
+          case 'n':
+            nuke = true;
+            break;
+
+          case 'l':
+            size = atoi(optarg);
+            break;
+            
+          default:
+            usage ();
+            break;
+        }
+    }
+    
+    
+    // If no command line arguments have been supplied, do nothing but
+    // print the  usage message.
+    if (argc < 2) {
+        usage();
+        exit(0);
+    }
+    
+    
+    if (size == 0) {
+        size = DEFAULT_SHM_SIZE;
+    }
+    
+    // get the file name from the command line
+    if (optind < argc) {
+        filespec = argv[optind];
+        cout << "Will use \"" << filespec << "\" for memory segment file"
+             << endl;
+    }
+    
+    DIR *library_dir = NULL;
+
+    // Solaris stores shared memory segments in /var/tmp/.SHMD and
+    // /tmp/.SHMD. Linux stores them in /dev/shm.
+    dirlist.push_back("/dev/shm");
+    dirlist.push_back("/var/tmp/.SHMD");
+    dirlist.push_back("/tmp/.SHMD");
+
+    // Open the directory where the raw POSIX shared memory files are
+    for (i=0; i<dirlist.size(); i++) {
+        library_dir = opendir (dirlist[i]);
+        if (library_dir != NULL) {
+            realname = dirlist[i];
+            
+            // By convention, the first two entries in each directory are
+            // for . and .. (``dot'' and ``dot dot''), so we ignore those. The
+            // next directory read will get a real file, if any exists.
+            entry = readdir(library_dir);
+            entry = readdir(library_dir);
+            break;
+        }
+    }
+
+    // MacOSX, unlike Solaris and Linux doesn't appear to use a file
+    // based scheme for shared memory segments. In this case, we can't
+    // analyze the files directly, and are forced to explicitly create
+    // all the probable names to be deleted.
+    if (library_dir == NULL || force && nuke) {
+        // These are the names left by the various test cases. Just
+        // blindly delete them, because they may not even exist, so
+        // the errors can be ignored.
+        shm_unlink("/lc_test");
+        exit(0);
+    }
+
+    // Just list the shared memory segments
+    if (listfiles) {
+        if (library_dir != NULL)
+        {
+            for (i=0; entry>0; i++) {
+                entry = readdir(library_dir);
+                if (entry != NULL) {
+                    cout << "Found segment: " << entry->d_name << endl;
+                }
+            }
+        } else {
+            cout << "Sorry, we can only list the files on systems with";
+            cout << "with disk based shared memory" << endl;
+        }
+        exit(0);
+    }
+
+    //Destroy shared memory segments
+    if (nuke) {
+        if (filespec.size() == 0) {
+            cout << "No name specified, nuking everything..." << endl;
+            for (i=0; entry>0; i++) {
+                entry = readdir(library_dir);
+                if (entry != NULL) {
+                    tmpname = "/"; // prefix a / so shm_unlink can
+                                   // use the correct path
+                    tmpname += entry->d_name;
+                    cout << "Removing segment: " << tmpname << endl;
+                    shm_unlink(tmpname.c_str());
+                }
+            }
+            exit(0);
+        } else {
+            cout << "Nuking the shared memory segment " << filespec << endl;
+            shm_unlink(filespec.c_str());
+        }
+        
+        exit(0);
+    }
+    
+    // Because POSIX shared memory is is file system based, we can
+    // open the raw file, which lets us analyze it better without the
+    // potential hassle of memory faults.
+    ifstream in;
+//    int offset;
+    Shm shmptr;
+
+    realname += filespec;
+
+#ifdef __STDC_HOSTED__
+    in.open(realname.c_str(), ios::binary|ios::in);
+#else
+    in.open(realname.c_str(), ios::binary|ios::in|ios::nocreate);
+#endif
+    
+    if (!in.eof()) {
+         if (!in.read(reinterpret_cast<char*>(&shmptr), sizeof(Shm))) {
+             cerr << "ERROR: couldn't read!" << endl;
+             exit(1);
+         }
+         dump_ctrl(&shmptr);
+         
+//        in.read(reinterpret_cast<char*>(mmptr), sizeof(MemManager));
+        // This is pretty gross. Because we aren't mapping this segment
+        // into memory, we splice in the data we first read to the
+        // proper field in the Memory Manager structure, since it
+        // references this same data anyway.
+//        long *tmpptr = reinterpret_cast<long *>(mmptr);
+//        tmpptr[2] = reinterpret_cast<long>(shmptr);
+//        mmptr->memControlSet(shmptr);
+
+//        memblks  = new MemBlock [mmptr->blockCountGet()];
+        // The Memory Block data is a big array of contiguous memory,
+        // so we figure out it's offset from the front of the file and
+        // then read from there.
+//        offset = reinterpret_cast<char*>(mmptr->memBlocksGet()) -
+//            reinterpret_cast<char*>(shmptr->memAddrGet());
+//        in.seekg(offset, ios::beg);
+//        in.read(reinterpret_cast<char*>(memblks), mmptr->blockCountGet());
+//        tmpptr[1] = reinterpret_cast<long>(memblks);        
+//        mmptr->memBlocksSet(memblks);
+    }
+}
+
+/// \brief  Display the command line arguments
+static void
+usage (void)
+{
+    cerr << "This program dumps the internal data of a shared memory segment"
+         << endl;
+    cerr << "Usage: dumpmem [hdsanlif] filename" << endl;
+    cerr << "-h\tHelp" << endl;
+    cerr << "-d\tDump data" << endl;
+    cerr << "-n [optional name]\tNuke everything" << endl;
+    cerr << "-l\tLength of segment" << endl;
+    cerr << "-i\tList segments" << endl;
+    cerr << "-f\tForce to use builtin names for nuke" << endl;
+    exit (-1);
+}
+
+/// \brief Dumps the internal data of the found ShmControl
+///              block. We do our own dumping, rather than letting
+///              ShmControl::dump() do it, cause that's for debugging,
+///              and this is for user display purposes.
+void dump_ctrl(void *inmem)
+{
+    Shm *ptr = static_cast<Shm *>(inmem);
+    
+    cerr << "\tBase address of this segment: "
+         << static_cast<void *>(ptr->getAddr()) << endl;
+    cerr << "\tFilespec: " << ptr->getName() << endl;
+    cerr << "\t# Bytes allocated: " << ptr->getAllocated() << endl;
+    cerr << "\tTotal # of bytes: " << ptr->getSize() << endl;
+}
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]