소스 검색

[add] lseek support for write

isundil 9 년 전
부모
커밋
8271643244
8개의 변경된 파일67개의 추가작업 그리고 14개의 파일을 삭제
  1. 14 0
      src/math.h
  2. 28 1
      src/ovr_syscall/ovr_lseek.c
  3. 1 0
      src/ovr_syscall/ovr_open.c
  4. 2 0
      src/ovr_syscall/ovr_write.c
  5. 6 0
      src/pathutil.c
  6. 3 1
      src/sandbox.h
  7. 1 1
      test/common.h
  8. 12 11
      test/write/main.c

+ 14 - 0
src/math.h

@@ -0,0 +1,14 @@
+#ifndef  MATH_H__
+# define MATH_H__
+
+# ifndef MAX
+#  define MAX(a, b) (a > b ? a : b)
+# endif
+# ifndef MIN
+#  define MIN(a, b) (a < b ? a : b)
+# endif
+
+
+
+#endif /*MATH_H__*/
+

+ 28 - 1
src/ovr_syscall/ovr_lseek.c

@@ -1,9 +1,36 @@
 #include "sandbox.h"
 #include "sllist.h"
+#include "math.h"
+
+/**
+ * Get new cursor position from beginning
+**/
+int getNewCursorOffset(t_fileinfo *file, t_fd *fd, off_t offsetRequest, int whence)
+{
+    if (whence == SEEK_CUR)
+        offsetRequest = offsetRequest + fd->offset;
+    else if (whence == SEEK_END)
+        offsetRequest = file->totalSize - offsetRequest;
+    return MAX(0, MIN(file->totalSize, offsetRequest));
+}
 
 int ovr_lseek(struct s_sandboxenv *env)
 {
-#warning TODO
+    int fd = (int) env->syscall_args[0];
+    off_t offset = (off_t) env->syscall_args[1];
+    int whence = (int) env->syscall_args[2];
+    t_fileinfo *file = get_fileinfo_fd(env, fd);
+    t_fd *_fd;
+    int tmp;
+
+    if (file == NULL)
+        return 0;
+    if ((tmp = sllist_find(file->fds, fileinfo_compare_tfd, (void *)env->syscall_args[0])) == -1)
+        return 0;
+    _fd = sllist_at(file->fds, tmp);
+    offset = getNewCursorOffset(file, _fd, offset, whence);
+    _fd->offset = offset;
+    registerSetResult(env, offset);
     return 0;
 }
 

+ 1 - 0
src/ovr_syscall/ovr_open.c

@@ -19,6 +19,7 @@ static t_fileinfo *open_local(struct s_sandboxenv *env, char *filename)
     result->local_fd = open(localpath, O_CREAT | O_RDWR, 0600);
     result->fds = sllist_create();
     result->modif_write = sllist_create();
+    result->totalSize = getFileSize(filename);
     sllist_pushback(env->filetable, result);
     free(localpath);
     return result;

+ 2 - 0
src/ovr_syscall/ovr_write.c

@@ -34,6 +34,8 @@ int ovr_write(struct s_sandboxenv *env)
     page->offset_start = _fd->offset;
     _fd->offset += result;
     sllist_pushback(file->modif_write, page);
+    if (file->totalSize < _fd->offset + result)
+        file->totalSize = _fd->offset + result;
     return 0;
 }
 

+ 6 - 0
src/pathutil.c

@@ -54,6 +54,12 @@ t_fileinfo *get_fileinfo_fd(const struct s_sandboxenv *env, const int fd)
     return sllist_at(env->filetable, i);
 }
 
+size_t getFileSize(const char *path)
+{
+    size_t size;
+    return file_exists_getFilesize(path, &size) ? size : 0;
+}
+
 int file_exists_getFilesize(const char*path, size_t *size)
 {
     struct stat buf;

+ 3 - 1
src/sandbox.h

@@ -29,7 +29,7 @@ typedef struct fd {
     int fd;
     int flags;
     int mod;
-    size_t offset;
+    off_t offset;
 } t_fd;
 
 typedef struct {
@@ -37,6 +37,7 @@ typedef struct {
     sl_list *fds;
     sl_list *modif_write;
     int local_fd;
+    size_t totalSize;
 } t_fileinfo;
 
 typedef struct {
@@ -96,6 +97,7 @@ void find_fullpath(char **path, int free);
 t_fileinfo *get_fileinfo(const struct s_sandboxenv *env, const char *filename);
 t_fileinfo *get_fileinfo_fd(const struct s_sandboxenv *env, const int fd);
 unsigned long long int hash_path(const char *filename);
+size_t getFileSize(const char *path);
 int file_exists(const char *filename);
 /**
  * Check if file exists, and return its size in size

+ 1 - 1
test/common.h

@@ -15,7 +15,7 @@
 
 #define _assertDiff(a, b) { REGISTER_TYPE _a = (REGISTER_TYPE) a; REGISTER_TYPE _b = (REGISTER_TYPE) b; if(_a == _b) { fprintf(stderr, "File %s, line %d: fail asserting %lld is different than %lld\n", __FILE__, __LINE__, (long long int) _a, (long long int )_b); return -1; }}
 
-#define _assertStrNEqual(a, b, c) { if (strncmp(a, b, c) != 0) { fprintf(stderr, "File %s, line %d: fail asserting %s match expected string %s\n", __FILE__, __LINE__, a, b); return -1; }}
+#define _assertStrNEqual(a, b, c) { if (strncmp(a, b, c) != 0) { fprintf(stderr, "File %s, line %d: fail asserting %.*s match expected string %.*s\n", __FILE__, __LINE__, c, a, c, b); return -1; }}
 
 void tests_init_env(struct s_sandboxenv *env, t_param *params);
 void tests_release_env(struct s_sandboxenv *env, t_param *params);

+ 12 - 11
test/write/main.c

@@ -118,19 +118,20 @@ int test_write(struct s_sandboxenv *env, int fd)
     _assertEqual(fakewrite(fd, "test", 4, env), 4);
     _assertEqual(stat("_test", &st), 0);
     _assertEqual(st.st_size, 0);
-#warning TODO
-    /*
-    _assertEqual(fakelseek(fd, 0, SEEK_SET, env), 0);
-    _assertEqual(fakeread(fd, buf, 4, env), 4);
-    _assertEqual(strcmp(buf, "test"), 0);
-    */
-    apply_fs(env);
+    //atm VBufer contains `test', file empty
+    fakelseek(fd, 2, SEEK_SET, env);
     _assertEqual(fakewrite(fd, "test", 4, env), 4);
     _assertEqual(stat("_test", &st), 0);
-    _assertEqual(st.st_size, 4);
+    _assertEqual(st.st_size, 0);
+    //atm VBufer contains `tetest', file still empty
+
+    apply_fs(env);
+    //VBuffer empty, file containing `tetest'
+    _assertEqual(stat("_test", &st), 0);
+    _assertEqual(st.st_size, 6);
     lfd = open("_test", O_RDONLY);
-    read(lfd, buf, 4);
-    _assertStrNEqual(buf, "test", 4);
+    read(lfd, buf, 6);
+    _assertStrNEqual(buf, "tetest", 4);
     return 0;
 }
 
@@ -141,6 +142,7 @@ int main()
     int fd;
     t_param params;
 
+    unlink("_test");
     tests_init_env(&env, &params);
 
     success &= !test_open(&env, &fd);
@@ -148,7 +150,6 @@ int main()
 
     fakeclose(fd, &env);
     tests_release_env(&env, &params);
-    unlink("_test");
     exit(success ? EXIT_SUCCESS: EXIT_FAILURE);
 }