* 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.
*
* Authors:
@ -1088,7 +1088,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// Check shelf types if needed
if (fTypeEnforced) {
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) {
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);
@ -1142,10 +1143,14 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// Instantiate the object, if this fails we have a zombie
image_id image;
BArchivable *archivable = _InstantiateObject(data, &image);
if (archivable) {
BView *view = dynamic_cast<BView*>(archivable);
BPoint point;
BView *view = dynamic_cast<BView*>(archivable);
if (archivable != NULL && view == NULL) {
printf("Replicant was rejected: it's not a view!");
return send_reply(data, B_ERROR, uniqueID);
}
if (view != NULL) {
BPoint point;
if (location)
point = *location;
else
@ -1215,7 +1220,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
view->MoveTo(point + adjust);
// 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);
replicant->AddFilter(new ReplicantViewFilter(this, replicant));
@ -1246,13 +1252,17 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
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_offset_");
replicant_data *item = new replicant_data(data, replicant, dragger, relation,
uniqueID, image);
replicant_data *item = new replicant_data(data, replicant, dragger,
relation, uniqueID, image);
item->error = B_OK;
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.
*
* Authors:
* Erik Jaesler (erik@cgsoftware.com)
*/
/** Description: BArchivable mix-in class defines the archiving
protocol. Also some global archiving functions.*/
/*! BArchivable mix-in class defines the archiving protocol.
Also some global archiving functions.
*/
#include <ctype.h>
@ -15,6 +16,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <syslog.h>
#include <typeinfo>
#include <vector>
@ -26,8 +28,6 @@
#include <Path.h>
#include <Roster.h>
#include <String.h>
#include <SupportDefs.h>
#include <syslog.h>
using std::string;
@ -37,35 +37,15 @@ const char* B_CLASS_FIELD = "class";
const char* B_ADD_ON_FIELD = "add_on";
const int32 FUNC_NAME_LEN = 1024;
// TODO: consider moving these
// to a separate module, and making them more full-featured (e.g., taking
// NS::ClassName::Function(Param p) instead of just NS::ClassName)
// TODO: consider moving these to a separate module, and making them more
// full-featured (e.g., taking NS::ClassName::Function(Param p) instead
// of just NS::ClassName)
static void Demangle(const char *name, BString &out);
static void Mangle(const char *name, BString &out);
static instantiation_func FindFuncInImage(BString& funcName, image_id id,
status_t& err);
status_t& err);
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()
{
@ -142,12 +122,9 @@ BuildFuncName(const char* className, BString& funcName)
BArchivable*
instantiate_object(BMessage* archive, image_id* id)
{
errno = B_OK;
// Check our params
if (id) {
if (id)
*id = B_BAD_VALUE;
}
if (!archive) {
// TODO: extended error handling
@ -162,7 +139,7 @@ instantiate_object(BMessage* archive, image_id* id)
if (err) {
// TODO: extended error handling
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;
}
@ -172,68 +149,68 @@ instantiate_object(BMessage* archive, image_id* id)
instantiation_func iFunc = find_instantiation_func(name, sig);
// if find_instantiation_func() can't locate Class::Instantiate()
// and a signature was specified
// if find_instantiation_func() can't locate Class::Instantiate()
// and a signature was specified
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;
entry_ref ref;
err = Roster.FindApp(sig, &ref);
// if an entry_ref is obtained
BEntry entry;
// if an entry_ref is obtained
if (!err)
err = entry.SetTo(&ref);
if (err) {
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) {
BPath path;
err = entry.GetPath(&path);
if (!err) {
// load the app/add-on
image_id theImage = load_add_on(path.Path());
if (theImage < 0) {
// load the app/add-on
image_id addOn = load_add_on(path.Path());
if (addOn < 0) {
// TODO: extended error handling
syslog(LOG_ERR, "instantiate_object failed: Could not load "
"add-on %s: %s.", path.Path(), strerror(addOn));
return NULL;
}
// Save the image_id
if (id) {
*id = theImage;
}
if (id)
*id = addOn;
BString 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 "
"Instantiate static function for class %s.", name);
"Instantiate static function for class %s.", name);
}
}
}
} else if (!iFunc) {
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;
}
if (err) {
// TODO: extended error handling
syslog(LOG_ERR, "instantiate_object failed: %s (%x)",
strerror(err), err);
strerror(err), err);
errno = err;
return NULL;
}
// if Class::Instantiate(BMessage*) was found
// if Class::Instantiate(BMessage*) was found
if (iFunc) {
// use to create and return an object instance
// use to create and return an object instance
return iFunc(archive);
}