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