Ticket #12317: class_NetworktimeprefletAsAddon_+main_+intentionalcrash.cpp

File class_NetworktimeprefletAsAddon_+main_+intentionalcrash.cpp, 4.2 KB (added by ttcoder, 9 years ago)

Directly compilable and usable (unlike the original in 12319)

Line 
1/*
2
3gcc class_NetworktimeprefletAsAddon.cpp -lbe
4
5*/
6
7
8#include <image.h>
9#include <stdio.h>
10#include <stdlib.h>
11
12#include <String.h>
13#include <Path.h>
14#include <FindDirectory.h>
15
16
17//#pragma mark - class NetworktimeprefletAsAddon -
18
19
20class NetworktimeprefletAsAddon
21{
22 /*
23 This allows to invoke the /system/preferences/Time preflet.. Not with load_image()
24 but outright with load_add_on() so that we can call its ntp_update_time() function directly.
25 The source for that particular function is here:
26 http://cgit.haiku-os.org/haiku/tree/src/preferences/time/ntp.cpp
27 which is (in the original Time preflet) called from
28 http://cgit.haiku-os.org/haiku/tree/src/preferences/time/NetworkTimeView.cpp
29 */
30
31public:
32
33 NetworktimeprefletAsAddon();
34 ~NetworktimeprefletAsAddon();
35
36 void UpdateSystemTime();
37
38private: // CODE
39
40 static status_t thread_func( void * );
41
42
43private: // DATA
44
45 image_id addonId;
46 thread_id updaterThread;
47};
48
49
50NetworktimeprefletAsAddon::NetworktimeprefletAsAddon()
51: addonId( -1 ),
52 updaterThread( -1 )
53{
54 addonId = load_add_on( "/system/preferences/Time" );
55 if( addonId < B_OK )
56 {
57 printf( "** NetworktimeprefletAsAddon failure: can't load Time preflet: " );
58 perror( strerror(addonId) );
59 }
60 //printf("addonId %ld\n", addonId);
61}
62
63NetworktimeprefletAsAddon::~NetworktimeprefletAsAddon()
64{
65 // make sure to kill the thread dead before we unload_add_on() the add-on
66 // and its TEXT segment which the thread is running, or that will crash good! :
67
68 if( updaterThread > 0 )
69 kill_thread( updaterThread );
70
71 if( addonId > 0 )
72 unload_add_on( addonId );
73}
74
75
76void NetworktimeprefletAsAddon::UpdateSystemTime()
77{
78 status_t (*ntp_update_time)( const char *host, const char** errorString, int32* errorCode )
79 = NULL
80 ;
81 status_t sta = get_image_symbol(
82 addonId,
83 "ntp_update_time__FPCcPPCcPl", // "ntp_update_time" with some gcc2 name-mangling :-/
84 B_SYMBOL_TYPE_TEXT,
85 reinterpret_cast<void**>( &ntp_update_time )
86 );
87 printf("func %p\n", ntp_update_time);
88
89 if( sta != B_OK || NULL == ntp_update_time )
90 {
91 printf( "** NetworktimeprefletAsAddon: get_image_symbol failure: " );
92 perror( strerror(sta) );
93
94 //
95 return;
96 //
97 }
98
99 updaterThread = spawn_thread(
100 thread_func, "(add-on)ntp_update_time",
101 B_NORMAL_PRIORITY,
102 ntp_update_time
103 );
104 resume_thread( updaterThread );
105
106 // wait for (at most) 2 seconds:
107 for( int i = 0; i < 20; i++ )
108 {
109 snooze( 100000 );
110
111 // "resume_thread" is a good way to test if a thread is still running or not:
112 status_t test = resume_thread( updaterThread );
113 //printf( "0x%lx for updaterThread\n", test );
114 if( B_BAD_THREAD_ID == test )
115 // the thread has exited, no need to wait any longer
116 return;
117 //
118 }
119
120 // if we're here, we've waited for 2 seconds and the thread is STILL running...
121 printf( "* NetworktimeprefletAsAddon: network thread stuck for too long, aborting (will try again later)\n" );
122}
123
124status_t NetworktimeprefletAsAddon::thread_func( void * func_inside_addon )
125{
126 // SUMMARY
127 // - load settings BMessage
128 // - call function
129
130#if 1
131char * null = NULL;
132puts(null);
133#endif
134 status_t (*ntp_update_time)( const char *host, const char** errorString, int32* errorCode )
135 = NULL
136 ;
137 (void*)ntp_update_time = func_inside_addon;
138
139 const char * error_string = NULL;
140 int32 error_code = 0;
141 BString server;
142 {
143 // load "~/config/settings/networktime settings":
144/*
145 EasyMessage system_settings;
146 {
147 BPath path;
148 find_directory( B_USER_SETTINGS_DIRECTORY, &path );
149 path.Append( "networktime settings" );
150
151 system_settings.LoadFrom( path.Path() );
152 }
153 server = system_settings.String( "server" ); // server[0] contains e.g. "pool.ntp.org"
154*/
155 server = "pool.ntp.org";
156
157 // notes:
158 // - passing "invalid.blah" results in message << NTP STATUS = 0x80006003 error_string=<Could not contact server> error_code=0x0 >>
159 // - passing "invalid.com" stays stuck for many seconds (the invalid.com server probably fails to respond to our port probing..)
160 }
161 ;
162 status_t status = ntp_update_time(
163 server,
164 &error_string,
165 &error_code
166 );
167
168 if( B_OK != status )
169 printf( "** NetworktimeprefletAsAddon status = 0x%lx error_string=<%s> error_code=0x%lx\n", status, error_string, error_code );
170
171 return 0;
172}
173
174
175
176int main()
177{
178 printf("Running..\n");
179 NetworktimeprefletAsAddon addon;
180 addon.UpdateSystemTime();
181}
182