main.cpp revision ae10b91044bf76b40b77d81c169e48e0bbdf6d75
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License. 689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at 789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and 1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License. 1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */ 1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdio.h> 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdlib.h> 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <errno.h> 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <string.h> 217562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <sys/stat.h> 2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h> 23c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <fcntl.h> 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <dirent.h> 2664760240f931714858a59c1579f07264d7182ba2Dima Zavin 27fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#define LOG_TAG "Vold" 28c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 29c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent#include "cutils/log.h" 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "VolumeManager.h" 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "CommandListener.h" 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "NetlinkManager.h" 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "DirectVolume.h" 3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic int process_config(VolumeManager *vm); 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void coldboot(const char *path); 38c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 39c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurentint main() { 40c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 41f8c1a6f7ef515810356816b50bfe18af95f3ec32Glenn Kasten VolumeManager *vm; 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CommandListener *cl; 43fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin NetlinkManager *nm; 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGI("Vold 2.0 firing up"); 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project /* Create our singleton managers */ 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!(vm = VolumeManager::Instance())) { 4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Unable to create VolumeManager"); 5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(1); 5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project }; 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!(nm = NetlinkManager::Instance())) { 5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Unable to create NetlinkManager"); 5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(1); 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project }; 5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cl = new CommandListener(); 595ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block vm->setBroadcaster((SocketListener *) cl); 6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project nm->setBroadcaster((SocketListener *) cl); 6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (vm->start()) { 6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Unable to start VolumeManager (%s)", strerror(errno)); 6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(1); 6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (process_config(vm)) { 6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Error reading configuration (%s)", strerror(errno)); 6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(1); 7089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (nm->start()) { 7329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block LOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(1); 75c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project coldboot("/sys/block"); 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project /* 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Now that we're up, we can respond to commands 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */ 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (cl->startListener()) { 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Unable to start CommandListener (%s)", strerror(errno)); 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(1); 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Eventually we'll become the monitoring thread 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while(1) { 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sleep(1000); 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGI("Vold exiting"); 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project exit(0); 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void do_coldboot(DIR *d, int lvl) 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project struct dirent *de; 9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int dfd, fd; 10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dfd = dirfd(d); 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fd = openat(dfd, "uevent", O_WRONLY); 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if(fd >= 0) { 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project write(fd, "add\n", 4); 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project close(fd); 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while((de = readdir(d))) { 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DIR *d2; 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (de->d_name[0] == '.') 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project continue; 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (de->d_type != DT_DIR && lvl > 0) 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project continue; 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if(fd < 0) 12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project continue; 12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project d2 = fdopendir(fd); 123fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten if(d2 == 0) 12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project close(fd); 125fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin else { 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do_coldboot(d2, lvl + 1); 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project closedir(d2); 128c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 132fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatic void coldboot(const char *path) 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 134fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin DIR *d = opendir(path); 13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if(d) { 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do_coldboot(d, 0); 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project closedir(d); 13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 141fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatic int process_config(VolumeManager *vm) { 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project FILE *fp; 143fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int n = 0; 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project char line[255]; 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 146c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (!(fp = fopen("/etc/vold.fstab", "r"))) { 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return -1; 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 150fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten while(fgets(line, sizeof(line), fp)) { 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project char *next = line; 152fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin char *type, *label, *mount_point; 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project n++; 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project line[strlen(line)-1] = '\0'; 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (line[0] == '#' || line[0] == '\0') 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project continue; 159f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kasten 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!(type = strsep(&next, " \t"))) { 161930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten LOGE("Error parsing type"); 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto out_syntax; 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!(label = strsep(&next, " \t"))) { 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Error parsing label"); 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto out_syntax; 167c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!(mount_point = strsep(&next, " \t"))) { 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Error parsing mount point"); 170c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent goto out_syntax; 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 173c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (!strcmp(type, "dev_mount")) { 17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DirectVolume *dv = NULL; 175c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent char *part, *sysfs_path; 176c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!(part = strsep(&next, " \t"))) { 178c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent LOGE("Error parsing partition"); 179c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent goto out_syntax; 18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (strcmp(part, "auto") && atoi(part) == 0) { 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Partition must either be 'auto' or 1 based index instead of '%s'", part); 18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto out_syntax; 18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dv = new DirectVolume(label, mount_point, atoi(part)); 18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while((sysfs_path = strsep(&next, " \t"))) { 18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (dv->addPath(sysfs_path)) { 19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Failed to add devpath %s to volume %s", sysfs_path, 19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project label); 19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto out_fail; 193b8a805261bf0282e992d3608035e47d05a898710Steve Block } 19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project vm->addVolume(dv); 19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (!strcmp(type, "map_mount")) { 19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOGE("Unknown type '%s'", type); 19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project goto out_syntax; 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 201b8a805261bf0282e992d3608035e47d05a898710Steve Block } 20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fclose(fp); 20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return 0; 20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 206c813985abd8ba61e999b3505f6a332574f87a1beAndreas Huberout_syntax: 207c813985abd8ba61e999b3505f6a332574f87a1beAndreas Huber LOGE("Syntax error on config line %d", n); 208c813985abd8ba61e999b3505f6a332574f87a1beAndreas Huber errno = -EINVAL; 209c813985abd8ba61e999b3505f6a332574f87a1beAndreas Huberout_fail: 210c813985abd8ba61e999b3505f6a332574f87a1beAndreas Huber fclose(fp); 211fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten return -1; 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 213c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent