this repo has no description
at trunk 171 lines 5.9 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include <fcntl.h> 3#include <sys/stat.h> 4#include <unistd.h> 5 6#include <cerrno> 7 8#include "builtins.h" 9#include "file.h" 10#include "module-builtins.h" 11#include "modules.h" 12#include "os.h" 13#include "runtime.h" 14#include "symbols.h" 15 16namespace py { 17 18RawObject FUNC(_os, access)(Thread*, Arguments args) { 19 CHECK(args.get(0).isStr(), "path must be str"); 20 unique_c_ptr<char> path(Str::cast(args.get(0)).toCStr()); 21 CHECK(args.get(1).isSmallInt(), "mode must be int"); 22 int result = OS::access(path.get(), SmallInt::cast(args.get(1)).value()); 23 return Bool::fromBool(result); 24} 25 26RawObject FUNC(_os, close)(Thread* thread, Arguments args) { 27 CHECK(args.get(0).isSmallInt(), "fd must be small int"); 28 word fd = SmallInt::cast(args.get(0)).value(); 29 int result = File::close(fd); 30 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 31 return NoneType::object(); 32} 33 34RawObject FUNC(_os, fstat_size)(Thread* thread, Arguments args) { 35 CHECK(args.get(0).isSmallInt(), "fd must be small int"); 36 word fd = SmallInt::cast(args.get(0)).value(); 37 int64_t result = File::size(fd); 38 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 39 return thread->runtime()->newInt(result); 40} 41 42RawObject FUNC(_os, ftruncate)(Thread* thread, Arguments args) { 43 CHECK(args.get(0).isSmallInt(), "fd must be small int"); 44 word fd = SmallInt::cast(args.get(0)).value(); 45 CHECK(args.get(1).isSmallInt(), "size must be small int"); 46 word size = SmallInt::cast(args.get(1)).value(); 47 int result = File::truncate(fd, size); 48 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 49 return NoneType::object(); 50} 51 52RawObject FUNC(_os, isatty)(Thread*, Arguments args) { 53 CHECK(args.get(0).isSmallInt(), "fd must be small int"); 54 word fd = SmallInt::cast(args.get(0)).value(); 55 int result = File::isatty(fd); 56 return Bool::fromBool(result < 0 ? false : result); 57} 58 59RawObject FUNC(_os, isdir)(Thread* thread, Arguments args) { 60 CHECK(args.get(0).isSmallInt(), "fd must be small int"); 61 word fd = SmallInt::cast(args.get(0)).value(); 62 int result = File::isDirectory(fd); 63 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 64 return Bool::fromBool(result); 65} 66 67RawObject FUNC(_os, lseek)(Thread* thread, Arguments args) { 68 CHECK(args.get(0).isSmallInt(), "fd must be small int"); 69 word fd = SmallInt::cast(args.get(0)).value(); 70 CHECK(args.get(1).isInt(), "offset must be int"); 71 word offset = Int::cast(args.get(1)).asWord(); 72 CHECK(args.get(2).isSmallInt(), "whence must be int"); 73 word whence = SmallInt::cast(args.get(2)).value(); 74 int64_t result = File::seek(fd, offset, whence); 75 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 76 return thread->runtime()->newInt(result); 77} 78 79RawObject FUNC(_os, open)(Thread* thread, Arguments args) { 80 HandleScope scope(thread); 81 Object flags_obj(&scope, args.get(1)); 82 CHECK(flags_obj.isSmallInt(), "flags must be small int"); 83 word flags = SmallInt::cast(*flags_obj).value(); 84 Object mode_obj(&scope, args.get(2)); 85 CHECK(mode_obj.isSmallInt(), "mode must be small int"); 86 word mode = SmallInt::cast(*mode_obj).value(); 87 Object dir_fd_obj(&scope, args.get(3)); 88 if (!dir_fd_obj.isNoneType()) { 89 UNIMPLEMENTED("_os_open with dir_fd"); 90 } 91 Object path_obj(&scope, args.get(0)); 92 int result; 93 if (path_obj.isStr()) { 94 unique_c_ptr<char> path_cstr(Str::cast(*path_obj).toCStr()); 95 result = File::open(path_cstr.get(), flags, mode); 96 } else if (path_obj.isBytes()) { 97 unique_c_ptr<char> path_cstr(Bytes::cast(*path_obj).toCStr()); 98 result = File::open(path_cstr.get(), flags, mode); 99 } else { 100 UNIMPLEMENTED("_os_open with non-str/bytes path"); 101 } 102 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 103 return SmallInt::fromWord(result); 104} 105 106static bool charInMode(const char c, const Str& mode) { 107 for (word i = 0; i < mode.length(); i++) { 108 if (c == mode.byteAt(i)) return true; 109 } 110 return false; 111} 112 113static word flagsFromMode(const Str& mode) { 114 word flags = 0; 115 bool readable = false, writable = false; 116 if (charInMode('x', mode)) { 117 writable = true; 118 flags = O_EXCL | O_CREAT; 119 } else if (charInMode('r', mode)) { 120 readable = true; 121 } else if (charInMode('w', mode)) { 122 writable = true; 123 flags = O_CREAT | O_TRUNC; 124 } else if (charInMode('a', mode)) { 125 writable = true; 126 flags = O_APPEND | O_CREAT; 127 } 128 if (charInMode('+', mode)) { 129 readable = writable = true; 130 } 131 if (readable && writable) { 132 flags |= O_RDWR; 133 } else if (readable) { 134 flags |= O_RDONLY; 135 } else { 136 flags |= O_WRONLY; 137 } 138 flags |= File::kBinaryFlag; 139 flags |= File::kNoInheritFlag; 140 return flags; 141} 142 143RawObject FUNC(_os, parse_mode)(Thread* thread, Arguments args) { 144 HandleScope scope(thread); 145 Str mode(&scope, args.get(0)); 146 return thread->runtime()->newInt(flagsFromMode(mode)); 147} 148 149RawObject FUNC(_os, read)(Thread* thread, Arguments args) { 150 HandleScope scope(thread); 151 Object fd_obj(&scope, args.get(0)); 152 CHECK(fd_obj.isSmallInt(), "fd must be small int"); 153 Object count_obj(&scope, args.get(1)); 154 CHECK(count_obj.isSmallInt(), "count must be small int"); 155 CHECK(!Int::cast(*count_obj).isNegative(), "count must be non-negative"); 156 size_t count = SmallInt::cast(*count_obj).value(); 157 std::unique_ptr<byte[]> buffer(new byte[count]); 158 int fd = SmallInt::cast(*fd_obj).value(); 159 ssize_t result = File::read(fd, buffer.get(), count); 160 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 161 return thread->runtime()->newBytesWithAll(View<byte>(buffer.get(), result)); 162} 163 164RawObject FUNC(_os, set_noinheritable)(Thread* thread, Arguments args) { 165 int fd = SmallInt::cast(args.get(0)).value(); 166 int result = File::setNoInheritable(fd); 167 if (result < 0) return thread->raiseOSErrorFromErrno(-result); 168 return NoneType::object(); 169} 170 171} // namespace py