S2OJ/web/app/models/FS.php

65 lines
1.6 KiB
PHP

<?php
class FS {
public static function scandir(string $directory, $cfg = []) {
$cfg += [
'exclude_dots' => true
];
$entries = scandir($directory);
if ($cfg['exclude_dots']) {
$entries = array_filter($entries, fn($name) => $name !== '.' && $name !== '..');
}
return $entries;
}
public static function scandir_r(string $directory, $cfg = []) {
foreach (FS::scandir($directory, $cfg) as $name) {
$cur = "{$directory}/{$name}";
if (is_dir($cur)) {
foreach (FS::scandir_r($cur, $cfg) as $sub) {
yield "{$name}/{$sub}";
}
} else {
yield $name;
}
}
}
/**
* @param int $type lock type. can be either LOCK_SH or LOCK_EX
*/
public static function lock_file(string $path, int $type, callable $func) {
$lock_fp = fopen($path, 'c');
if (!flock($lock_fp, $type | LOCK_NB)) {
UOJLog::error("lock failed: {$path}");
return false;
}
$ret = $func();
flock($lock_fp, LOCK_UN | LOCK_NB);
return $ret;
}
public static function randomAvailableFileName($dir, $suffix = '') {
do {
$name = $dir . uojRandString(20) . $suffix;
} while (file_exists(UOJContext::storagePath().$name));
return $name;
}
public static function randomAvailableTmpFileName() {
return static::randomAvailableFileName('/tmp/');
}
public static function randomAvailableSubmissionFileName() {
$num = uojRand(1, 10000);
if (!file_exists(UOJContext::storagePath()."/submission/$num")) {
system("mkdir ".UOJContext::storagePath()."/submission/$num");
}
return static::randomAvailableFileName("/submission/$num/");
}
}