• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015 PLUMgrid, Inc.
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 <cstring>
17 #include <memory>
18 #include <string>
19 #include <vector>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <ftw.h>
23 
24 namespace ebpf {
25 
26 struct FileDeleter {
operatorFileDeleter27   void operator() (FILE *fp) {
28     fclose(fp);
29   }
30 };
31 typedef std::unique_ptr<FILE, FileDeleter> FILEPtr;
32 
33 // Helper with pushd/popd semantics
34 class DirStack {
35  public:
DirStack(const std::string & dst)36   explicit DirStack(const std::string &dst) : ok_(false) {
37     if (getcwd(cwd_, sizeof(cwd_)) == NULL) {
38       ::perror("getcwd");
39       return;
40     }
41     if (::chdir(dst.c_str())) {
42       fprintf(stderr, "chdir(%s): %s\n", dst.c_str(), strerror(errno));
43       return;
44     }
45     ok_ = true;
46   }
~DirStack()47   ~DirStack() {
48     if (!ok_) return;
49     if (::chdir(cwd_)) {
50       fprintf(stderr, "chdir(%s): %s\n", cwd_, strerror(errno));
51     }
52   }
ok()53   bool ok() const { return ok_; }
cwd()54   const char * cwd() const { return cwd_; }
55  private:
56   bool ok_;
57   char cwd_[256];
58 };
59 
ftw_cb(const char * path,const struct stat *,int,struct FTW *)60 static int ftw_cb(const char *path, const struct stat *, int, struct FTW *) {
61   return ::remove(path);
62 }
63 
64 // Scoped class to manage the creation/deletion of tmpdirs
65 class TmpDir {
66  public:
67   explicit TmpDir(const std::string &prefix = "/tmp/bcc-")
ok_(false)68       : ok_(false), prefix_(prefix) {
69     prefix_ += "XXXXXX";
70     if (::mkdtemp((char *)prefix_.data()) == NULL)
71       ::perror("mkdtemp");
72     else
73       ok_ = true;
74   }
~TmpDir()75   ~TmpDir() {
76     if (::nftw(prefix_.c_str(), ftw_cb, 20, FTW_DEPTH) < 0)
77       ::perror("ftw");
78     else
79       ::remove(prefix_.c_str());
80   }
ok()81   bool ok() const { return ok_; }
str()82   const std::string & str() const { return prefix_; }
83  private:
84   bool ok_;
85   std::string prefix_;
86 };
87 
88 // Compute the kbuild flags for the currently running kernel
89 // Do this by:
90 //   1. Create temp Makefile with stub dummy.c
91 //   2. Run module build on that makefile, saving the computed flags to a file
92 //   3. Cache the file for fast flag lookup in subsequent runs
93 //  Note: Depending on environment, different cache locations may be desired. In
94 //  case we eventually support non-root user programs, cache in $HOME.
95 class KBuildHelper {
96  public:
97   explicit KBuildHelper(const std::string &kdir, bool has_source_dir);
98   int get_flags(const char *uname_machine, std::vector<std::string> *cflags);
99  private:
100   std::string kdir_;
101   bool has_source_dir_;
102 };
103 
104 }  // namespace ebpf
105