aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cases/i32_mem.ll23
-rw-r--r--tests/cases/i32_mem.txt2
-rw-r--r--tests/cases/zeroembedded.ll7
-rw-r--r--tests/glgetattachedshaders.c93
-rwxr-xr-xtests/runner.py76
-rw-r--r--tests/sdl_audio.c29
-rw-r--r--tests/stat/output.txt202
-rw-r--r--tests/stat/src.c242
-rw-r--r--tests/stat/test_chmod.c153
-rw-r--r--tests/stat/test_mknod.c96
-rw-r--r--tests/stat/test_stat.c167
11 files changed, 623 insertions, 467 deletions
diff --git a/tests/cases/i32_mem.ll b/tests/cases/i32_mem.ll
new file mode 100644
index 00000000..e50014ca
--- /dev/null
+++ b/tests/cases/i32_mem.ll
@@ -0,0 +1,23 @@
+; ModuleID = 'tests/hello_world.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+@.str = private unnamed_addr constant [15 x i8] c".%x.\0A\00", align 1 ; [#uses=1 type=[5 x i8]*]
+
+define i32 @main() {
+entry:
+ %mem = alloca i32
+ store i32 4279383126, i32* %mem
+ %i24 = bitcast i32* %mem to i24*
+ %load = load i24* %i24, align 4
+ %load32 = zext i24 %load to i32
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %load32)
+ %val_24 = trunc i32 4041265344 to i24
+ store i24 %val_24, i24* %i24, align 4
+ %load32b = load i32* %mem, align 4
+ %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %load32b)
+ ret i32 1
+}
+
+; [#uses=1]
+declare i32 @printf(i8*, ...)
diff --git a/tests/cases/i32_mem.txt b/tests/cases/i32_mem.txt
new file mode 100644
index 00000000..683e58e2
--- /dev/null
+++ b/tests/cases/i32_mem.txt
@@ -0,0 +1,2 @@
+.123456.
+.ffe0d0c0.
diff --git a/tests/cases/zeroembedded.ll b/tests/cases/zeroembedded.ll
index c1ffa212..6a4f6073 100644
--- a/tests/cases/zeroembedded.ll
+++ b/tests/cases/zeroembedded.ll
@@ -2,15 +2,22 @@
%struct.pypy_str = type { i32, [0 x i8] }
%struct.pypy_strval = type { i32, [13 x i8] }
+%union.pypy_array3_len0u = type { %struct.pypy_array3_len0 }
+%struct.pypy_array3_len0 = type { i32, i32, [0 x i8] }
+
@pypy_g_strval = global %struct.pypy_strval { i32 13, [13 x i8] c"hello world\0A\00" }
+@pypy_g_strval2 = global %struct.pypy_array3_len0 { i32 13, i32 111, [0 x i8] c"" }
declare i32 @printf(i8*, ...)
define i32 @main(i32 %argc, i8** nocapture %argv) {
+ %waka = alloca %struct.pypy_array3_len0
%1 = bitcast %struct.pypy_strval* @pypy_g_strval to %struct.pypy_str*
%2 = getelementptr inbounds %struct.pypy_str* %1, i32 1
%3 = bitcast %struct.pypy_str* %2 to i8*
call i32 (i8*, ...)* @printf(i8* %3)
+ %unneeded = bitcast %struct.pypy_str* %2 to %struct.pypy_array3_len0*
+ call i32 (i8*, ...)* @printf(i8* %3, %struct.pypy_array3_len0* %unneeded)
ret i32 0
}
diff --git a/tests/glgetattachedshaders.c b/tests/glgetattachedshaders.c
new file mode 100644
index 00000000..303e0f92
--- /dev/null
+++ b/tests/glgetattachedshaders.c
@@ -0,0 +1,93 @@
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void die(const char *msg)
+{
+ printf("%s\n", msg);
+ abort();
+}
+
+static void create_context(void)
+{
+ EGLint num_config;
+ EGLContext g_egl_ctx;
+ EGLDisplay g_egl_dpy;
+ EGLConfig g_config;
+
+ static const EGLint attribute_list[] =
+ {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_NONE
+ };
+
+ static const EGLint context_attributes[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!g_egl_dpy)
+ die("failed to create display");
+
+ if (!eglInitialize(g_egl_dpy, NULL, NULL))
+ die("failed to initialize egl");
+
+ if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config))
+ die("failed to choose config");
+
+ g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes);
+ if (!g_egl_ctx)
+ die("failed to create context");
+}
+
+int main(int argc, char *argv[])
+{
+ unsigned i;
+
+ create_context();
+
+ GLuint prog = glCreateProgram();
+ if (glGetError())
+ die("failed to create program");
+
+ GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
+ if (glGetError())
+ die("failed to create vertex shader");
+ glAttachShader(prog, vertex);
+
+ GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
+ if (glGetError())
+ die("failed to create fragment shader");
+ glAttachShader(prog, fragment);
+
+ GLuint shaders[2];
+ GLsizei count;
+
+ glGetAttachedShaders(prog, 2, &count, shaders);
+ if (glGetError())
+ die("failed to get attached shaders");
+ if (count != 2)
+ die("unknown number of shaders returned");
+ if (shaders[0] == shaders[1])
+ die("returned identical shaders");
+
+ for (i = 0; i < count; i++)
+ {
+ if (shaders[i] == 0)
+ die("returned 0");
+ if (shaders[i] != vertex && shaders[i] != fragment)
+ die("unknown shader returned");
+ }
+
+ int result = 1;
+ REPORT_RESULT();
+
+ return 0;
+}
diff --git a/tests/runner.py b/tests/runner.py
index ad8481cc..4a9bf623 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2969,6 +2969,37 @@ back
self.emcc_args.pop() ; self.emcc_args.pop() # disable closure to work around a closure bug
self.do_run(src, 'Throw...Construct...Catched...Destruct...Throw...Construct...Copy...Catched...Destruct...Destruct...')
+ def test_exception_2(self):
+ if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly')
+ Settings.DISABLE_EXCEPTION_CATCHING = 0
+ src = r'''
+ #include <stdexcept>
+ #include <stdio.h>
+
+ typedef void (*FuncPtr)();
+
+ void ThrowException()
+ {
+ throw std::runtime_error("catch me!");
+ }
+
+ FuncPtr ptr = ThrowException;
+
+ int main()
+ {
+ try
+ {
+ ptr();
+ }
+ catch(...)
+ {
+ printf("Exception caught successfully!\n");
+ }
+ return 0;
+ }
+ '''
+ self.do_run(src, 'Exception caught successfully!')
+
def test_white_list_exception(self):
Settings.DISABLE_EXCEPTION_CATCHING = 2
Settings.EXCEPTION_CATCHING_WHITELIST = ["__Z12somefunctionv"]
@@ -6963,11 +6994,12 @@ Pass: 0.000012 0.000012''')
def test_sscanf_6(self):
src = r'''
#include <stdio.h>
-
+ #include <string.h>
int main()
{
char *date = "18.07.2013w";
char c[10];
+ memset(c, 0, 10);
int y, m, d, i;
i = sscanf(date, "%d.%d.%4d%c", &d, &m, &y, c);
printf("date: %s; day %2d, month %2d, year %4d, extra: %c, %d\n", date, d, m, y, c[0], i);
@@ -7173,23 +7205,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 = '''
@@ -11030,7 +11058,7 @@ f.close()
if size > 100: ret[curr] = size
return ret
- for outlining_limit in [1000, 2000, 5000, 0]:
+ for outlining_limit in [500, 1000, 2000, 5000, 0]:
Popen([PYTHON, EMCC, src] + libs + ['-o', 'test.js', '-O2', '-g3', '-s', 'OUTLINING_LIMIT=%d' % outlining_limit] + args).communicate()
assert os.path.exists('test.js')
shutil.copyfile('test.js', '%d_test.js' % outlining_limit)
@@ -11048,10 +11076,11 @@ f.close()
self.get_library('zlib', os.path.join('libz.a'), make_args=['libz.a']),
open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(),
{
+ 500: (340, 345), # too big, need if-else chain flattening
1000: (380, 390),
2000: (395, 410),
5000: (800, 1100),
- 0: (1500, 1800)
+ 0: (1500, 1800)
},
args=['-I' + path_from_root('tests', 'zlib')], suffix='c')
@@ -12969,11 +12998,13 @@ Press any key to continue.'''
def test_sdl_audio(self):
shutil.copyfile(path_from_root('tests', 'sounds', 'alarmvictory_1.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
shutil.copyfile(path_from_root('tests', 'sounds', 'alarmcreatemiltaryfoot_1.wav'), os.path.join(self.get_dir(), 'sound2.wav'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'), os.path.join(self.get_dir(), 'noise.ogg'))
+ shutil.copyfile(path_from_root('tests', 'sounds', 'the_entertainer.ogg'), os.path.join(self.get_dir(), 'the_entertainer.ogg'))
open(os.path.join(self.get_dir(), 'bad.ogg'), 'w').write('I claim to be audio, but am lying')
open(os.path.join(self.get_dir(), 'sdl_audio.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_audio.c')).read()))
# use closure to check for a possible bug with closure minifying away newer Audio() attributes
- Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate()
+ Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl_audio.c'), '--preload-file', 'sound.ogg', '--preload-file', 'sound2.wav', '--embed-file', 'the_entertainer.ogg', '--preload-file', 'noise.ogg', '--preload-file', 'bad.ogg', '-o', 'page.html', '-s', 'EXPORTED_FUNCTIONS=["_main", "_play", "_play2"]']).communicate()
self.run_browser('page.html', '', '/report_result?1')
def test_sdl_audio_mix_channels(self):
@@ -13339,6 +13370,9 @@ Press any key to continue.'''
def test_glshaderinfo(self):
self.btest('glshaderinfo.cpp', '1')
+ def test_glgetattachedshaders(self):
+ self.btest('glgetattachedshaders.c', '1')
+
def test_sdlglshader(self):
self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1'])
diff --git a/tests/sdl_audio.c b/tests/sdl_audio.c
index ae1b89e9..7373d220 100644
--- a/tests/sdl_audio.c
+++ b/tests/sdl_audio.c
@@ -1,11 +1,13 @@
#include <stdio.h>
+#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include <assert.h>
#include <emscripten.h>
+#include <sys/stat.h>
-Mix_Chunk *sound, *sound2;
-
+Mix_Chunk *sound, *sound2, *sound3;
+Mix_Music * music;
int play2();
int play() {
@@ -28,6 +30,9 @@ int play2() {
int channel2 = Mix_PlayChannel(-1, sound2, 0);
assert(channel2 == 1);
+ int channel3 = Mix_PlayChannel(-1, sound3, 0);
+ assert(channel3 == 2);
+ assert(Mix_PlayMusic(music, 1) == 0);
return channel2;
}
@@ -39,6 +44,26 @@ int main(int argc, char **argv) {
sound = Mix_LoadWAV("sound.ogg");
assert(sound);
+
+ {
+ struct stat info;
+ int result = stat("noise.ogg", &info);
+ char * bytes = malloc( info.st_size );
+ FILE * f = fopen( "noise.ogg", "rb" );
+ fread( bytes, 1, info.st_size, f );
+ fclose(f);
+
+ SDL_RWops * ops = SDL_RWFromConstMem(bytes, info.st_size);
+ sound3 = Mix_LoadWAV_RW(ops, 0);
+ SDL_FreeRW(ops);
+ free(bytes);
+ }
+
+ {
+ music = Mix_LoadMUS("the_entertainer.ogg");
+ }
+
+
sound2 = Mix_LoadWAV("sound2.wav");
assert(sound);
diff --git a/tests/stat/output.txt b/tests/stat/output.txt
deleted file mode 100644
index 1e6ae74e..00000000
--- a/tests/stat/output.txt
+++ /dev/null
@@ -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
diff --git a/tests/stat/src.c b/tests/stat/src.c
deleted file mode 100644
index dc5a0198..00000000
--- a/tests/stat/src.c
+++ /dev/null
@@ -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;
-}
diff --git a/tests/stat/test_chmod.c b/tests/stat/test_chmod.c
new file mode 100644
index 00000000..94e6c12b
--- /dev/null
+++ b/tests/stat/test_chmod.c
@@ -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;
+} \ No newline at end of file
diff --git a/tests/stat/test_mknod.c b/tests/stat/test_mknod.c
new file mode 100644
index 00000000..4cff57d9
--- /dev/null
+++ b/tests/stat/test_mknod.c
@@ -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();