Так вот что я придумал. Я использую холст для рисования линий и getBoundingClientRect
, чтобы получить положение отдельных элементов. Он использует vanilla JS, поэтому нет 600 кБ зависимостей.
https://codepen.io/kwiniarski97/pen/VqNjbm?editors=1111
var c = document.getElementById("canvas");
var li1 = document.getElementById("1");
var li1Pos = li1.getBoundingClientRect();
var li2 = document.getElementById("2");
var li2Pos = li2.getBoundingClientRect();
var li3 = document.getElementById("3");
var li3Pos = li3.getBoundingClientRect();
var li4 = document.getElementById("4");
var li4Pos = li4.getBoundingClientRect();
var ctx = c.getContext("2d");
drawLine(li1Pos, li4Pos, 30);
drawLine(li2Pos, li3Pos, 20);
function drawLine(from, to, deepness){
ctx.beginPath();
ctx.moveTo(from.x, from.y);
ctx.bezierCurveTo(from.x + deepness, from.y , to.x+deepness, to.y, to.x, to.y);
ctx.stroke();
}
div{
display:flex;
}
canvas{
margin-left: -45px;
}
- 1
- 2
- 3
- 4
Я демонтировал рассматриваемую функцию (_utilPurgeDiskBuffers
) от платформы CHUD. Функция, кажется, не очень сложна, но так как я не программист MacOS, импорт и названные sys API не имеют большого смысла мне.
Первая вещь, которую делает API, состоит в том, чтобы вызвать другую функцию, а именно, _miscUtilsUserClientConnect_internal
. Эта функция, кажется, устанавливает соединение с расширением ядра CHUD.
Чтобы сделать это, это звонит _getCHUDUtilsKextService
который пытается определить местоположение расширения ядра CHUD путем перечисления всего использования kexts IORegistryCreateIterator
импортированный из набора ввода-вывода. После того, как kext был найден, он открыт через _IOServiceOpen
.
В этой точке у нас есть соединение с CHUD kext (по крайней мере это - мое понимание из списка дизассемблирования).
Наконец вызов к IOConnectMethodStructureIStructureO
сделан, который я предполагаю, выполняет реальное волшебство.
Не зная некоторые внутренние детали или подпись этой функции параметры не имеют смысла мне.
Вот дизассемблирование, хотя:
__text:4B0157A7 lea eax, [ebp+var_1C]
__text:4B0157AA mov dword ptr [esp+14h], 0
__text:4B0157B2 mov [esp+10h], eax
__text:4B0157B6 mov [esp+0Ch], eax
__text:4B0157BA mov dword ptr [esp+8], 0
__text:4B0157C2 mov dword ptr [esp+4], 0Eh
__text:4B0157CA mov [esp], edx
__text:4B0157CD call _IOConnectMethodStructureIStr
Отметьте это var_1C
был обнулен прежде.
Надо надеяться, некоторые из Вас могут иметь больше смысла из тех syscalls. Если Вы хотите больше информации, сообщить мне.
Обновление:
Для запущения Вас просто возьмите AppleSamplePCIClient.c
пример от набора IO SDK. Это делает в основном, что делает приложение чистки от инструментов CHUD.
Единственной вещью, которую необходимо было бы изменить, являются параметры к финалу _IOConnectMethodStructureIStr
звонить. Возьмите их от упоминающего выше дизассемблирования. Я не могу протестировать весь этот материал, так как у меня нет Mac.
Кажется что:
Можно использовать usr/bin/purge (введите чистку в терминале) для сбрасывания дискового кэша (неактивная память), или можно сделать много случайных чтений от жесткого диска, чтобы сделать то же самое.
Взятый из комментария из пользовательского оружия.
Вы могли использовать sync(2)
несколько раз (как в известной идиоме sync; sync; sync
). Я, может казаться, не нахожу purge
исходный код, но это может просто быть часть пакетов человека, доступных в 10.5.6 кодах
Когда у Вас нет исходного кода для инструмента, Вы хотите эмулировать (как имеет место здесь), существует много способов пойти об этом.
1/Из Вашего кода C, просто назовите инструмент с a system()
вызов функции. Это работает хорошо пока нет никакого видимого эффекта (такого как открытие графического окна). Вы могли использовать system("/path/to/purge -purgargs >/dev/null 2>&1");
, например.
2/Перепроектируют код, чтобы видеть, как он на самом деле делает его. Это несколько более хитро, так как это потребует знания ассемблерного языка, системных вызовов и многих других вещей.
3/Связываются с разработчиками для получения подсказок относительно того, как это было сделано. Это не должно быть, "отправляют мне код, таким образом, я могу сорвать его и делать деньги" вопрос. Вы могли формулировать его как, "У меня есть интерес к использованию чистки для разработки, но я не уверен точно, что, делает" или "У меня есть проблемы безопасности с выполнением кода, власть имущие не позволят мне выполнить его, если мы не будем знать точно, что это делает". Затем Вы кодируете Ваш, чтобы сделать то же.
Меня, я просто использовал бы опцию 1, если возможный (я по сути ленив :-). Если Вы собираетесь записать инструмент для конкуренции с чисткой (и этому трудно дадут, это свободно), опция 2 является, вероятно, лучшим выбором.
Разве Вы не интересовались бы выключением кэша для файла вместо этого? В зависимости от того, чего Вы пытаетесь достигнуть, это могла быть альтернатива. Хорошая сводка здесь.
UBC может быть очищен путем выполнения 'чистки', которая выделяет большую память, чтобы вынудить кэш очиститься.
fcntl(fd, F_GLOBAL_NOCACHE, 1)
может использоваться выключают кэширование для конкретного файла. Это может быть сделано в любом процессе, и файл может быть закрыт после.