* SysOpen (path, flags) - Opens file at specified path with flags * path - Path of file * flags - flags of opened file descriptor * * On success: return file descriptor * On failure: return -1 */
| 295 | * On failure: return -1 |
| 296 | */ |
| 297 | long SysOpen(regs64_t* r){ |
| 298 | char* filepath = (char*)kmalloc(strlen((char*)SC_ARG0(r)) + 1); |
| 299 | strcpy(filepath, (char*)SC_ARG0(r)); |
| 300 | FsNode* root = fs::GetRoot(); |
| 301 | |
| 302 | uint64_t flags = SC_ARG1(r); |
| 303 | |
| 304 | process_t* proc = Scheduler::GetCurrentProcess(); |
| 305 | |
| 306 | //Log::Info("Opening: %s", filepath); |
| 307 | long fd; |
| 308 | if(strcmp(filepath,"/") == 0){ |
| 309 | fd = proc->fileDescriptors.get_length(); |
| 310 | proc->fileDescriptors.add_back(fs::Open(root, 0)); |
| 311 | return fd; |
| 312 | } |
| 313 | |
| 314 | open: |
| 315 | FsNode* node = fs::ResolvePath(filepath, proc->workingDir, !(flags & O_NOFOLLOW)); |
| 316 | |
| 317 | if(!node){ |
| 318 | if(flags & O_CREAT){ |
| 319 | FsNode* parent = fs::ResolveParent(filepath, proc->workingDir); |
| 320 | char* basename = fs::BaseName(filepath); |
| 321 | |
| 322 | Log::Info("sys_open: Creating %s", basename); |
| 323 | |
| 324 | if(!parent) { |
| 325 | Log::Warning("sys_open: Could not resolve parent directory of new file %s", basename); |
| 326 | return -ENOENT; |
| 327 | } |
| 328 | |
| 329 | DirectoryEntry ent; |
| 330 | strcpy(ent.name, basename); |
| 331 | parent->Create(&ent, flags); |
| 332 | |
| 333 | kfree(basename); |
| 334 | |
| 335 | flags &= ~O_CREAT; |
| 336 | goto open; |
| 337 | } else { |
| 338 | Log::Warning("sys_open: Failed to open file %s", filepath); |
| 339 | return -ENOENT; |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | if(flags & O_DIRECTORY && ((node->flags & FS_NODE_TYPE) != FS_NODE_DIRECTORY)){ |
| 344 | return -ENOTDIR; |
| 345 | } |
| 346 | |
| 347 | if(flags & O_TRUNC && ((flags & O_ACCESS) == O_RDWR || (flags & O_ACCESS) == O_WRONLY)){ |
| 348 | node->Truncate(0); |
| 349 | } |
| 350 | |
| 351 | fs_fd_t* handle = fs::Open(node, SC_ARG1(r)); |
| 352 | |
| 353 | if(!handle){ |
| 354 | Log::Warning("SysOpen: Error retrieving file handle for node. Dangling symlink?"); |
nothing calls this directly
no test coverage detected