* BShelf::_AddReplicant() did not recognize zombies if their object was not

inherited from BView.
* BShelf::_AddReplicant() did not honour the fAllowZombies flag correctly; if
  it wasn't allowed, no error message was given.
* Both of these changes fixes the crashing of the Deskbar as described in
  bug #555.
* instantiate_object() now also fires a message to the syslog if the object's
  image could not been loaded. Some cleanup, no longer resets errno.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22117 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-08-30 01:03:33 +00:00
parent 9774b66a7d
commit 7bc5a06be6
2 changed files with 51 additions and 64 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2006, Haiku. * Copyright 2001-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@ -1088,7 +1088,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// Check shelf types if needed // Check shelf types if needed
if (fTypeEnforced) { if (fTypeEnforced) {
const char *shelfType = NULL; const char *shelfType = NULL;
if (data->FindString("shelf_type", &shelfType) == B_OK && shelfType != NULL) { if (data->FindString("shelf_type", &shelfType) == B_OK
&& shelfType != NULL) {
if (Name() && strcmp(shelfType, Name()) != 0) { if (Name() && strcmp(shelfType, Name()) != 0) {
printf("Replicant was rejected by BShelf: The BShelf's type and the Replicant's type don't match."); printf("Replicant was rejected by BShelf: The BShelf's type and the Replicant's type don't match.");
return send_reply(data, B_ERROR, uniqueID); return send_reply(data, B_ERROR, uniqueID);
@ -1142,10 +1143,14 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// Instantiate the object, if this fails we have a zombie // Instantiate the object, if this fails we have a zombie
image_id image; image_id image;
BArchivable *archivable = _InstantiateObject(data, &image); BArchivable *archivable = _InstantiateObject(data, &image);
if (archivable) { BView *view = dynamic_cast<BView*>(archivable);
BView *view = dynamic_cast<BView*>(archivable); if (archivable != NULL && view == NULL) {
BPoint point; printf("Replicant was rejected: it's not a view!");
return send_reply(data, B_ERROR, uniqueID);
}
if (view != NULL) {
BPoint point;
if (location) if (location)
point = *location; point = *location;
else else
@ -1215,7 +1220,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
view->MoveTo(point + adjust); view->MoveTo(point + adjust);
// if it's a sibling or a child, we need to add the dragger // if it's a sibling or a child, we need to add the dragger
if (relation == BDragger::TARGET_IS_SIBLING || relation == BDragger::TARGET_IS_CHILD) if (relation == BDragger::TARGET_IS_SIBLING
|| relation == BDragger::TARGET_IS_CHILD)
fContainerView->AddChild(dragger); fContainerView->AddChild(dragger);
replicant->AddFilter(new ReplicantViewFilter(this, replicant)); replicant->AddFilter(new ReplicantViewFilter(this, replicant));
@ -1246,13 +1252,17 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
fContainerView->AddChild(zombie); fContainerView->AddChild(zombie);
} }
} else if (!fAllowZombies) {
// There was no view, and we're not allowed to have any zombies
// in the house
return send_reply(data, B_ERROR, uniqueID);
} }
data->RemoveName("_drop_point_"); data->RemoveName("_drop_point_");
data->RemoveName("_drop_offset_"); data->RemoveName("_drop_offset_");
replicant_data *item = new replicant_data(data, replicant, dragger, relation, replicant_data *item = new replicant_data(data, replicant, dragger,
uniqueID, image); relation, uniqueID, image);
item->error = B_OK; item->error = B_OK;
item->zombie_view = zombie; item->zombie_view = zombie;

View File

@ -1,13 +1,14 @@
/* /*
* Copyright (c) 2001-2006, Haiku, Inc. * Copyright (c) 2001-2007, Haiku, Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Erik Jaesler (erik@cgsoftware.com) * Erik Jaesler (erik@cgsoftware.com)
*/ */
/** Description: BArchivable mix-in class defines the archiving /*! BArchivable mix-in class defines the archiving protocol.
protocol. Also some global archiving functions.*/ Also some global archiving functions.
*/
#include <ctype.h> #include <ctype.h>
@ -15,6 +16,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include <syslog.h>
#include <typeinfo> #include <typeinfo>
#include <vector> #include <vector>
@ -26,8 +28,6 @@
#include <Path.h> #include <Path.h>
#include <Roster.h> #include <Roster.h>
#include <String.h> #include <String.h>
#include <SupportDefs.h>
#include <syslog.h>
using std::string; using std::string;
@ -37,35 +37,15 @@ const char* B_CLASS_FIELD = "class";
const char* B_ADD_ON_FIELD = "add_on"; const char* B_ADD_ON_FIELD = "add_on";
const int32 FUNC_NAME_LEN = 1024; const int32 FUNC_NAME_LEN = 1024;
// TODO: consider moving these // TODO: consider moving these to a separate module, and making them more
// to a separate module, and making them more full-featured (e.g., taking // full-featured (e.g., taking NS::ClassName::Function(Param p) instead
// NS::ClassName::Function(Param p) instead of just NS::ClassName) // of just NS::ClassName)
static void Demangle(const char *name, BString &out); static void Demangle(const char *name, BString &out);
static void Mangle(const char *name, BString &out); static void Mangle(const char *name, BString &out);
static instantiation_func FindFuncInImage(BString& funcName, image_id id, static instantiation_func FindFuncInImage(BString& funcName, image_id id,
status_t& err); status_t& err);
static bool CheckSig(const char* sig, image_info& info); static bool CheckSig(const char* sig, image_info& info);
/*
// TODO: Where do these get triggered from?
Log entries graciously coughed up by the Be implementation:
Nov 28 01:40:45 instantiate_object failed: NULL BMessage argument
Nov 28 01:40:45 instantiate_object failed: Failed to find an entrydefining the class name (Name not found).
Nov 28 01:40:45 instantiate_object failed: No signature specified in archive, looking for class "TInvalidClassName".
Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found)
Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b)
Nov 28 01:40:45 instantiate_object failed: Failed to find exported Instantiate static function for class TInvalidClassName.
Nov 28 01:40:45 instantiate_object failed: Invalid argument (80000005)
Nov 28 01:40:45 instantiate_object failed: No signature specified in archive, looking for class "TRemoteTestObject".
Nov 28 01:40:45 instantiate_object - couldn't get mime sig for /boot/home/src/projects/OpenBeOS/app_kit/test/lib/support/BArchivable/./BArchivableSystemTester
Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found)
Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b)
Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found)
Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b)
Nov 28 01:40:45 instantiate_object failed: Error finding app with signature "application/x-vnd.InvalidSignature" (Application could not be found)
Nov 28 01:40:45 instantiate_object failed: Application could not be found (8000200b)
*/
BArchivable::BArchivable() BArchivable::BArchivable()
{ {
@ -142,12 +122,9 @@ BuildFuncName(const char* className, BString& funcName)
BArchivable* BArchivable*
instantiate_object(BMessage* archive, image_id* id) instantiate_object(BMessage* archive, image_id* id)
{ {
errno = B_OK;
// Check our params // Check our params
if (id) { if (id)
*id = B_BAD_VALUE; *id = B_BAD_VALUE;
}
if (!archive) { if (!archive) {
// TODO: extended error handling // TODO: extended error handling
@ -162,7 +139,7 @@ instantiate_object(BMessage* archive, image_id* id)
if (err) { if (err) {
// TODO: extended error handling // TODO: extended error handling
syslog(LOG_ERR, "instantiate_object failed: Failed to find an entry " syslog(LOG_ERR, "instantiate_object failed: Failed to find an entry "
"defining the class name (%s).", strerror(err)); "defining the class name (%s).", strerror(err));
return NULL; return NULL;
} }
@ -172,68 +149,68 @@ instantiate_object(BMessage* archive, image_id* id)
instantiation_func iFunc = find_instantiation_func(name, sig); instantiation_func iFunc = find_instantiation_func(name, sig);
// if find_instantiation_func() can't locate Class::Instantiate() // if find_instantiation_func() can't locate Class::Instantiate()
// and a signature was specified // and a signature was specified
if (!iFunc && hasSig) { if (!iFunc && hasSig) {
// use BRoster::FindApp() to locate an app or add-on with the symbol // use BRoster::FindApp() to locate an app or add-on with the symbol
BRoster Roster; BRoster Roster;
entry_ref ref; entry_ref ref;
err = Roster.FindApp(sig, &ref); err = Roster.FindApp(sig, &ref);
// if an entry_ref is obtained
BEntry entry; BEntry entry;
// if an entry_ref is obtained
if (!err) if (!err)
err = entry.SetTo(&ref); err = entry.SetTo(&ref);
if (err) { if (err) {
syslog(LOG_ERR, "instantiate_object failed: Error finding app " syslog(LOG_ERR, "instantiate_object failed: Error finding app "
"with signature \"%s\" (%s)", sig, strerror(err)); "with signature \"%s\" (%s)", sig, strerror(err));
} }
if (!err) { if (!err) {
BPath path; BPath path;
err = entry.GetPath(&path); err = entry.GetPath(&path);
if (!err) { if (!err) {
// load the app/add-on // load the app/add-on
image_id theImage = load_add_on(path.Path()); image_id addOn = load_add_on(path.Path());
if (theImage < 0) { if (addOn < 0) {
// TODO: extended error handling // TODO: extended error handling
syslog(LOG_ERR, "instantiate_object failed: Could not load "
"add-on %s: %s.", path.Path(), strerror(addOn));
return NULL; return NULL;
} }
// Save the image_id // Save the image_id
if (id) { if (id)
*id = theImage; *id = addOn;
}
BString funcName; BString funcName;
BuildFuncName(name, funcName); BuildFuncName(name, funcName);
iFunc = FindFuncInImage(funcName, theImage, err);
if (!iFunc) iFunc = FindFuncInImage(funcName, addOn, err);
{ if (!iFunc) {
syslog(LOG_ERR, "instantiate_object failed: Failed to find exported " syslog(LOG_ERR, "instantiate_object failed: Failed to find exported "
"Instantiate static function for class %s.", name); "Instantiate static function for class %s.", name);
} }
} }
} }
} else if (!iFunc) { } else if (!iFunc) {
syslog(LOG_ERR, "instantiate_object failed: No signature specified " syslog(LOG_ERR, "instantiate_object failed: No signature specified "
"in archive, looking for class \"%s\".", name); "in archive, looking for class \"%s\".", name);
errno = B_BAD_VALUE; errno = B_BAD_VALUE;
} }
if (err) { if (err) {
// TODO: extended error handling // TODO: extended error handling
syslog(LOG_ERR, "instantiate_object failed: %s (%x)", syslog(LOG_ERR, "instantiate_object failed: %s (%x)",
strerror(err), err); strerror(err), err);
errno = err; errno = err;
return NULL; return NULL;
} }
// if Class::Instantiate(BMessage*) was found // if Class::Instantiate(BMessage*) was found
if (iFunc) { if (iFunc) {
// use to create and return an object instance // use to create and return an object instance
return iFunc(archive); return iFunc(archive);
} }