Merge pull request #1394 from inolen/stat_tests

added lchmod, new tests, fixed for mknod return values
This commit is contained in:
Alon Zakai 2013-07-24 11:44:53 -07:00
Родитель f4cff4862c 9c52c8a191
Коммит e6e22495e2
10 изменённых файлов: 482 добавлений и 486 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}

153
tests/stat/test_chmod.c Normal file
Просмотреть файл

@ -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;
}

96
tests/stat/test_mknod.c Normal file
Просмотреть файл

@ -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;
}

167
tests/stat/test_stat.c Normal file
Просмотреть файл

@ -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;
}