@@ -75,6 +75,9 @@ PB_BIND(PersistentProperties_PersistentPropertyRecord, PersistentProperties_Pers
7575 * End of auto generated code
7676 * ***************************/
7777
78+ #define PERSIST_PROP_DIR " /data/property"
79+ #define PERSIST_PROP PERSIST_PROP_DIR " /persistent_properties"
80+
7881static bool name_decode (pb_istream_t *stream, const pb_field_t *, void **arg) {
7982 string &name = *static_cast <string *>(*arg);
8083 name.resize (stream->bytes_left );
@@ -102,7 +105,7 @@ static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * co
102105 PersistentProperties_PersistentPropertyRecord prop{};
103106 prop.name .funcs .encode = name_encode;
104107 prop.has_value = true ;
105- auto &list = *static_cast <prop_list *>(*arg);
108+ prop_list &list = *static_cast <prop_list *>(*arg);
106109 for (auto &p : list) {
107110 if (!pb_encode_tag_for_field (stream, field))
108111 return false ;
@@ -119,8 +122,7 @@ static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t coun
119122 return xwrite (fd, buf, count) == count;
120123}
121124
122- static pb_ostream_t create_ostream (const char *filename) {
123- int fd = creat (filename, 0644 );
125+ static pb_ostream_t create_ostream (int fd) {
124126 pb_ostream_t o = {
125127 .callback = write_callback,
126128 .state = (void *)(intptr_t )fd,
@@ -130,19 +132,40 @@ static pb_ostream_t create_ostream(const char *filename) {
130132 return o;
131133}
132134
133- static void pb_getprop (prop_cb *prop_cb) {
134- LOGD (" resetprop: decode with protobuf [" PERSISTENT_PROPERTY_DIR " /persistent_properties ]\n " );
135- PersistentProperties props = {};
135+ static void pb_get_prop (prop_cb *prop_cb) {
136+ LOGD (" resetprop: decode with protobuf [" PERSIST_PROP " ]\n " );
137+ PersistentProperties props{};
136138 props.properties .funcs .decode = prop_decode;
137139 props.properties .arg = prop_cb;
138- auto m = mmap_data (PERSISTENT_PROPERTY_DIR " /persistent_properties " );
140+ auto m = mmap_data (PERSIST_PROP );
139141 pb_istream_t stream = pb_istream_from_buffer (m.buf , m.sz );
140142 pb_decode (&stream, &PersistentProperties_msg, &props);
141143}
142144
143- static bool file_getprop (const char *name, char *value) {
145+ static bool pb_write_props (prop_list &list) {
146+ char tmp[4096 ];
147+ strscpy (tmp, PERSIST_PROP " .XXXXXX" , sizeof (tmp));
148+ int fd = mkostemp (tmp, O_CLOEXEC);
149+ if (fd < 0 )
150+ return false ;
151+
152+ pb_ostream_t ostream = create_ostream (fd);
153+ PersistentProperties props{};
154+ props.properties .funcs .encode = prop_encode;
155+ props.properties .arg = &list;
156+ LOGD (" resetprop: encode with protobuf [%s]\n " , tmp);
157+ bool ret = pb_encode (&ostream, &PersistentProperties_msg, &props);
158+ close (fd);
159+ if (!ret)
160+ return false ;
161+
162+ clone_attr (PERSIST_PROP, tmp);
163+ return rename (tmp, PERSIST_PROP) == 0 ;
164+ }
165+
166+ static bool file_get_prop (const char *name, char *value) {
144167 char path[4096 ];
145- ssprintf (path, sizeof (path), PERSISTENT_PROPERTY_DIR " /%s" , name);
168+ ssprintf (path, sizeof (path), PERSIST_PROP_DIR " /%s" , name);
146169 int fd = open (path, O_RDONLY | O_CLOEXEC);
147170 if (fd < 0 )
148171 return false ;
@@ -152,20 +175,38 @@ static bool file_getprop(const char *name, char *value) {
152175 return value[0 ] != ' \0 ' ;
153176}
154177
178+ static bool file_set_prop (const char *name, const char *value) {
179+ char tmp[4096 ];
180+ strscpy (tmp, PERSIST_PROP_DIR " /prop.XXXXXX" , sizeof (tmp));
181+ int fd = mkostemp (tmp, O_CLOEXEC);
182+ if (fd < 0 )
183+ return false ;
184+ auto len = strlen (value);
185+ LOGD (" resetprop: write prop to [%s]\n " , tmp);
186+ bool ret = write (fd, value, len) == len;
187+ close (fd);
188+ if (!ret)
189+ return false ;
190+
191+ char path[4096 ];
192+ ssprintf (path, sizeof (path), PERSIST_PROP_DIR " /%s" , name);
193+ return rename (tmp, path) == 0 ;
194+ }
195+
155196static bool check_pb () {
156- static bool use_pb = access (PERSISTENT_PROPERTY_DIR " /persistent_properties " , R_OK) == 0 ;
197+ static bool use_pb = access (PERSIST_PROP , R_OK) == 0 ;
157198 return use_pb;
158199}
159200
160- void persist_getprops (prop_cb *prop_cb) {
201+ void persist_get_props (prop_cb *prop_cb) {
161202 if (check_pb ()) {
162- pb_getprop (prop_cb);
203+ pb_get_prop (prop_cb);
163204 } else {
164- auto dir = open_dir (PERSISTENT_PROPERTY_DIR );
205+ auto dir = open_dir (PERSIST_PROP_DIR );
165206 if (!dir) return ;
207+ char value[PROP_VALUE_MAX];
166208 for (dirent *entry; (entry = xreaddir (dir.get ()));) {
167- char value[PROP_VALUE_MAX];
168- if (file_getprop (entry->d_name , value))
209+ if (file_get_prop (entry->d_name , value))
169210 prop_cb->exec (entry->d_name , value);
170211 }
171212 }
@@ -174,67 +215,64 @@ void persist_getprops(prop_cb *prop_cb) {
174215struct match_prop_name : prop_cb {
175216 explicit match_prop_name (const char *name) : _name(name) { value[0 ] = ' \0 ' ; }
176217 void exec (const char *name, const char *val) override {
177- if (std::strcmp (name, _name) == 0 )
218+ if (value[ 0 ] == ' \0 ' && _name == name )
178219 strscpy (value, val, sizeof (value));
179220 }
180221 char value[PROP_VALUE_MAX];
181222private:
182- const char * _name;
223+ string_view _name;
183224};
184225
185- string persist_getprop (const char *name) {
226+ string persist_get_prop (const char *name) {
186227 if (check_pb ()) {
187- auto prop = match_prop_name (name);
188- pb_getprop (&prop );
189- if (prop .value [0 ]) {
190- LOGD (" resetprop: get prop (persist) [%s]: [%s]\n " , name, prop .value );
191- return prop .value ;
228+ match_prop_name cb (name);
229+ pb_get_prop (&cb );
230+ if (cb .value [0 ]) {
231+ LOGD (" resetprop: get prop (persist) [%s]: [%s]\n " , name, cb .value );
232+ return cb .value ;
192233 }
193234 } else {
194235 // Try to read from file
195236 char value[PROP_VALUE_MAX];
196- if (file_getprop (name, value)) {
237+ if (file_get_prop (name, value)) {
197238 LOGD (" resetprop: get prop (persist) [%s]: [%s]\n " , name, value);
198239 return value;
199240 }
200241 }
201- return string () ;
242+ return " " ;
202243}
203244
204- bool persist_deleteprop (const char *name) {
245+ bool persist_delete_prop (const char *name) {
205246 if (check_pb ()) {
206247 prop_list list;
207248 prop_collector collector (list);
208- persist_getprops (&collector);
209-
210- for (auto it = list.begin (); it != list.end (); ++it) {
211- if (it->first == name) {
212- list.erase (it);
213- // Dump the props back
214- PersistentProperties props{};
215- pb_ostream_t ostream = create_ostream (PERSISTENT_PROPERTY_DIR
216- " /persistent_properties.tmp" );
217- props.properties .funcs .encode = prop_encode;
218- props.properties .arg = &list;
219- LOGD (" resetprop: encode with protobuf [" PERSISTENT_PROPERTY_DIR
220- " /persistent_properties.tmp]\n " );
221- if (!pb_encode (&ostream, &PersistentProperties_msg, &props))
222- return false ;
223- clone_attr (PERSISTENT_PROPERTY_DIR " /persistent_properties" ,
224- PERSISTENT_PROPERTY_DIR " /persistent_properties.tmp" );
225- rename (PERSISTENT_PROPERTY_DIR " /persistent_properties.tmp" ,
226- PERSISTENT_PROPERTY_DIR " /persistent_properties" );
227- return true ;
228- }
249+ pb_get_prop (&collector);
250+
251+ auto it = list.find (name);
252+ if (it != list.end ()) {
253+ list.erase (it);
254+ return pb_write_props (list);
229255 }
230256 return false ;
231257 } else {
232258 char path[4096 ];
233- ssprintf (path, sizeof (path), PERSISTENT_PROPERTY_DIR " /%s" , name);
259+ ssprintf (path, sizeof (path), PERSIST_PROP_DIR " /%s" , name);
234260 if (unlink (path) == 0 ) {
235261 LOGD (" resetprop: unlink [%s]\n " , path);
236262 return true ;
237263 }
238264 }
239265 return false ;
240266}
267+
268+ bool persist_set_prop (const char *name, const char *value) {
269+ if (check_pb ()) {
270+ prop_list list;
271+ prop_collector collector (list);
272+ pb_get_prop (&collector);
273+ list[name] = value;
274+ return pb_write_props (list);
275+ } else {
276+ return file_set_prop (name, value);
277+ }
278+ }
0 commit comments