| 1 | module os |
| 2 | |
| 3 | $if js_node { |
| 4 | #var $fs = require('fs'); |
| 5 | #var $path = require('path'); |
| 6 | #var tty = require('tty') |
| 7 | } |
| 8 | |
| 9 | pub const path_delimiter = get_path_delimiter() |
| 10 | pub const path_separator = get_path_separator() |
| 11 | pub const path_devnull = '/dev/null' // TODO |
| 12 | |
| 13 | pub const args = []string{} |
| 14 | |
| 15 | const executable_suffixes = [''] |
| 16 | |
| 17 | fn get_path_delimiter() string { |
| 18 | delimiter := ':' |
| 19 | $if js_node { |
| 20 | #delimiter.str = $path.delimiter |
| 21 | } |
| 22 | return delimiter |
| 23 | } |
| 24 | |
| 25 | fn get_path_separator() string { |
| 26 | separator := '/' |
| 27 | $if js_node { |
| 28 | #separator.str = $path.sep |
| 29 | } |
| 30 | return separator |
| 31 | } |
| 32 | |
| 33 | fn init() { |
| 34 | $if js_node { |
| 35 | #$process.argv.forEach(function(val,index) { os__args.arr[index] = new string(val); }) |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | // real_path returns the full absolute path for fpath, with all relative ../../, symlinks and so on resolved. |
| 40 | // See http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html |
| 41 | // Also https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html |
| 42 | // and https://insanecoding.blogspot.com/2007/11/implementing-realpath-in-c.html |
| 43 | // Note: this particular rabbit hole is *deep* ... |
| 44 | pub fn real_path(fpath string) string { |
| 45 | $if js_node { |
| 46 | mut res := '' |
| 47 | #res = new string( $fs.realpathSync(fpath)) |
| 48 | |
| 49 | return res |
| 50 | } $else { |
| 51 | return fpath |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | // flush will flush the stdout buffer. |
| 56 | pub fn flush() { |
| 57 | $if js_node { |
| 58 | #$process.stdout.write('') |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | pub fn getpid() int { |
| 63 | res := 0 |
| 64 | #res.val = $process.pid |
| 65 | |
| 66 | return res |
| 67 | } |
| 68 | |
| 69 | // chmod change file access attributes of `path` to `mode`. |
| 70 | // Octals like `0o600` can be used. |
| 71 | pub fn chmod(path string, mode int) ! { |
| 72 | $if js_node { |
| 73 | #try { |
| 74 | #$fs.chmodSync(''+path,mode.valueOf()) |
| 75 | #} catch (error) { |
| 76 | #return error_with_code(new string("chmod failed: " + error.message),new int(error.code)) |
| 77 | #} |
| 78 | } $else { |
| 79 | return error('os.chmod() is available only for NodeJS') |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | // chown changes the owner and group attributes of `path` to `owner` and `group`. |
| 84 | // Octals like `0o600` can be used. |
| 85 | pub fn chown(path string, owner int, group int) ! { |
| 86 | $if js_node { |
| 87 | #try { |
| 88 | #$fs.chownSync(''+path,owner.valueOf(),group.valueOf()) |
| 89 | #} catch (error) { return error_with_code(new string("chown failed: " + error.message),new int(error.code)) } |
| 90 | } $else { |
| 91 | return error('os.chown() is available only for NodeJS') |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | pub fn temp_dir() string { |
| 96 | mut res := '' |
| 97 | $if js_node { |
| 98 | #res = new string($os.tmpdir()) |
| 99 | } |
| 100 | return res |
| 101 | } |
| 102 | |
| 103 | pub fn home_dir() string { |
| 104 | mut res := '' |
| 105 | $if js_node { |
| 106 | #res = new string($os.homedir()) |
| 107 | } |
| 108 | return res |
| 109 | } |
| 110 | |
| 111 | // join_path returns a path as string from input string parameter(s). |
| 112 | pub fn join_path(base string, dirs ...string) string { |
| 113 | mut result := []string{} |
| 114 | result << base.trim_right('\\/') |
| 115 | for d in dirs { |
| 116 | result << d |
| 117 | } |
| 118 | mut path_sep := '' |
| 119 | #path_sep = $path.sep; |
| 120 | |
| 121 | res := result.join(path_sep) |
| 122 | return res |
| 123 | } |
| 124 | |
| 125 | pub fn join_path_single(base string, elem string) string { |
| 126 | // TODO: deprecate this |
| 127 | return join_path(base, elem) |
| 128 | } |
| 129 | |
| 130 | pub fn execute(cmd string) Result { |
| 131 | mut exit_code := 0 |
| 132 | mut stdout := '' |
| 133 | #let commands = cmd.str.split(' '); |
| 134 | #let output = $child_process.spawnSync(commands[0],commands.slice(1,commands.length)); |
| 135 | #exit_code = new int(output.status) |
| 136 | #stdout = new string(output.stdout + '') |
| 137 | |
| 138 | return Result{ |
| 139 | exit_code: exit_code |
| 140 | output: stdout |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | // exec starts the specified command with arguments, waits for it to complete, and returns its output. |
| 145 | pub fn exec(args []string) Result { |
| 146 | if args.len == 0 { |
| 147 | return Result{ |
| 148 | exit_code: -1 |
| 149 | output: 'exec requires at least one argument' |
| 150 | } |
| 151 | } |
| 152 | mut exit_code := 0 |
| 153 | mut stdout := '' |
| 154 | #let commands = args.arr.map((x) => x.valueOf() + ''); |
| 155 | #let output = $child_process.spawnSync(commands[0], commands.slice(1, commands.length)); |
| 156 | #exit_code = new int(output.status === null ? -1 : output.status) |
| 157 | #stdout = new string((output.stdout ? output.stdout + '' : '') + (output.stderr ? output.stderr + '' : '')) |
| 158 | |
| 159 | return Result{ |
| 160 | exit_code: exit_code |
| 161 | output: stdout |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | pub fn system(cmd string) int { |
| 166 | exit_code := 0 |
| 167 | #let commands = cmd.str.split(' '); |
| 168 | #exit_code.val = $child_process.execSync(commands[0],commands.slice(1,commands.length)); |
| 169 | |
| 170 | return exit_code |
| 171 | } |
| 172 | |
| 173 | pub fn is_atty(fd int) int { |
| 174 | res := 0 |
| 175 | #res.val = +tty.isatty(fd.val) |
| 176 | |
| 177 | return res |
| 178 | } |
| 179 | |
| 180 | pub fn glob(patterns ...string) ![]string { |
| 181 | panic('not yet implemented') |
| 182 | return error('not yet implemented') |
| 183 | } |
| 184 | |
| 185 | pub fn write_file_array(path string, buffer array) ! { |
| 186 | mut f := create(path)! |
| 187 | f.write_array(buffer)! |
| 188 | f.close() |
| 189 | } |
| 190 | |
| 191 | pub fn chdir(s string) ! { |
| 192 | #try { $process.chdir(s.str); } catch (e) { return error(new string('' + s)) } |
| 193 | } |
| 194 | |
| 195 | pub fn file_last_mod_unix(path string) int { |
| 196 | mtime := 0 |
| 197 | #mtime.val = Math.floor($fs.lstatSync(path.str).mtime.getTime() / 1000) |
| 198 | |
| 199 | return mtime |
| 200 | } |
| 201 | |
| 202 | pub fn ensure_folder_is_writable(path string) ! { |
| 203 | fpath := join_path(path, 'some_newfile') |
| 204 | #try { $fs.writeFileSync(fpath); $fs.unlinkSync(fpath) } catch(e) { return error(new string('could not write to ' + path)) } |
| 205 | |
| 206 | _ := fpath |
| 207 | } |
| 208 | |