OSDN Git Service

am e0644327: Fix a TOCTOU and symlink attack in netd.
[android-x86/system-netd.git] / ClatdController.cpp
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
26 ClatdController::ClatdController() {
27     mClatdPid = 0;
28 }
29
30 ClatdController::~ClatdController() {
31 }
32
33 int ClatdController::startClatd(char *interface) {
34     pid_t pid;
35
36     if(mClatdPid != 0) {
37         ALOGE("clatd already running");
38         errno = EBUSY;
39         return -1;
40     }
41
42     ALOGD("starting clatd");
43
44     if ((pid = fork()) < 0) {
45         ALOGE("fork failed (%s)", strerror(errno));
46         return -1;
47     }
48
49     if (!pid) {
50         char **args = (char **)malloc(sizeof(char *) * 4);
51         args[0] = (char *)"/system/bin/clatd";
52         args[1] = (char *)"-i";
53         args[2] = interface;
54         args[3] = NULL;
55
56         if (execv(args[0], args)) {
57             ALOGE("execv failed (%s)", strerror(errno));
58         }
59         ALOGE("Should never get here!");
60         free(args);
61         _exit(0);
62     } else {
63         mClatdPid = pid;
64         ALOGD("clatd started");
65     }
66
67     return 0;
68 }
69
70 int ClatdController::stopClatd() {
71     if (mClatdPid == 0) {
72         ALOGE("clatd already stopped");
73         return -1;
74     }
75
76     ALOGD("Stopping clatd");
77
78     kill(mClatdPid, SIGTERM);
79     waitpid(mClatdPid, NULL, 0);
80     mClatdPid = 0;
81
82     ALOGD("clatd stopped");
83
84     return 0;
85 }
86
87 bool ClatdController::isClatdStarted() {
88     pid_t waitpid_status;
89     if(mClatdPid == 0) {
90         return false;
91     }
92     waitpid_status = waitpid(mClatdPid, NULL, WNOHANG);
93     if(waitpid_status != 0) {
94         mClatdPid = 0; // child exited, don't call waitpid on it again
95     }
96     return waitpid_status == 0; // 0 while child is running
97 }