1// RosterLaunchTestApp1.cpp 2 3#include <stdio.h> 4#include <string.h> 5 6#include <Application.h> 7#include <Entry.h> 8#include <File.h> 9#include <Message.h> 10#include <Messenger.h> 11#include <OS.h> 12#include <Resources.h> 13#include <Roster.h> 14#include <String.h> 15 16#include "RosterTestAppDefs.h" 17 18BMessenger unitTesterMessenger; 19 20static const char *kUnitTesterSignature 21 = "application/x-vnd.obos-roster-launch-test"; 22 23// init_unit_tester_messenger 24static 25status_t 26init_unit_tester_messenger() 27{ 28 // Unfortunately BeOS R5 doesn't update the roster-side information about 29 // the app looper's port ID once a BApplication has been created, and 30 // thus we can't construct a BMessenger targeting a BApplication created 31 // after the first one using the signature/team ID constructor. 32 // We need to do some hacking. 33 struct fake_messenger { 34 port_id fPort; 35 int32 fHandlerToken; 36 team_id fTeam; 37 int32 extra0; 38 int32 extra1; 39 bool fPreferredTarget; 40 bool extra2; 41 bool extra3; 42 bool extra4; 43 } &fake = *(fake_messenger*)&unitTesterMessenger; 44 // get team 45 status_t error = B_OK; 46 fake.fTeam = BRoster().TeamFor(kUnitTesterSignature); 47 if (fake.fTeam < 0) 48 error = fake.fTeam; 49 // find app looper port 50 bool found = false; 51 int32 cookie = 0; 52 port_info info; 53 while (error == B_OK && !found) { 54 error = get_next_port_info(fake.fTeam, &cookie, &info); 55 found = (error == B_OK && !strcmp("AppLooperPort", info.name)); 56 } 57 // init messenger 58 if (error == B_OK) { 59 fake.fPort = info.port; 60 fake.fHandlerToken = 0; 61 fake.fPreferredTarget = true; 62 } 63 return error; 64} 65 66// get_app_path 67status_t 68get_app_path(char *buffer) 69{ 70 status_t error = (buffer ? B_OK : B_BAD_VALUE); 71 image_info info; 72 int32 cookie = 0; 73 bool found = false; 74 if (error == B_OK) { 75 while (!found && get_next_image_info(0, &cookie, &info) == B_OK) { 76 if (info.type == B_APP_IMAGE) { 77 strncpy(buffer, info.name, B_PATH_NAME_LENGTH); 78 buffer[B_PATH_NAME_LENGTH] = 0; 79 found = true; 80 } 81 } 82 } 83 if (error == B_OK && !found) 84 error = B_ENTRY_NOT_FOUND; 85 return error; 86} 87 88// TestApp 89class TestApp : public BApplication { 90public: 91 TestApp(const char *signature) : BApplication(signature) 92 { 93 } 94 95 virtual void ArgvReceived(int32 argc, char **argv) 96 { 97 BMessage message(MSG_ARGV_RECEIVED); 98 message.AddInt32("argc", argc); 99 for (int32 i = 0; i < argc; i++) 100 message.AddString("argv", argv[i]); 101 unitTesterMessenger.SendMessage(&message); 102 } 103 104 virtual void RefsReceived(BMessage *_message) 105 { 106 BMessage message(*_message); 107 message.what = MSG_REFS_RECEIVED; 108 unitTesterMessenger.SendMessage(&message); 109 } 110 111 virtual void MessageReceived(BMessage *_message) 112 { 113 BMessage message(MSG_MESSAGE_RECEIVED); 114 message.AddMessage("message", _message); 115 message.AddInt32("sender", _message->ReturnAddress().Team()); 116 unitTesterMessenger.SendMessage(&message); 117 } 118 119 virtual bool QuitRequested() 120 { 121 unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED); 122 return true; 123 } 124 125 virtual void ReadyToRun() 126 { 127 unitTesterMessenger.SendMessage(MSG_READY_TO_RUN); 128 } 129}; 130 131// main 132int 133main(int argc, char **argv) 134{ 135 // find app file and get signature from resources 136 char path[B_PATH_NAME_LENGTH]; 137 status_t error = get_app_path(path); 138 char signature[B_MIME_TYPE_LENGTH]; 139 if (error == B_OK) { 140 // init app file 141 BFile file; 142 error = file.SetTo(path, B_READ_ONLY); 143 // get signature 144 BString signatureString; 145 if (error == B_OK) { 146 if (file.ReadAttrString("signature", &signatureString) == B_OK 147 && signatureString.Length() > 0) { 148 strcpy(signature, signatureString.String()); 149 } else 150 strcpy(signature, kDefaultTestAppSignature); 151 } else 152 printf("ERROR: Couldn't init app file: %s\n", strerror(error)); 153 } else 154 printf("ERROR: Couldn't get app ref: %s\n", strerror(error)); 155 // create the app 156 TestApp *app = NULL; 157 if (error == B_OK) { 158 app = new TestApp(signature); 159// unitTesterMessenger = BMessenger(kUnitTesterSignature); 160 error = init_unit_tester_messenger(); 161 if (error != B_OK) 162 printf("ERROR: Couldn't init messenger: %s\n", strerror(error)); 163 // send started message 164 BMessage message(MSG_STARTED); 165 message.AddString("path", path); 166 unitTesterMessenger.SendMessage(&message); 167 // send main() args message 168 BMessage argsMessage(MSG_MAIN_ARGS); 169 argsMessage.AddInt32("argc", argc); 170 for (int i = 0; i < argc; i++) 171 argsMessage.AddString("argv", argv[i]); 172 unitTesterMessenger.SendMessage(&argsMessage); 173 // run the app 174 app->Run(); 175 delete app; 176 // send terminated message 177 unitTesterMessenger.SendMessage(MSG_TERMINATED); 178 } 179 return 0; 180} 181 182