S2OJ/web/app/models/FS.php

74 lines
1.8 KiB
PHP
Raw Normal View History

2022-11-06 02:26:21 +00:00
<?php
class FS {
public static function scandir(string $directory, $cfg = []) {
$cfg += [
2023-02-13 00:28:33 +00:00
'exclude_dots' => true
2022-11-06 02:26:21 +00:00
];
$entries = scandir($directory);
if ($cfg['exclude_dots']) {
2023-02-13 00:28:33 +00:00
$entries = array_values(array_filter($entries, fn ($name) => $name !== '.' && $name !== '..'));
2022-11-06 02:26:21 +00:00
}
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
2023-02-13 00:28:33 +00:00
*/
2022-11-06 02:26:21 +00:00
public static function lock_file(string $path, int $type, callable $func) {
$lock_fp = fopen($path, 'c');
2023-02-13 00:28:33 +00:00
2022-11-06 02:26:21 +00:00
if (!flock($lock_fp, $type | LOCK_NB)) {
UOJLog::error("lock failed: {$path}");
return false;
}
2023-02-13 00:28:33 +00:00
2022-11-06 02:26:21 +00:00
$ret = $func();
2023-02-13 00:28:33 +00:00
2022-11-06 02:26:21 +00:00
flock($lock_fp, LOCK_UN | LOCK_NB);
return $ret;
}
public static function randomAvailableFileName($dir, $suffix = '') {
do {
$name = $dir . uojRandString(20) . $suffix;
2023-02-13 00:28:33 +00:00
} while (file_exists(UOJContext::storagePath() . $name));
2022-11-06 02:26:21 +00:00
return $name;
}
public static function randomAvailableTmpFileName() {
return static::randomAvailableFileName('/tmp/');
}
public static function randomAvailableSubmissionFileName() {
$num = uojRand(1, 10000);
2023-02-13 00:28:33 +00:00
if (!file_exists(UOJContext::storagePath() . "/submission/$num")) {
system("mkdir " . UOJContext::storagePath() . "/submission/$num");
2022-11-06 02:26:21 +00:00
}
return static::randomAvailableFileName("/submission/$num/");
}
2023-02-13 00:28:33 +00:00
public static function moveFilesInDir(string $src, string $dest) {
foreach (FS::scandir($src) as $name) {
if (!rename("{$src}/{$name}", "{$dest}/{$name}")) {
return false;
}
}
return true;
}
2022-11-06 02:26:21 +00:00
}