Merge pull request #1394 from inolen/stat_tests
added lchmod, new tests, fixed for mknod return values
This commit is contained in:
Коммит
e6e22495e2
|
@ -1048,27 +1048,45 @@ LibraryManager.library = {
|
|||
mknod: function(path, mode, dev) {
|
||||
// int mknod(const char *path, mode_t mode, dev_t dev);
|
||||
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/mknod.html
|
||||
if (dev !== 0 || !(mode & 0xC000)) { // S_IFREG | S_IFDIR.
|
||||
// Can't create devices or pipes through mknod().
|
||||
path = Pointer_stringify(path);
|
||||
var fmt = (mode & {{{ cDefine('S_IFMT') }}});
|
||||
if (fmt !== {{{ cDefine('S_IFREG') }}} && fmt !== {{{ cDefine('S_IFCHR') }}} &&
|
||||
fmt !== {{{ cDefine('S_IFBLK') }}} && fmt !== {{{ cDefine('S_IFIFO') }}} &&
|
||||
fmt !== {{{ cDefine('S_IFSOCK') }}}) {
|
||||
// not valid formats for mknod
|
||||
___setErrNo(ERRNO_CODES.EINVAL);
|
||||
return -1;
|
||||
} else {
|
||||
var properties = {contents: [], isFolder: Boolean(mode & 0x4000)}; // S_IFDIR.
|
||||
path = FS.analyzePath(Pointer_stringify(path));
|
||||
try {
|
||||
FS.createObject(path.parentObject, path.name, properties,
|
||||
mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR.
|
||||
return 0;
|
||||
} catch (e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (fmt === {{{ cDefine('S_IFCHR') }}} || fmt === {{{ cDefine('S_IFBLK') }}} ||
|
||||
fmt === {{{ cDefine('S_IFIFO') }}} || fmt === {{{ cDefine('S_IFSOCK') }}}) {
|
||||
// not supported currently
|
||||
___setErrNo(ERRNO_CODES.EPERM);
|
||||
return -1;
|
||||
}
|
||||
path = FS.analyzePath(path);
|
||||
var properties = { contents: [], isFolder: false }; // S_IFDIR.
|
||||
try {
|
||||
FS.createObject(path.parentObject, path.name, properties,
|
||||
mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR.
|
||||
return 0;
|
||||
} catch (e) {
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
mkdir__deps: ['mknod'],
|
||||
mkdir: function(path, mode) {
|
||||
// int mkdir(const char *path, mode_t mode);
|
||||
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/mkdir.html
|
||||
return _mknod(path, 0x4000 | (mode & 0x180), 0); // S_IFDIR, S_IRUSR | S_IWUSR.
|
||||
path = Pointer_stringify(path);
|
||||
path = FS.analyzePath(path);
|
||||
var properties = { contents: [], isFolder: true };
|
||||
try {
|
||||
FS.createObject(path.parentObject, path.name, properties,
|
||||
mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR.
|
||||
return 0;
|
||||
} catch (e) {
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
mkfifo__deps: ['__setErrNo', '$ERRNO_CODES'],
|
||||
mkfifo: function(path, mode) {
|
||||
|
@ -1082,10 +1100,13 @@ LibraryManager.library = {
|
|||
return -1;
|
||||
},
|
||||
chmod__deps: ['$FS'],
|
||||
chmod: function(path, mode) {
|
||||
chmod: function(path, mode, dontResolveLastLink) {
|
||||
// int chmod(const char *path, mode_t mode);
|
||||
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/chmod.html
|
||||
var obj = FS.findObject(Pointer_stringify(path));
|
||||
// NOTE: dontResolveLastLink is a shortcut for lchmod(). It should never be
|
||||
// used in client code.
|
||||
path = typeof path !== 'string' ? Pointer_stringify(path) : path;
|
||||
var obj = FS.findObject(path, dontResolveLastLink);
|
||||
if (obj === null) return -1;
|
||||
obj.read = mode & 0x100; // S_IRUSR.
|
||||
obj.write = mode & 0x80; // S_IWUSR.
|
||||
|
@ -1096,15 +1117,16 @@ LibraryManager.library = {
|
|||
fchmod: function(fildes, mode) {
|
||||
// int fchmod(int fildes, mode_t mode);
|
||||
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/fchmod.html
|
||||
if (!FS.streams[fildes]) {
|
||||
var stream = FS.streams[fildes];
|
||||
if (!stream) {
|
||||
___setErrNo(ERRNO_CODES.EBADF);
|
||||
return -1;
|
||||
} else {
|
||||
var pathArray = intArrayFromString(FS.streams[fildes].path);
|
||||
return _chmod(allocate(pathArray, 'i8', ALLOC_STACK), mode);
|
||||
}
|
||||
return _chmod(stream.path, mode);
|
||||
},
|
||||
lchmod: function(path, mode) {
|
||||
return _chmod(path, mode, true);
|
||||
},
|
||||
lchmod: function() { throw 'TODO: lchmod' },
|
||||
|
||||
umask__deps: ['$FS'],
|
||||
umask: function(newMask) {
|
||||
|
@ -6931,15 +6953,15 @@ LibraryManager.library = {
|
|||
// NOTE: These are fake, since we don't support the C device creation API.
|
||||
// http://www.kernel.org/doc/man-pages/online/pages/man3/minor.3.html
|
||||
makedev: function(maj, min) {
|
||||
return 0;
|
||||
return ((maj) << 8 | (min));
|
||||
},
|
||||
gnu_dev_makedev: 'makedev',
|
||||
major: function(dev) {
|
||||
return 0;
|
||||
return ((dev) >> 8);
|
||||
},
|
||||
gnu_dev_major: 'major',
|
||||
minor: function(dev) {
|
||||
return 0;
|
||||
return ((dev) & 0xff);
|
||||
},
|
||||
gnu_dev_minor: 'minor',
|
||||
|
||||
|
|
|
@ -243,6 +243,8 @@ var FS_LOG = 0; // Log all FS operations. This is especially helpful when you'r
|
|||
// a new project and want to see a list of file system operations happening
|
||||
// so that you can create a virtual file system with all of the required files.
|
||||
|
||||
var USE_OLD_FS = 1; // Switch to toggle the new / old FS code. Currently only used for testing purposes.
|
||||
|
||||
var USE_BSS = 1; // https://en.wikipedia.org/wiki/.bss
|
||||
// When enabled, 0-initialized globals are sorted to the end of the globals list,
|
||||
// enabling us to not explicitly store the initialization value for each 0 byte.
|
||||
|
@ -412,7 +414,6 @@ var DEBUG_TAGS_SHOWING = [];
|
|||
// metadata
|
||||
// legalizer
|
||||
|
||||
|
||||
// A cached set of defines, generated from the header files. This
|
||||
// lets the emscripten libc (library.js) see the right values.
|
||||
// If you the headers or use different ones, you will need to override
|
||||
|
|
|
@ -179,7 +179,8 @@ struct stat64
|
|||
#endif
|
||||
|
||||
int _EXFUN(chmod,( const char *__path, mode_t __mode ));
|
||||
int _EXFUN(fchmod,(int __fd, mode_t __mode));
|
||||
int _EXFUN(lchmod,( const char *__path, mode_t __mode ));
|
||||
int _EXFUN(fchmod,(int __fd, mode_t __mode));
|
||||
int _EXFUN(fstat,( int __fd, struct stat *__sbuf ));
|
||||
int _EXFUN(fstat64,( int __fd, struct stat64 *__sbuf )); /* XXX Emscripten */
|
||||
int _EXFUN(mkdir,( const char *_path, mode_t __mode ));
|
||||
|
|
|
@ -159,6 +159,10 @@ typedef __gid_t gid_t;
|
|||
typedef __id_t id_t ; /* can hold a uid_t or pid_t */
|
||||
#endif
|
||||
|
||||
__int32_t major(__uint32_t _x);
|
||||
__int32_t minor(__uint32_t _x);
|
||||
dev_t makedev(__uint32_t _major, __uint32_t _minor);
|
||||
|
||||
#if defined(__XMK__)
|
||||
typedef signed char pid_t;
|
||||
#else
|
||||
|
|
|
@ -7174,23 +7174,19 @@ def process(filename):
|
|||
self.do_run(src, 'success', force_c=True)
|
||||
|
||||
def test_stat(self):
|
||||
add_pre_run = '''
|
||||
def process(filename):
|
||||
src = open(filename, 'r').read().replace(
|
||||
'// {{PRE_RUN_ADDITIONS}}',
|
||||
\'\'\'
|
||||
var f1 = FS.createFolder('/', 'test', true, true);
|
||||
var f2 = FS.createDataFile(f1, 'file', 'abcdef', true, true);
|
||||
var f3 = FS.createLink(f1, 'link', 'file', true, true);
|
||||
var f4 = FS.createDevice(f1, 'device', function(){}, function(){});
|
||||
f1.timestamp = f2.timestamp = f3.timestamp = f4.timestamp = new Date(1200000000000);
|
||||
\'\'\'
|
||||
)
|
||||
open(filename, 'w').write(src)
|
||||
'''
|
||||
src = open(path_from_root('tests', 'stat', 'src.c'), 'r').read()
|
||||
expected = open(path_from_root('tests', 'stat', 'output.txt'), 'r').read()
|
||||
self.do_run(src, expected, post_build=add_pre_run, extra_emscripten_args=['-H', 'libc/fcntl.h'])
|
||||
Building.COMPILER_TEST_OPTS += ['-DUSE_OLD_FS='+str(Settings.USE_OLD_FS)]
|
||||
src = open(path_from_root('tests', 'stat', 'test_stat.c'), 'r').read()
|
||||
self.do_run(src, 'success', force_c=True)
|
||||
|
||||
def test_stat_chmod(self):
|
||||
Building.COMPILER_TEST_OPTS += ['-DUSE_OLD_FS='+str(Settings.USE_OLD_FS)]
|
||||
src = open(path_from_root('tests', 'stat', 'test_chmod.c'), 'r').read()
|
||||
self.do_run(src, 'success', force_c=True)
|
||||
|
||||
def test_stat_mknod(self):
|
||||
Building.COMPILER_TEST_OPTS += ['-DUSE_OLD_FS='+str(Settings.USE_OLD_FS)]
|
||||
src = open(path_from_root('tests', 'stat', 'test_mknod.c'), 'r').read()
|
||||
self.do_run(src, 'success', force_c=True)
|
||||
|
||||
def test_fcntl(self):
|
||||
add_pre_run = '''
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
--stat FOLDER--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_dev: 1
|
||||
st_ino: 2
|
||||
st_mode: 040777
|
||||
st_nlink: 1
|
||||
st_rdev: 0
|
||||
st_size: 4096
|
||||
st_atime: 1200000000
|
||||
st_mtime: 1200000000
|
||||
st_ctime: 1200000000
|
||||
st_blksize: 4096
|
||||
st_blocks: 1
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 1
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 0
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--stat FILE--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_dev: 1
|
||||
st_ino: 3
|
||||
st_mode: 0100777
|
||||
st_nlink: 1
|
||||
st_rdev: 0
|
||||
st_size: 6
|
||||
st_atime: 1200000000
|
||||
st_mtime: 1200000000
|
||||
st_ctime: 1200000000
|
||||
st_blksize: 4096
|
||||
st_blocks: 1
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 0
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 1
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--stat DEVICE--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_dev: 5
|
||||
st_ino: 5
|
||||
st_mode: 020777
|
||||
st_nlink: 1
|
||||
st_rdev: 5
|
||||
st_size: 0
|
||||
st_atime: 1200000000
|
||||
st_mtime: 1200000000
|
||||
st_ctime: 1200000000
|
||||
st_blksize: 4096
|
||||
st_blocks: 0
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 1
|
||||
S_ISDIR: 0
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 0
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--stat LINK--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_dev: 1
|
||||
st_ino: 3
|
||||
st_mode: 0100777
|
||||
st_nlink: 1
|
||||
st_rdev: 0
|
||||
st_size: 6
|
||||
st_atime: 1200000000
|
||||
st_mtime: 1200000000
|
||||
st_ctime: 1200000000
|
||||
st_blksize: 4096
|
||||
st_blocks: 1
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 0
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 1
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--lstat LINK--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_dev: 1
|
||||
st_ino: 4
|
||||
st_mode: 0120777
|
||||
st_nlink: 1
|
||||
st_rdev: 0
|
||||
st_size: 4
|
||||
st_atime: 1200000000
|
||||
st_mtime: 1200000000
|
||||
st_ctime: 1200000000
|
||||
st_blksize: 4096
|
||||
st_blocks: 1
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 0
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 0
|
||||
S_ISLNK: 1
|
||||
S_ISSOCK: 0
|
||||
|
||||
--fstat FILE--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_dev: 1
|
||||
st_ino: 3
|
||||
st_mode: 0100777
|
||||
st_nlink: 1
|
||||
st_rdev: 0
|
||||
st_size: 6
|
||||
st_atime: 1200000000
|
||||
st_mtime: 1200000000
|
||||
st_ctime: 1200000000
|
||||
st_blksize: 4096
|
||||
st_blocks: 1
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 0
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 1
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--chmod FILE--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 0100222
|
||||
st_mtime changed: 1
|
||||
|
||||
--fchmod FILE--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 0100777
|
||||
st_mtime changed: 1
|
||||
|
||||
--chmod FOLDER--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 040555
|
||||
st_mtime changed: 1
|
||||
|
||||
--chmod LINK--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 0100000
|
||||
|
||||
--mkdir--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 040777
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 1
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 0
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--mknod FILE--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 0100777
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 0
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 1
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--mknod FOLDER--
|
||||
ret: 0
|
||||
errno: 0
|
||||
st_mode: 040777
|
||||
S_ISBLK: 0
|
||||
S_ISCHR: 0
|
||||
S_ISDIR: 1
|
||||
S_ISFIFO: 0
|
||||
S_ISREG: 0
|
||||
S_ISLNK: 0
|
||||
S_ISSOCK: 0
|
||||
|
||||
--mknod FIFO--
|
||||
ret: -1
|
||||
errno: 22
|
||||
|
||||
--mknod DEVICE--
|
||||
ret: -1
|
||||
errno: 22
|
||||
|
||||
--mkfifo--
|
||||
ret: -1
|
||||
errno: 30
|
242
tests/stat/src.c
242
tests/stat/src.c
|
@ -1,242 +0,0 @@
|
|||
/*
|
||||
Note: Hardcoded st_ino values etc. may change with minor changes to the library impl.
|
||||
In such an event, we will need to update output.txt here.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int main() {
|
||||
struct stat s;
|
||||
|
||||
printf("--stat FOLDER--\n");
|
||||
printf("ret: %d\n", stat("/test", &s));
|
||||
printf("errno: %d\n", errno);
|
||||
printf("st_dev: %lu\n", s.st_dev);
|
||||
printf("st_ino: %lu\n", s.st_ino);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_nlink: %d\n", s.st_nlink);
|
||||
printf("st_rdev: %lu\n", s.st_rdev);
|
||||
printf("st_size: %ld\n", s.st_size);
|
||||
printf("st_atime: %ld\n", s.st_atime);
|
||||
printf("st_mtime: %ld\n", s.st_mtime);
|
||||
printf("st_ctime: %ld\n", s.st_ctime);
|
||||
printf("st_blksize: %ld\n", s.st_blksize);
|
||||
printf("st_blocks: %ld\n", s.st_blocks);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--stat FILE--\n");
|
||||
printf("ret: %d\n", stat("/test/file", &s));
|
||||
printf("errno: %d\n", errno);
|
||||
printf("st_dev: %lu\n", s.st_dev);
|
||||
printf("st_ino: %lu\n", s.st_ino);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_nlink: %d\n", s.st_nlink);
|
||||
printf("st_rdev: %lu\n", s.st_rdev);
|
||||
printf("st_size: %ld\n", s.st_size);
|
||||
printf("st_atime: %ld\n", s.st_atime);
|
||||
printf("st_mtime: %ld\n", s.st_mtime);
|
||||
printf("st_ctime: %ld\n", s.st_ctime);
|
||||
printf("st_blksize: %ld\n", s.st_blksize);
|
||||
printf("st_blocks: %ld\n", s.st_blocks);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--stat DEVICE--\n");
|
||||
printf("ret: %d\n", stat("/test/device", &s));
|
||||
printf("errno: %d\n", errno);
|
||||
printf("st_dev: %lu\n", s.st_dev);
|
||||
printf("st_ino: %lu\n", s.st_ino);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_nlink: %d\n", s.st_nlink);
|
||||
printf("st_rdev: %lu\n", s.st_rdev);
|
||||
printf("st_size: %ld\n", s.st_size);
|
||||
printf("st_atime: %ld\n", s.st_atime);
|
||||
printf("st_mtime: %ld\n", s.st_mtime);
|
||||
printf("st_ctime: %ld\n", s.st_ctime);
|
||||
printf("st_blksize: %ld\n", s.st_blksize);
|
||||
printf("st_blocks: %ld\n", s.st_blocks);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--stat LINK--\n");
|
||||
printf("ret: %d\n", stat("/test/link", &s));
|
||||
printf("errno: %d\n", errno);
|
||||
printf("st_dev: %lu\n", s.st_dev);
|
||||
printf("st_ino: %lu\n", s.st_ino);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_nlink: %d\n", s.st_nlink);
|
||||
printf("st_rdev: %lu\n", s.st_rdev);
|
||||
printf("st_size: %ld\n", s.st_size);
|
||||
printf("st_atime: %ld\n", s.st_atime);
|
||||
printf("st_mtime: %ld\n", s.st_mtime);
|
||||
printf("st_ctime: %ld\n", s.st_ctime);
|
||||
printf("st_blksize: %ld\n", s.st_blksize);
|
||||
printf("st_blocks: %ld\n", s.st_blocks);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--lstat LINK--\n");
|
||||
printf("ret: %d\n", lstat("/test/link", &s));
|
||||
printf("errno: %d\n", errno);
|
||||
printf("st_dev: %lu\n", s.st_dev);
|
||||
printf("st_ino: %lu\n", s.st_ino);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_nlink: %d\n", s.st_nlink);
|
||||
printf("st_rdev: %lu\n", s.st_rdev);
|
||||
printf("st_size: %ld\n", s.st_size);
|
||||
printf("st_atime: %ld\n", s.st_atime);
|
||||
printf("st_mtime: %ld\n", s.st_mtime);
|
||||
printf("st_ctime: %ld\n", s.st_ctime);
|
||||
printf("st_blksize: %ld\n", s.st_blksize);
|
||||
printf("st_blocks: %ld\n", s.st_blocks);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--fstat FILE--\n");
|
||||
printf("ret: %d\n", fstat(open("/test/file", O_RDONLY, 0777), &s));
|
||||
printf("errno: %d\n", errno);
|
||||
printf("st_dev: %lu\n", s.st_dev);
|
||||
printf("st_ino: %lu\n", s.st_ino);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_nlink: %d\n", s.st_nlink);
|
||||
printf("st_rdev: %lu\n", s.st_rdev);
|
||||
printf("st_size: %ld\n", s.st_size);
|
||||
printf("st_atime: %ld\n", s.st_atime);
|
||||
printf("st_mtime: %ld\n", s.st_mtime);
|
||||
printf("st_ctime: %ld\n", s.st_ctime);
|
||||
printf("st_blksize: %ld\n", s.st_blksize);
|
||||
printf("st_blocks: %ld\n", s.st_blocks);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--chmod FILE--\n");
|
||||
printf("ret: %d\n", chmod("/test/file", 0200));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test/file", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_mtime changed: %d\n", s.st_mtime != 1200000000l);
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--fchmod FILE--\n");
|
||||
printf("ret: %d\n", fchmod(open("/test/file", O_WRONLY, 0777), 0777));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test/file", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_mtime changed: %d\n", s.st_mtime != 1200000000l);
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--chmod FOLDER--\n");
|
||||
printf("ret: %d\n", chmod("/test", 0400));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("st_mtime changed: %d\n", s.st_mtime != 1200000000l);
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--chmod LINK--\n");
|
||||
printf("ret: %d\n", chmod("/test/link", 0000));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test/file", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
// Make sure we can create stuff in the root.
|
||||
chmod("/", 0777);
|
||||
|
||||
printf("\n--mkdir--\n");
|
||||
printf("ret: %d\n", mkdir("/test-mkdir", 0777));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test-mkdir", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--mknod FILE--\n");
|
||||
printf("ret: %d\n", mknod("/test-mknod-file", S_IFREG | 0777, 0));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test-mknod-file", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--mknod FOLDER--\n");
|
||||
printf("ret: %d\n", mknod("/test-mknod-dir", S_IFDIR | 0777, 0));
|
||||
printf("errno: %d\n", errno);
|
||||
stat("/test-mknod-dir", &s);
|
||||
printf("st_mode: 0%o\n", s.st_mode);
|
||||
printf("S_ISBLK: %d\n", S_ISBLK(s.st_mode));
|
||||
printf("S_ISCHR: %d\n", S_ISCHR(s.st_mode));
|
||||
printf("S_ISDIR: %d\n", S_ISDIR(s.st_mode));
|
||||
printf("S_ISFIFO: %d\n", S_ISFIFO(s.st_mode));
|
||||
printf("S_ISREG: %d\n", S_ISREG(s.st_mode));
|
||||
printf("S_ISLNK: %d\n", S_ISLNK(s.st_mode));
|
||||
printf("S_ISSOCK: %d\n", S_ISSOCK(s.st_mode));
|
||||
memset(&s, 0, sizeof s);
|
||||
|
||||
printf("\n--mknod FIFO--\n");
|
||||
printf("ret: %d\n", mknod("/test-mknod-fifo", S_IFIFO | 0777, 0));
|
||||
printf("errno: %d\n", errno);
|
||||
|
||||
printf("\n--mknod DEVICE--\n");
|
||||
printf("ret: %d\n", mknod("/test-mknod-device", S_IFCHR | 0777, 123));
|
||||
printf("errno: %d\n", errno);
|
||||
|
||||
printf("\n--mkfifo--\n");
|
||||
printf("ret: %d\n", mkfifo("/test-mkfifo", 0777));
|
||||
printf("errno: %d\n", errno);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void create_file(const char *path, const char *buffer, int mode) {
|
||||
int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||
assert(fd >= 0);
|
||||
|
||||
int err = write(fd, buffer, sizeof(char) * strlen(buffer));
|
||||
assert(err == (sizeof(char) * strlen(buffer)));
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
create_file("file", "abcdef", 0777);
|
||||
symlink("file", "file-link");
|
||||
// some platforms use 777, some use 755 by default for symlinks
|
||||
// make sure we're using 777 for the test
|
||||
lchmod("file-link", 0777);
|
||||
mkdir("folder", 0777);
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
unlink("file-link");
|
||||
unlink("file");
|
||||
rmdir("folder");
|
||||
}
|
||||
|
||||
void test() {
|
||||
int err;
|
||||
int lastctime;
|
||||
struct stat s;
|
||||
|
||||
//
|
||||
// chmod a file
|
||||
//
|
||||
// get the current ctime for the file
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("file", &s);
|
||||
lastctime = s.st_ctime;
|
||||
sleep(1);
|
||||
|
||||
// do the actual chmod
|
||||
err = chmod("file", 0200);
|
||||
assert(!err);
|
||||
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("file", &s);
|
||||
#if USE_OLD_FS
|
||||
assert(s.st_mode == (0222 | S_IFREG));
|
||||
#else
|
||||
assert(s.st_mode == (0200 | S_IFREG));
|
||||
#endif
|
||||
assert(s.st_ctime != lastctime);
|
||||
|
||||
//
|
||||
// fchmod a file
|
||||
//
|
||||
lastctime = s.st_ctime;
|
||||
sleep(1);
|
||||
|
||||
err = fchmod(open("file", O_WRONLY), 0100);
|
||||
assert(!err);
|
||||
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("file", &s);
|
||||
#if USE_OLD_FS
|
||||
assert(s.st_mode == (0000 | S_IFREG));
|
||||
#else
|
||||
assert(s.st_mode == (0100 | S_IFREG));
|
||||
#endif
|
||||
assert(s.st_ctime != lastctime);
|
||||
|
||||
//
|
||||
// chmod a folder
|
||||
//
|
||||
// get the current ctime for the folder
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("folder", &s);
|
||||
lastctime = s.st_ctime;
|
||||
sleep(1);
|
||||
|
||||
// do the actual chmod
|
||||
err = chmod("folder", 0300);
|
||||
assert(!err);
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("folder", &s);
|
||||
#if USE_OLD_FS
|
||||
assert(s.st_mode == (0222 | S_IFDIR));
|
||||
#else
|
||||
assert(s.st_mode == (0300 | S_IFDIR));
|
||||
#endif
|
||||
assert(s.st_ctime != lastctime);
|
||||
|
||||
//
|
||||
// chmod a symlink's target
|
||||
//
|
||||
err = chmod("file-link", 0400);
|
||||
assert(!err);
|
||||
|
||||
// make sure the file it references changed
|
||||
stat("file-link", &s);
|
||||
#if USE_OLD_FS
|
||||
assert(s.st_mode == (0555 | S_IFREG));
|
||||
#else
|
||||
assert(s.st_mode == (0400 | S_IFREG));
|
||||
#endif
|
||||
|
||||
// but the link didn't
|
||||
lstat("file-link", &s);
|
||||
assert(s.st_mode == (0777 | S_IFLNK));
|
||||
|
||||
//
|
||||
// chmod the actual symlink
|
||||
//
|
||||
err = lchmod("file-link", 0500);
|
||||
assert(!err);
|
||||
|
||||
// make sure the file it references didn't change
|
||||
stat("file-link", &s);
|
||||
#if USE_OLD_FS
|
||||
assert(s.st_mode == (0555 | S_IFREG));
|
||||
#else
|
||||
assert(s.st_mode == (0400 | S_IFREG));
|
||||
#endif
|
||||
|
||||
// but the link did
|
||||
lstat("file-link", &s);
|
||||
#if USE_OLD_FS
|
||||
assert(s.st_mode == (0555 | S_IFLNK));
|
||||
#else
|
||||
assert(s.st_mode == (0500 | S_IFLNK));
|
||||
#endif
|
||||
|
||||
puts("success");
|
||||
}
|
||||
|
||||
int main() {
|
||||
atexit(cleanup);
|
||||
signal(SIGABRT, cleanup);
|
||||
setup();
|
||||
test();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void setup() {
|
||||
mkdir("folder-readonly", 0555);
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
unlink("mknod-file");
|
||||
unlink("mknod-device");
|
||||
rmdir("folder");
|
||||
rmdir("folder-readonly");
|
||||
}
|
||||
|
||||
void test() {
|
||||
int err;
|
||||
struct stat s;
|
||||
|
||||
//
|
||||
// mknod
|
||||
// mknod is _extremely_ unportable for anything other
|
||||
// than a FIFO. so, the tests are disabled when running
|
||||
// natively as they'd be utterly inconsistent.
|
||||
//
|
||||
#if EMSCRIPTEN
|
||||
|
||||
// mknod a folder
|
||||
err = mknod("mknod-folder", S_IFDIR | 0777, 0);
|
||||
assert(err);
|
||||
assert(errno == EINVAL);
|
||||
|
||||
// mknod fifo
|
||||
err = mknod("mknod-fifo", S_IFIFO | 0777, 0);
|
||||
assert(err);
|
||||
assert(errno == EPERM);
|
||||
|
||||
// mknod a file
|
||||
err = mknod("mknod-file", S_IFREG | 0777, 0);
|
||||
assert(!err);
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("mknod-file", &s);
|
||||
assert(S_ISREG(s.st_mode));
|
||||
|
||||
// mknod a character device
|
||||
err = mknod("mknod-device", S_IFCHR | 0777, 123);
|
||||
#if USE_OLD_FS
|
||||
assert(err);
|
||||
assert(errno == EPERM);
|
||||
#else
|
||||
assert(!err);
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("mknod-device", &s);
|
||||
assert(S_ISCHR(s.st_mode));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// mkdir
|
||||
//
|
||||
// can't mkdir in a readonly dir
|
||||
err = mkdir("folder-readonly/subfolder", 0777);
|
||||
assert(err);
|
||||
assert(errno == EACCES);
|
||||
|
||||
// regular creation
|
||||
err = mkdir("folder", 0777);
|
||||
assert(!err);
|
||||
memset(&s, 0, sizeof s);
|
||||
stat("folder", &s);
|
||||
assert(S_ISDIR(s.st_mode));
|
||||
|
||||
// try to re-create the same folder
|
||||
err = mkdir("folder", 0777);
|
||||
assert(err);
|
||||
assert(errno == EEXIST);
|
||||
|
||||
puts("success");
|
||||
}
|
||||
|
||||
int main() {
|
||||
atexit(cleanup);
|
||||
signal(SIGABRT, cleanup);
|
||||
setup();
|
||||
test();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void create_file(const char *path, const char *buffer, int mode) {
|
||||
int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||
assert(fd >= 0);
|
||||
|
||||
int err = write(fd, buffer, sizeof(char) * strlen(buffer));
|
||||
assert(err == (sizeof(char) * strlen(buffer)));
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
struct utimbuf t = {1200000000, 1200000000};
|
||||
|
||||
mkdir("folder", 0777);
|
||||
create_file("folder/file", "abcdef", 0777);
|
||||
symlink("file", "folder/file-link");
|
||||
|
||||
utime("folder/file", &t);
|
||||
utime("folder", &t);
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
unlink("folder/file");
|
||||
unlink("folder/file-link");
|
||||
rmdir("folder");
|
||||
}
|
||||
|
||||
void test() {
|
||||
int err;
|
||||
struct stat s;
|
||||
|
||||
// stat a folder
|
||||
memset(&s, 0, sizeof(s));
|
||||
err = stat("folder", &s);
|
||||
assert(!err);
|
||||
assert(s.st_dev);
|
||||
assert(s.st_ino);
|
||||
assert(S_ISDIR(s.st_mode));
|
||||
assert(s.st_nlink);
|
||||
assert(s.st_rdev == 0);
|
||||
assert(s.st_size);
|
||||
assert(s.st_atime == 1200000000);
|
||||
assert(s.st_mtime == 1200000000);
|
||||
assert(s.st_ctime);
|
||||
#ifdef EMSCRIPTEN
|
||||
assert(s.st_blksize == 4096);
|
||||
assert(s.st_blocks == 1);
|
||||
#endif
|
||||
|
||||
// stat a file
|
||||
memset(&s, 0, sizeof(s));
|
||||
err = stat("folder/file", &s);
|
||||
assert(!err);
|
||||
assert(s.st_dev);
|
||||
assert(s.st_ino);
|
||||
assert(S_ISREG(s.st_mode));
|
||||
assert(s.st_nlink);
|
||||
assert(s.st_rdev == 0);
|
||||
assert(s.st_size == 6);
|
||||
assert(s.st_atime == 1200000000);
|
||||
assert(s.st_mtime == 1200000000);
|
||||
assert(s.st_ctime);
|
||||
#if EMSCRIPTEN
|
||||
assert(s.st_blksize == 4096);
|
||||
assert(s.st_blocks == 1);
|
||||
#endif
|
||||
|
||||
// fstat a file (should match file stat from above)
|
||||
memset(&s, 0, sizeof(s));
|
||||
err = fstat(open("folder/file", O_RDONLY), &s);
|
||||
assert(!err);
|
||||
assert(s.st_dev);
|
||||
assert(s.st_ino);
|
||||
assert(S_ISREG(s.st_mode));
|
||||
assert(s.st_nlink);
|
||||
assert(s.st_rdev == 0);
|
||||
assert(s.st_size == 6);
|
||||
assert(s.st_atime == 1200000000);
|
||||
assert(s.st_mtime == 1200000000);
|
||||
assert(s.st_ctime);
|
||||
#if EMSCRIPTEN
|
||||
assert(s.st_blksize == 4096);
|
||||
assert(s.st_blocks == 1);
|
||||
#endif
|
||||
|
||||
// stat a device
|
||||
memset(&s, 0, sizeof(s));
|
||||
err = stat("/dev/null", &s);
|
||||
assert(!err);
|
||||
assert(s.st_dev);
|
||||
assert(s.st_ino);
|
||||
assert(S_ISCHR(s.st_mode));
|
||||
assert(s.st_nlink);
|
||||
#if !USE_OLD_FS
|
||||
// old FS doesn't store proper device ids
|
||||
#ifndef __APPLE__
|
||||
// mac uses makedev(3, 2) for /dev/null
|
||||
assert(s.st_rdev == makedev(1, 3));
|
||||
#endif
|
||||
#endif
|
||||
assert(!s.st_size);
|
||||
assert(s.st_atime);
|
||||
assert(s.st_mtime);
|
||||
assert(s.st_ctime);
|
||||
#if EMSCRIPTEN
|
||||
assert(s.st_blksize == 4096);
|
||||
assert(s.st_blocks == 0);
|
||||
#endif
|
||||
|
||||
// stat a link (should match the file stat from above)
|
||||
memset(&s, 0, sizeof(s));
|
||||
err = stat("folder/file-link", &s);
|
||||
assert(!err);
|
||||
assert(s.st_dev);
|
||||
assert(s.st_ino);
|
||||
assert(S_ISREG(s.st_mode));
|
||||
assert(s.st_nlink);
|
||||
assert(s.st_rdev == 0);
|
||||
assert(s.st_size == 6);
|
||||
assert(s.st_atime == 1200000000);
|
||||
assert(s.st_mtime == 1200000000);
|
||||
assert(s.st_ctime);
|
||||
#if EMSCRIPTEN
|
||||
assert(s.st_blksize == 4096);
|
||||
assert(s.st_blocks == 1);
|
||||
#endif
|
||||
|
||||
// lstat a link (should NOT match the file stat from above)
|
||||
memset(&s, 0, sizeof(s));
|
||||
err = lstat("folder/file-link", &s);
|
||||
assert(!err);
|
||||
assert(s.st_dev);
|
||||
assert(s.st_ino);
|
||||
assert(S_ISLNK(s.st_mode));
|
||||
assert(s.st_nlink);
|
||||
assert(s.st_rdev == 0);
|
||||
assert(s.st_size == 4); // strlen("file")
|
||||
assert(s.st_atime != 1200000000); // should NOT match the utime call we did for dir/file
|
||||
assert(s.st_mtime != 1200000000);
|
||||
assert(s.st_ctime);
|
||||
#if EMSCRIPTEN
|
||||
assert(s.st_blksize == 4096);
|
||||
assert(s.st_blocks == 1);
|
||||
#endif
|
||||
|
||||
puts("success");
|
||||
}
|
||||
|
||||
int main() {
|
||||
atexit(cleanup);
|
||||
signal(SIGABRT, cleanup);
|
||||
setup();
|
||||
test();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Загрузка…
Ссылка в новой задаче