This source file includes following definitions.
- f_reg
- f_reg_write
- f_lnk
- f
- main
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 #undef NDEBUG
  23 #include <assert.h>
  24 #include <errno.h>
  25 #include <sys/types.h>
  26 #include <dirent.h>
  27 #include <stdbool.h>
  28 #include <stdlib.h>
  29 #include <stdio.h>
  30 #include <string.h>
  31 #include <sys/stat.h>
  32 #include <sys/vfs.h>
  33 #include <fcntl.h>
  34 #include <unistd.h>
  35 
  36 #include "proc.h"
  37 
  38 static void f_reg(DIR *d, const char *filename)
  39 {
  40         char buf[4096];
  41         int fd;
  42         ssize_t rv;
  43 
  44         
  45         fd = openat(dirfd(d), filename, O_RDONLY|O_NONBLOCK);
  46         if (fd == -1)
  47                 return;
  48         rv = read(fd, buf, sizeof(buf));
  49         assert((0 <= rv && rv <= sizeof(buf)) || rv == -1);
  50         close(fd);
  51 }
  52 
  53 static void f_reg_write(DIR *d, const char *filename, const char *buf, size_t len)
  54 {
  55         int fd;
  56         ssize_t rv;
  57 
  58         fd = openat(dirfd(d), filename, O_WRONLY);
  59         if (fd == -1)
  60                 return;
  61         rv = write(fd, buf, len);
  62         assert((0 <= rv && rv <= len) || rv == -1);
  63         close(fd);
  64 }
  65 
  66 static void f_lnk(DIR *d, const char *filename)
  67 {
  68         char buf[4096];
  69         ssize_t rv;
  70 
  71         rv = readlinkat(dirfd(d), filename, buf, sizeof(buf));
  72         assert((0 <= rv && rv <= sizeof(buf)) || rv == -1);
  73 }
  74 
  75 static void f(DIR *d, unsigned int level)
  76 {
  77         struct dirent *de;
  78 
  79         de = xreaddir(d);
  80         assert(de->d_type == DT_DIR);
  81         assert(streq(de->d_name, "."));
  82 
  83         de = xreaddir(d);
  84         assert(de->d_type == DT_DIR);
  85         assert(streq(de->d_name, ".."));
  86 
  87         while ((de = xreaddir(d))) {
  88                 assert(!streq(de->d_name, "."));
  89                 assert(!streq(de->d_name, ".."));
  90 
  91                 switch (de->d_type) {
  92                         DIR *dd;
  93                         int fd;
  94 
  95                 case DT_REG:
  96                         if (level == 0 && streq(de->d_name, "sysrq-trigger")) {
  97                                 f_reg_write(d, de->d_name, "h", 1);
  98                         } else if (level == 1 && streq(de->d_name, "clear_refs")) {
  99                                 f_reg_write(d, de->d_name, "1", 1);
 100                         } else if (level == 3 && streq(de->d_name, "clear_refs")) {
 101                                 f_reg_write(d, de->d_name, "1", 1);
 102                         } else {
 103                                 f_reg(d, de->d_name);
 104                         }
 105                         break;
 106                 case DT_DIR:
 107                         fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY);
 108                         if (fd == -1)
 109                                 continue;
 110                         dd = fdopendir(fd);
 111                         if (!dd)
 112                                 continue;
 113                         f(dd, level + 1);
 114                         closedir(dd);
 115                         break;
 116                 case DT_LNK:
 117                         f_lnk(d, de->d_name);
 118                         break;
 119                 default:
 120                         assert(0);
 121                 }
 122         }
 123 }
 124 
 125 int main(void)
 126 {
 127         DIR *d;
 128         struct statfs sfs;
 129 
 130         d = opendir("/proc");
 131         if (!d)
 132                 return 4;
 133 
 134         
 135         if (fstatfs(dirfd(d), &sfs) == -1) {
 136                 return 1;
 137         }
 138         if (sfs.f_type != 0x9fa0) {
 139                 fprintf(stderr, "error: unexpected f_type %lx\n", (long)sfs.f_type);
 140                 return 2;
 141         }
 142 
 143         f(d, 0);
 144 
 145         return 0;
 146 }