]> git.saurik.com Git - cydia.git/commitdiff
Drop sysroot dependency on coreutils by owning du.
authorJay Freeman (saurik) <saurik@saurik.com>
Sat, 27 Jun 2015 08:42:19 +0000 (01:42 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Sat, 27 Jun 2015 08:42:19 +0000 (01:42 -0700)
DiskUsage.cpp [new file with mode: 0644]
MobileCydia.mm
makefile
sysroot.sh

diff --git a/DiskUsage.cpp b/DiskUsage.cpp
new file mode 100644 (file)
index 0000000..eece02c
--- /dev/null
@@ -0,0 +1,145 @@
+/* Cydia - iPhone UIKit Front-End for Debian APT
+ * Copyright (C) 2008-2014  Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cydia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cydia is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cydia.  If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define _syscall(expr) ({ decltype(expr) _value; for (;;) { \
+    _value = (expr); \
+    if ((long) _value != -1) \
+        break; \
+    if (errno != EINTR) { \
+        perror(#expr); \
+        return -1; \
+    } \
+} _value; })
+
+extern "C" int __getdirentries64(int, char *, int, long *);
+
+enum Recurse {
+    RecurseYes,
+    RecurseNo,
+    RecurseMaybe,
+};
+
+struct File {
+    int fd_;
+
+    File(int fd);
+    ~File();
+
+    operator int() const;
+};
+
+File::File(int fd) :
+    fd_(fd)
+{
+}
+
+File::~File() {
+    close(fd_);
+}
+
+File::operator int() const {
+    return fd_;
+}
+
+static bool DiskUsage(size_t &total, const char *path, size_t before, Recurse recurse) {
+    File fd(_syscall(open_dprotected_np(path, O_RDONLY | O_SYMLINK, 0, O_DP_GETRAWENCRYPTED)));
+
+    struct stat stat;
+    _syscall(fstat(fd, &stat));
+    total += stat.st_blocks * 512;
+
+    if (recurse == RecurseMaybe)
+        switch (stat.st_mode & S_IFMT) {
+            case S_IFLNK:
+                return true;
+            default:
+                return false;
+
+            case S_IFDIR:
+                recurse = RecurseYes;
+                break;
+            case S_IFREG:
+                recurse = RecurseNo;
+                break;
+        }
+
+    if (recurse == RecurseNo) {
+    } else for (long address(0);;) {
+        char buffer[4096];
+        int size(_syscall(__getdirentries64(fd, buffer, sizeof(buffer), &address)));
+        if (size == 0)
+            break;
+
+        const char *next(buffer), *stop(next + size);
+        while (next != stop) {
+            const dirent *dir(reinterpret_cast<const dirent *>(next));
+            const char *name(dir->d_name);
+            size_t after(strlen(name));
+
+            if (dir->d_ino == 0);
+            else if (after == 1 && name[0] == '.');
+            else if (after == 2 && name[0] == '.' && name[1] == '.');
+            else {
+                size_t both(before + 1 + after);
+                char sub[both + 1];
+                memcpy(sub, path, before);
+                sub[before] = '/';
+                memcpy(sub + before + 1, name, after);
+                sub[both] = '\0';
+
+                switch (dir->d_type) {
+                    case DT_DIR:
+                        if (!DiskUsage(total, sub, both, RecurseYes))
+                            return false;
+                        break;
+
+                    case DT_LNK:
+                    case DT_REG:
+                        if (!DiskUsage(total, sub, both, RecurseNo))
+                            return false;
+                        break;
+
+                    default:
+                        return false;
+                }
+            }
+
+            next += dir->d_reclen;
+        }
+    }
+
+    return true;
+}
+
+ssize_t DiskUsage(const char *path) {
+    size_t total(0);
+    if (!DiskUsage(total, path, strlen(path), RecurseMaybe))
+        return -1;
+    return total;
+}
index 196859962fc103d58164e1f389e4f663407639a8..ca91d0868253d43594b5a4463a9eb27f88d19604 100644 (file)
@@ -4728,41 +4728,13 @@ static _H<NSMutableSet> Diversions_;
     nil];
 }
 
-- (NSNumber *) du:(NSString *)path {
-    NSNumber *value(nil);
-
-    int fds[2];
-    _assert(pipe(fds) != -1);
-
-    pid_t pid(ExecFork());
-    if (pid == 0) {
-        _assert(dup2(fds[1], 1) != -1);
-        _assert(close(fds[0]) != -1);
-        _assert(close(fds[1]) != -1);
-        /* XXX: this should probably not use du */
-        _root(execl("/usr/libexec/cydia/du", "du", "-s", [path UTF8String], NULL));
-        exit(1);
-    } else {
-        _assert(close(fds[1]) != -1);
+ssize_t DiskUsage(const char *path);
 
-        if (FILE *du = fdopen(fds[0], "r")) {
-            char line[1024];
-            while (fgets(line, sizeof(line), du) != NULL) {
-                size_t length(strlen(line));
-                while (length != 0 && line[length - 1] == '\n')
-                    line[--length] = '\0';
-                if (char *tab = strchr(line, '\t')) {
-                    *tab = '\0';
-                    value = [NSNumber numberWithUnsignedLong:strtoul(line, NULL, 0)];
-                }
-            }
-
-            fclose(du);
-        } else
-            _assert(close(fds[0]) != -1);
-    } ReapZombie(pid);
-
-    return value;
+- (NSNumber *) du:(NSString *)path {
+    ssize_t usage(DiskUsage([path UTF8String]));
+    if (usage != -1)
+        usage /= 1024;
+    return [NSNumber numberWithUnsignedLong:usage];
 }
 
 - (void) close {
index fbca76be5416663fe46f62fcda67dd14a17059f2..f47ab0283d352cbe559d21e720ddccde59ace447 100644 (file)
--- a/makefile
+++ b/makefile
@@ -61,7 +61,7 @@ dirs := Menes CyteKit Cydia SDURLCache
 
 code := $(foreach dir,$(dirs),$(wildcard $(foreach ext,h hpp c cpp m mm,$(dir)/*.$(ext))))
 code := $(filter-out SDURLCache/SDURLCacheTests.m,$(code))
-code += MobileCydia.mm Version.mm iPhonePrivate.h Cytore.hpp lookup3.c Sources.h Sources.mm
+code += MobileCydia.mm Version.mm iPhonePrivate.h Cytore.hpp lookup3.c Sources.h Sources.mm DiskUsage.cpp
 
 source := $(filter %.m,$(code)) $(filter %.mm,$(code))
 source += $(filter %.c,$(code)) $(filter %.cpp,$(code))
@@ -95,6 +95,11 @@ Objects/%.o: %.m $(header)
        @echo "[cycc] $<"
        @$(cycc) -c $< $(flags)
 
+Objects/%.o: %.cpp $(header)
+       @mkdir -p $(dir $@)
+       @echo "[cycc] $<"
+       @$(cycc) -std=c++11 -c $< $(flags) $(xflags)
+
 Objects/%.o: %.mm $(header)
        @mkdir -p $(dir $@)
        @echo "[cycc] $<"
@@ -146,7 +151,6 @@ debs/cydia_$(version)_iphoneos-arm.deb: MobileCydia preinst postinst cfversion s
        
        mkdir -p _/usr/libexec
        cp -a Library _/usr/libexec/cydia
-       cp -a sysroot/usr/bin/du _/usr/libexec/cydia
        cp -a cfversion _/usr/libexec/cydia
        cp -a setnsfpn _/usr/libexec/cydia
        
index e17d8d9be5576af916330ff002a05f969325c269..6b277d29f6a67e3ed1ad78406da43092c7250bce 100755 (executable)
@@ -64,7 +64,6 @@ declare -A urls
 
 urls[apt7]=http://apt.saurik.com/debs/apt7_0.7.25.3-7_iphoneos-arm.deb
 urls[apt7-lib]=http://apt.saurik.com/debs/apt7-lib_0.7.25.3-12_iphoneos-arm.deb
-urls[coreutils]=http://apt.saurik.com/debs/coreutils_7.4-11_iphoneos-arm.deb
 
 if [[ 0 ]]; then
     wget -qO- "${repository}dists/${distribution}/${component}/binary-${architecture}/Packages.bz2" | bzcat | {