ClatdController.cpp revision 84c1d035fdef996602ab8878d952c4fcb1f6963d
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <unistd.h>
17#include <errno.h>
18#include <sys/types.h>
19#include <sys/wait.h>
20
21#define LOG_TAG "ClatdController"
22#include <cutils/log.h>
23
24#include "ClatdController.h"
25#include "NetdConstants.h"
26#include "NetworkController.h"
27
28ClatdController::ClatdController(NetworkController* controller)
29        : mNetCtrl(controller), mClatdPid(0) {
30}
31
32ClatdController::~ClatdController() {
33}
34
35int ClatdController::startClatd(char *interface) {
36    pid_t pid;
37
38    if(mClatdPid != 0) {
39        ALOGE("clatd already running");
40        errno = EBUSY;
41        return -1;
42    }
43
44    ALOGD("starting clatd");
45
46    if ((pid = fork()) < 0) {
47        ALOGE("fork failed (%s)", strerror(errno));
48        return -1;
49    }
50
51    if (!pid) {
52        char netId[UINT32_STRLEN];
53        snprintf(netId, sizeof(netId), "%u", mNetCtrl->getNetworkId(interface));
54        char *args[] = {
55            (char*)"/system/bin/clatd",
56            (char*)"-i",
57            interface,
58            (char*)"-n",
59            netId,
60            NULL
61        };
62
63        if (execv(args[0], args)) {
64            ALOGE("execv failed (%s)", strerror(errno));
65        }
66        ALOGE("Should never get here!");
67        _exit(0);
68    } else {
69        mClatdPid = pid;
70        ALOGD("clatd started");
71    }
72
73    return 0;
74}
75
76int ClatdController::stopClatd() {
77    if (mClatdPid == 0) {
78        ALOGE("clatd already stopped");
79        return -1;
80    }
81
82    ALOGD("Stopping clatd");
83
84    kill(mClatdPid, SIGTERM);
85    waitpid(mClatdPid, NULL, 0);
86    mClatdPid = 0;
87
88    ALOGD("clatd stopped");
89
90    return 0;
91}
92
93bool ClatdController::isClatdStarted() {
94    pid_t waitpid_status;
95    if(mClatdPid == 0) {
96        return false;
97    }
98    waitpid_status = waitpid(mClatdPid, NULL, WNOHANG);
99    if(waitpid_status != 0) {
100        mClatdPid = 0; // child exited, don't call waitpid on it again
101    }
102    return waitpid_status == 0; // 0 while child is running
103}
104