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 18 BMessenger unitTesterMessenger; 19 20 static const char *kUnitTesterSignature 21 = "application/x-vnd.obos-roster-launch-test"; 22 23 // init_unit_tester_messenger 24 static 25 status_t 26 init_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 67 status_t 68 get_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 89 class TestApp : public BApplication { 90 public: 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 132 int 133 main(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