AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
sys_file.c
Go to the documentation of this file.
1
10
11#include "syscalls.h"
12
18static int at_uio(int dirfd, const char *path, struct uio *uio)
19{
21
22 if (dirfd == AT_FDCWD || *path == '/')
23 return 0;
24
25 struct file *file = fd_file(dirfd);
26
27 if (!file)
28 return -EBADF;
29
30 /* start from the directory itself (the call holds the file, so its
31 * vnode stays) */
32 if ((file->flags & FILE_SOCKET) || !S_ISDIR(file->vnode->mode))
33 return -ENOTDIR;
34
35 uio->cwd = file->vnode;
36 return 0;
37}
38
42static int at_path(int dirfd, const char *upath, char **path, struct uio *uio)
43{
44 int ret;
45
46 if ((ret = upath_get(upath, path)))
47 return ret;
48
49 if ((ret = at_uio(dirfd, *path, uio))) {
50 kfree(*path);
51 *path = NULL;
52 }
53
54 return ret;
55}
56
60static int at_lookup(int dirfd, const char *upath, int flags, struct uio *uio, struct vnode **vnode)
61{
62 char *path;
63 int ret;
64
65 if ((ret = upath_get(upath, &path)))
66 return ret;
67
68 if (!(ret = at_uio(dirfd, path, uio))) {
69 if (flags & AT_SYMLINK_NOFOLLOW)
70 uio->flags |= O_NOFOLLOW;
71
72 ret = vfs_lookup(path, uio, vnode);
73 }
74
75 kfree(path);
76 return ret;
77}
78
86long sys_close(int fildes)
87{
88 syscall_log(LOG_DEBUG, "close(fildes=%d)\n", fildes);
89
90 /* the descriptor goes now, the open file once nothing else refers to
91 * it (another descriptor, or a call using it) */
92 return proc_fd_close(curproc, fildes);
93}
94
103long sys_fstat(int fildes, struct aquila_stat *buf)
104{
105 syscall_log(LOG_DEBUG, "fstat(fildes=%d, buf=%p)\n", fildes, buf);
106
107 struct file *file = fd_file(fildes);
108
109 if (!file) {
110 return -EBADF;
111 }
112
113 struct aquila_stat st;
114 memset(&st, 0, sizeof(st));
115 int ret = 0;
116
117 /* a socket has no vnode: only its type is reported */
118 if (file->flags & FILE_SOCKET)
119 st.st_mode = S_IFSOCK;
120 else
121 ret = vfs_stat(file->vnode, &st);
122
123 if (!ret)
124 ret = copyout(buf, &st, sizeof(st));
125
126 return ret;
127}
128
137long sys_isatty(int fildes)
138{
139 syscall_log(LOG_DEBUG, "isatty(fildes=%d)\n", fildes);
140
141 struct file *file = fd_file(fildes);
142
143 if (!file) {
144 return -EBADF;
145 }
146
147 /* only character devices can be terminals */
148 if ((file->flags & FILE_SOCKET) || !S_ISCHR(file->vnode->mode)) {
149 return -ENOTTY;
150 }
151
152 return 1;
153}
154
157static int do_linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
158{
159 char *opath = NULL, *npath = NULL;
160 struct uio ouio, nuio;
161 int ret;
162
163 if (flags & ~AT_SYMLINK_FOLLOW)
164 return -EINVAL;
165
166 if (!(ret = at_path(olddirfd, oldpath, &opath, &ouio)) &&
167 !(ret = at_path(newdirfd, newpath, &npath, &nuio))) {
168 /* link the symbolic link itself, not what it points to */
169 if (!(flags & AT_SYMLINK_FOLLOW))
170 ouio.flags = O_NOFOLLOW;
171
172 ret = vfs_link(opath, &ouio, npath, &nuio);
173 }
174
175 kfree(opath);
176 kfree(npath);
177 return ret;
178}
179
188long sys_link(const char *oldpath, const char *newpath)
189{
190 syscall_log(LOG_DEBUG, "link(oldpath=%p, newpath=%p)\n", oldpath, newpath);
191 return do_linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
192}
193
205long sys_linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
206{
207 syscall_log(LOG_DEBUG, "linkat(olddirfd=%d, oldpath=%p, newdirfd=%d, newpath=%p, flags=%x)\n",
208 olddirfd, oldpath, newdirfd, newpath, flags);
209 return do_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
210}
211
221long sys_lseek(int fildes, off_t offset, int whence)
222{
223 syscall_log(LOG_DEBUG, "lseek(fildes=%d, offset=%ld, whence=%d)\n",
224 fildes, (int64_t) offset, whence);
225
226 struct file *file = fd_file(fildes);
227
228 if (!file) {
229 return -EBADF;
230 }
231
232 if (file->flags & FILE_SOCKET) {
233 return -ESPIPE;
234 }
235
236 /* keep the new offset whole: an int would cut one past 2 GiB */
237 off_t ret = vfs_file_lseek(file, offset, whence);
238 return ret;
239}
240
248static int creat_path(const char *path, struct uio *uio, char **ref)
249{
250 struct uio nofollow = *uio;
251 nofollow.flags |= O_NOFOLLOW;
252
253 char *cur = NULL;
254 *ref = NULL;
255
256 for (int depth = 0; depth < 8; ++depth) {
257 const char *p = cur ? cur : path;
258 struct vnode *vnode = NULL;
259
260 if (vfs_lookup(p, &nofollow, &vnode)) {
261 *ref = cur;
262 return 0;
263 }
264
265 int link = S_ISLNK(vnode->mode);
267
268 if (!link) {
269 kfree(cur);
270 return -EEXIST;
271 }
272
273 char target[256];
274 ssize_t len = vfs_readlink(p, &nofollow, target, sizeof(target) - 1);
275
276 if (len < 0) {
277 kfree(cur);
278 return len;
279 }
280
281 target[len] = '\0';
282
283 /* a relative target is relative to the link's directory */
284 size_t dirlen = 0;
285
286 if (target[0] != '/')
287 for (size_t i = 0; p[i]; ++i)
288 if (p[i] == '/')
289 dirlen = i + 1;
290
291 char *next = kmalloc(dirlen + len + 1, &M_BUFFER, 0);
292
293 if (!next) {
294 kfree(cur);
295 return -ENOMEM;
296 }
297
298 memcpy(next, p, dirlen);
299 memcpy(next + dirlen, target, len + 1);
300
301 kfree(cur);
302 cur = next;
303 }
304
305 kfree(cur);
306 return -ELOOP;
307}
308
311static int do_openat(int dirfd, const char *upath, int oflags, mode_t mode)
312{
313 struct uio uio;
314 char *path;
315 int ret;
316
317 if ((ret = upath_get(upath, &path)))
318 return ret;
319
320 if ((ret = at_uio(dirfd, path, &uio))) {
321 kfree(path);
322 return ret;
323 }
324
325 int fd = proc_fd_get(curproc);
326
327 if (fd == -1) { /* every descriptor is in use */
328 kfree(path);
329 return -EMFILE;
330 }
331
332 struct vnode *vnode = NULL;
333 struct file *file = NULL;
334 int excl = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
335 int created = 0;
336
337 uio.flags = oflags;
338
339 /* O_EXCL never creates through a symbolic link */
340 if (excl)
341 uio.flags |= O_NOFOLLOW;
342
343 ret = vfs_lookup(path, &uio, &vnode);
344
345 if (!ret && excl) {
346 ret = -EEXIST;
347 goto done;
348 }
349
350 if (ret == -ENOENT && (oflags & O_CREAT)) {
351 /* through a dangling symbolic link, create what it points to */
352 char *target = NULL;
353
354 if (!excl && (ret = creat_path(path, &uio, &target)))
355 goto done;
356
357 ret = vfs_creat(target ? target : path, mode & 07777, &uio, &vnode);
358 kfree(target);
359
360 if (ret)
361 goto done;
362
363 created = 1;
364 }
365
366 if (ret)
367 goto done;
368
369 /* with O_NOFOLLOW, the lookup stops at a final symbolic link */
370 if (S_ISLNK(vnode->mode)) {
371 ret = -ELOOP;
372 goto done;
373 }
374
375 if ((oflags & O_DIRECTORY) && !S_ISDIR(vnode->mode)) {
376 ret = -ENOTDIR;
377 goto done;
378 }
379
380 /* the open file; if anything fails before it is open, it is freed,
381 * not closed */
382 if (!(file = file_new())) {
383 ret = -ENOMEM;
384 goto done;
385 }
386
387 file->vnode = vnode;
388 file->flags = oflags & ~O_CLOEXEC;
389
390 /* the creator may open the file, whatever permissions it gave it */
391 if (!created && (ret = vfs_perms_check(file, &uio)))
392 goto done;
393
394 if ((ret = vfs_file_open(file)))
395 goto done;
396
397 proc_fd_install(curproc, fd, file, (oflags & O_CLOEXEC) ? FD_CLOEXEC : 0);
398 ret = fd;
399
400done:
401 if (ret < 0) {
403 kfree(file);
404
405 if (vnode)
407 }
408
409 kfree(path);
410 return ret;
411}
412
424long sys_open(const char *path, int oflags, mode_t mode)
425{
426 syscall_log(LOG_DEBUG, "open(path=%p, oflags=0x%x, mode=0x%x)\n", path, oflags, mode);
427 return do_openat(AT_FDCWD, path, oflags, mode);
428}
429
439long sys_openat(int dirfd, const char *path, int oflags, mode_t mode)
440{
441 syscall_log(LOG_DEBUG, "openat(dirfd=%d, path=%p, oflags=0x%x, mode=0x%x)\n", dirfd, path, oflags, mode);
442 return do_openat(dirfd, path, oflags, mode);
443}
444
454long sys_read(int fildes, void *buf, size_t nbytes)
455{
456 syscall_log(LOG_DEBUG, "read(fd=%d, buf=%p, count=%d)\n", fildes, buf, nbytes);
457
458 struct file *file = fd_file(fildes);
459
460 if (!file) {
461 return -EBADF;
462 }
463
464 if (uaccess_check(buf, nbytes)) {
465 return -EFAULT;
466 }
467
468 struct iobuf io;
469 iobuf_init(&io, buf, nbytes, 1);
470
471 ssize_t ret = vfs_file_read(file, &io);
472 return ret;
473}
474
477static int do_fstatat(int dirfd, const char *path, struct aquila_stat *buf, int flags)
478{
479 struct vnode *vnode = NULL;
480 struct uio uio;
481 int ret;
482
483 if (flags & ~AT_SYMLINK_NOFOLLOW)
484 return -EINVAL;
485
486 if ((ret = at_lookup(dirfd, path, flags, &uio, &vnode)))
487 return ret;
488
489 struct aquila_stat st;
490 memset(&st, 0, sizeof(st));
491
492 ret = vfs_stat(vnode, &st);
494 return ret ? ret : copyout(buf, &st, sizeof(st));
495}
496
504long sys_stat(const char *path, struct aquila_stat *buf)
505{
506 syscall_log(LOG_DEBUG, "stat(path=%p, buf=%p)\n", path, buf);
507 return do_fstatat(AT_FDCWD, path, buf, 0);
508}
509
520long sys_fstatat(int dirfd, const char *path, struct aquila_stat *buf, int flags)
521{
522 syscall_log(LOG_DEBUG, "fstatat(dirfd=%d, path=%p, buf=%p, flags=%x)\n", dirfd, path, buf, flags);
523 return do_fstatat(dirfd, path, buf, flags);
524}
525
528static int do_unlinkat(int dirfd, const char *upath, int flags)
529{
530 struct uio uio;
531 char *path;
532 int ret;
533
534 if (flags & ~AT_REMOVEDIR)
535 return -EINVAL;
536
537 if ((ret = upath_get(upath, &path)))
538 return ret;
539
540 if (!(ret = at_uio(dirfd, path, &uio)))
541 ret = (flags & AT_REMOVEDIR) ? vfs_rmdir(path, &uio) : vfs_unlink(path, &uio);
542
543 kfree(path);
544 return ret;
545}
546
553long sys_unlink(const char *path)
554{
555 syscall_log(LOG_DEBUG, "unlink(path=%p)\n", path);
556 return do_unlinkat(AT_FDCWD, path, 0);
557}
558
568long sys_unlinkat(int dirfd, const char *path, int flags)
569{
570 syscall_log(LOG_DEBUG, "unlinkat(dirfd=%d, path=%p, flags=%x)\n", dirfd, path, flags);
571 return do_unlinkat(dirfd, path, flags);
572}
573
584long sys_write(int fd, void *buf, size_t nbytes)
585{
586 syscall_log(LOG_DEBUG, "write(fd=%d, buf=%p, nbytes=%d)\n", fd, buf, nbytes);
587
588 struct file *file = fd_file(fd);
589
590 if (!file) {
591 return -EBADF;
592 }
593
594 if (uaccess_check(buf, nbytes)) {
595 return -EFAULT;
596 }
597
598 struct iobuf io;
599 iobuf_init(&io, buf, nbytes, 1);
600
601 ssize_t ret = vfs_file_write(file, &io);
602
603 /* writing to a pipe that no one reads raises SIGPIPE; the write fails
604 * with EPIPE if the signal is caught or ignored (it is delivered on
605 * the way back to user mode, after the result is set) */
606 if (ret == -EPIPE)
607 signal_proc_send(curproc, SIGPIPE);
608
609 return ret;
610}
611
622long sys_ioctl(int fd, int request, void *argp)
623{
624 syscall_log(LOG_DEBUG, "ioctl(fd=%d, request=0x%x, argp=%p)\n",
625 fd, request, argp);
626
627 struct file *file = fd_file(fd);
628
629 if (!file) {
630 return -EBADF;
631 }
632
633 /* FIONBIO works on any file: it sets O_NONBLOCK, as F_SETFL does */
634 if (request == FIONBIO) {
635 int on;
636
637 if (copyin(&on, argp, sizeof(on))) {
638 return -EFAULT;
639 }
640
641 if (on)
642 file->flags |= O_NONBLOCK;
643 else
644 file->flags &= ~O_NONBLOCK;
645
646 return 0;
647 }
648
649 /* argp is in user memory: the socket or the device copies what each
650 * request reads and writes */
651 if (file->flags & FILE_SOCKET) {
652 return socket_ioctl(file, request, argp);
653 }
654
655 int ret = vfs_file_ioctl(file, request, argp);
656 return ret;
657}
658
667long sys_readdir(int fd, struct dirent *dirent)
668{
669 syscall_log(LOG_DEBUG, "readdir(fd=%d, dirent=%p)\n", fd, dirent);
670
671 struct file *file = fd_file(fd);
672
673 if (!file) {
674 return -EBADF;
675 }
676
677 if (file->flags & FILE_SOCKET) {
678 return -ENOTDIR;
679 }
680
681 struct dirent d;
682 memset(&d, 0, sizeof(d));
683 int ret = vfs_file_readdir(file, &d);
684
685 /* the file systems don't report the entries' types yet */
686 if (ret > 0) {
687 d.d_type = DT_UNKNOWN;
688
689 if (copyout(dirent, &d, sizeof(d)))
690 ret = -EFAULT;
691 }
692
693 return ret;
694}
695
706long sys_mount(struct aquila_mount_args *args)
707{
708 if (curproc->uid != 0) {
709 return -EPERM;
710 }
711
712 struct aquila_mount_args a;
713
714 if (copyin(&a, args, sizeof(a))) {
715 return -EFAULT;
716 }
717
718 char *type = NULL, *dir = NULL;
719
720 /* every file system's mount data is {char *dev; char *opt;}: make the
721 * kernel's copy of it, and of its strings */
722 char *udata[2], *data[2] = {NULL, NULL};
723 int ret;
724
725 if ((ret = upath_get(a.type, &type)) || (ret = upath_get(a.dir, &dir)))
726 goto done;
727
728 if (a.data) {
729 if (copyin(udata, a.data, sizeof(udata))) {
730 ret = -EFAULT;
731 goto done;
732 }
733
734 for (int i = 0; i < 2; ++i)
735 if (udata[i] && (ret = upath_get(udata[i], &data[i])))
736 goto done;
737 }
738
739 syscall_log(LOG_DEBUG, "mount(type=%s, dir=%s, flags=%x, data=%p)\n",
740 type, dir, a.flags, a.data);
741
742 ret = vfs_mount(type, dir, a.flags, a.data ? data : NULL, &PROC_UIO(curproc));
743
744done:
745 kfree(type);
746 kfree(dir);
747 kfree(data[0]);
748 kfree(data[1]);
749 return ret;
750}
751
754static int do_mknodat(int dirfd, const char *upath, mode_t mode, dev_t dev)
755{
756 struct uio uio;
757 char *path;
758 int ret;
759
760 /* type 0 means a regular file */
761 if (!(mode & S_IFMT))
762 mode |= S_IFREG;
763
764 switch (mode & S_IFMT) {
765 case S_IFREG:
766 case S_IFDIR:
767 case S_IFIFO:
768 break;
769 case S_IFCHR:
770 case S_IFBLK:
771 /* only root may make device files: they give access to the
772 * device */
773 if (curproc->uid != 0)
774 return -EPERM;
775 break;
776 default:
777 return -EINVAL;
778 }
779
780 if ((ret = upath_get(upath, &path)))
781 return ret;
782
783 if (!(ret = at_uio(dirfd, path, &uio)))
784 ret = vfs_mknod(path, mode, dev, &uio, NULL);
785
786 kfree(path);
787 return ret;
788}
789
797long sys_mkdir(const char *path, mode_t mode)
798{
799 syscall_log(LOG_DEBUG, "mkdir(path=%p, mode=%x)\n", path, mode);
800 return do_mknodat(AT_FDCWD, path, S_IFDIR | (mode & 07777), 0);
801}
802
810long sys_pipe(int fd[2])
811{
812 syscall_log(LOG_DEBUG, "pipe(fd=%p)\n", fd);
813
814 if (uaccess_check(fd, 2 * sizeof(int))) {
815 return -EFAULT;
816 }
817
818 int err = 0;
819 int fd1 = -1, fd2 = -1;
820 int fds[2];
821 struct file *r = NULL, *w = NULL;
822
823 if ((fd1 = proc_fd_get(curproc)) == -1 || (fd2 = proc_fd_get(curproc)) == -1) {
824 err = -EMFILE;
825 goto error;
826 }
827
828 if (!(r = file_new()) || !(w = file_new())) {
829 err = -ENOMEM;
830 goto error;
831 }
832
833 if ((err = pipefs_pipe(r, w)))
834 goto error;
835
836 proc_fd_install(curproc, fd1, r, 0);
837 proc_fd_install(curproc, fd2, w, 0);
838
839 fds[0] = fd1;
840 fds[1] = fd2;
841
842 /* if the descriptors can't be written out, they are closed again */
843 if (copyout(fd, fds, sizeof(fds))) {
846 return -EFAULT;
847 }
848
849 return 0;
850
851error:
852 /* the files were never opened: there's nothing to close */
853 kfree(r);
854 kfree(w);
855
856 if (fd1 != -1)
858
859 if (fd2 != -1)
861
862 return err;
863}
864
876long sys_fcntl(int fd, int cmd, uintptr_t arg)
877{
878 syscall_log(LOG_DEBUG, "fcntl(fd=%d, cmd=%d, arg=0x%x)\n",
879 fd, cmd, arg);
880
881 struct file *file = fd_file(fd);
882
883 if (!file) {
884 return -EBADF;
885 }
886
887 /* file status flags that F_SETFL may change */
888 const int setfl = O_APPEND | O_NONBLOCK;
889 int dupfd = 0;
890
891 switch (cmd) {
892 case F_DUPFD:
893 case F_DUPFD_CLOEXEC:
894 if (arg >= FDS_COUNT) {
895 return -EINVAL;
896 }
897
898 /* the lowest free descriptor from arg on */
899 for (dupfd = arg; dupfd < FDS_COUNT; ++dupfd) {
900 if (!curproc->fds[dupfd].file)
901 break;
902 }
903
904 if (dupfd == FDS_COUNT) {
905 return -EMFILE;
906 }
907
908 /* the same open file: its offset and status flags are shared */
909 proc_fd_install(curproc, dupfd, file_ref(file), cmd == F_DUPFD_CLOEXEC ? FD_CLOEXEC : 0);
910
911 return dupfd;
912 case F_GETFD:
913 return curproc->fds[fd].flags;
914 case F_SETFD:
915 /* the descriptor's own flag */
916 curproc->fds[fd].flags = arg & FD_CLOEXEC;
917 return 0;
918 case F_GETFL:
919 return file->flags & ~FILE_SOCKET;
920 case F_SETFL:
921 /* the open file's flags: they affect every descriptor that
922 * refers to it */
923 file->flags = (file->flags & ~setfl) | ((int) arg & setfl);
924 return 0;
925 }
926
927 return -EINVAL;
928}
929
933static int cwd_set(struct vnode *vnode)
934{
935 int ret;
936
937 if (!S_ISDIR(vnode->mode))
938 return -ENOTDIR;
939
940 if ((ret = vfs_access(vnode, &PROC_UIO(curproc), VFS_X)))
941 return ret;
942
943 if (curproc->cwd)
944 vfs_close(curproc->cwd);
945
946 curproc->cwd = vnode;
947 return 0;
948}
949
956long sys_chdir(const char *upath)
957{
958 syscall_log(LOG_DEBUG, "chdir(path=%p)\n", upath);
959
960 char *path = NULL;
961 struct vnode *vnode = NULL;
962 int ret = upath_get(upath, &path);
963
964 if (!ret)
965 ret = vfs_lookup(path, &PROC_UIO(curproc), &vnode);
966
967 if (!ret && !(ret = cwd_set(vnode)))
968 vnode = NULL;
969
970 if (vnode)
972
973 kfree(path);
974 return ret;
975}
976
985long sys_getcwd(char *buf, size_t size)
986{
987 syscall_log(LOG_DEBUG, "getcwd(buf=%p, size=%d)\n", buf, size);
988
989 if (!size) {
990 return -EINVAL;
991 }
992
993 /* the path is made from the directory up: it isn't kept as a string */
995 char *path = kmalloc(size, &M_BUFFER, 0);
996 int ret;
997
998 if (!path) {
999 return -ENOMEM;
1000 }
1001
1002 if (!curproc->cwd)
1003 ret = size < 2 ? -ERANGE : (strcpy(path, "/"), 0);
1004 else
1005 ret = vfs_vnode_path(curproc->cwd, NULL, path, size);
1006
1007 if (!ret)
1008 ret = copyout(buf, path, strlen(path) + 1);
1009
1010 kfree(path);
1011 return ret;
1012}
1013
1023long sys_mknod(const char *path, uint32_t mode, uint32_t dev)
1024{
1025 syscall_log(LOG_DEBUG, "mknod(path=%p, mode=%x, dev=%x)\n", path, mode, dev);
1026 return do_mknodat(AT_FDCWD, path, mode, dev);
1027}
1028
1039long sys_mknodat(int dirfd, const char *path, uint32_t mode, uint32_t dev)
1040{
1041 syscall_log(LOG_DEBUG, "mknodat(dirfd=%d, path=%p, mode=%x, dev=%x)\n", dirfd, path, mode, dev);
1042 return do_mknodat(dirfd, path, mode, dev);
1043}
1044
1052long sys_lstat(const char *path, struct aquila_stat *buf)
1053{
1054 syscall_log(LOG_DEBUG, "lstat(path=%p, buf=%p)\n", path, buf);
1055 return do_fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
1056}
1057
1065long sys_ftruncate(int fildes, off_t len)
1066{
1067 syscall_log(LOG_DEBUG, "ftruncate(fildes=%d, len=%d)\n", fildes, len);
1068
1069 struct file *file = fd_file(fildes);
1070
1071 if (!file) {
1072 return -EBADF;
1073 }
1074
1075 /* the file must be open for writing */
1076 if (len < 0 || (file->flags & O_ACCMODE) == O_RDONLY) {
1077 return -EINVAL;
1078 }
1079
1080 return vfs_file_trunc(file, len);
1081}
1082
1090{
1091 syscall_log(LOG_DEBUG, "umask(mask=%d)\n", mask);
1092
1093 mode_t cur_mask = curproc->mask;
1094 curproc->mask = mask & 0777;
1095
1096 return cur_mask;
1097}
1098
1101static int do_fchmodat(int dirfd, const char *path, mode_t mode, int flags)
1102{
1103 struct vnode *vnode = NULL;
1104 struct uio uio;
1105 int ret;
1106
1107 /* symbolic links have no mode of their own */
1108 if (flags & AT_SYMLINK_NOFOLLOW)
1109 return -EOPNOTSUPP;
1110
1111 if (flags)
1112 return -EINVAL;
1113
1114 if ((ret = at_lookup(dirfd, path, flags, &uio, &vnode)))
1115 return ret;
1116
1117 ret = vfs_chmod(vnode, mode, &uio);
1119 return ret;
1120}
1121
1129long sys_chmod(const char *path, mode_t mode)
1130{
1131 syscall_log(LOG_DEBUG, "chmod(path=%p, mode=%o)\n", path, mode);
1132 return do_fchmodat(AT_FDCWD, path, mode, 0);
1133}
1134
1145long sys_fchmodat(int dirfd, const char *path, mode_t mode, int flags)
1146{
1147 syscall_log(LOG_DEBUG, "fchmodat(dirfd=%d, path=%p, mode=%o, flags=%x)\n", dirfd, path, mode, flags);
1148 return do_fchmodat(dirfd, path, mode, flags);
1149}
1150
1153static struct vnode *fd_vnode(int fd, int *err)
1154{
1155 struct file *file = fd_file(fd);
1156
1157 if (!file || (file->flags & FILE_SOCKET)) {
1158 *err = file ? -EINVAL : -EBADF;
1159 return NULL;
1160 }
1161
1162 return file->vnode;
1163}
1164
1172long sys_fchmod(int fd, mode_t mode)
1173{
1174 syscall_log(LOG_DEBUG, "fchmod(fd=%d, mode=%o)\n", fd, mode);
1175
1176 int ret = 0;
1177 struct vnode *vnode = fd_vnode(fd, &ret);
1178
1179 if (vnode)
1180 ret = vfs_chmod(vnode, mode, &PROC_UIO(curproc));
1181
1182 return ret;
1183}
1184
1185#define F_OK 0
1186#define X_OK 1
1187#define W_OK 2
1188#define R_OK 4
1189
1192static int do_faccessat(int dirfd, const char *path, int mode, int flags)
1193{
1194 struct vnode *vnode = NULL;
1195 struct uio uio;
1196 int ret;
1197
1198 /* there are no separate effective IDs, so AT_EACCESS changes nothing */
1199 if ((flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW)) || (mode & ~(R_OK | W_OK | X_OK)))
1200 return -EINVAL;
1201
1202 if ((ret = at_lookup(dirfd, path, flags, &uio, &vnode)))
1203 return ret;
1204
1205 int vmode = (mode & R_OK ? VFS_R : 0) | (mode & W_OK ? VFS_W : 0) | (mode & X_OK ? VFS_X : 0);
1206
1207 ret = vfs_access(vnode, &uio, vmode);
1209 return ret;
1210}
1211
1220long sys_access(const char *path, int mode)
1221{
1222 syscall_log(LOG_DEBUG, "access(path=%p, mode=%d)\n", path, mode);
1223 return do_faccessat(AT_FDCWD, path, mode, 0);
1224}
1225
1236long sys_faccessat(int dirfd, const char *path, int mode, int flags)
1237{
1238 syscall_log(LOG_DEBUG, "faccessat(dirfd=%d, path=%p, mode=%d, flags=%x)\n", dirfd, path, mode, flags);
1239 return do_faccessat(dirfd, path, mode, flags);
1240}
1241
1244static int do_fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags)
1245{
1246 struct vnode *vnode = NULL;
1247 struct uio uio;
1248 int ret;
1249
1250 if (flags & ~AT_SYMLINK_NOFOLLOW)
1251 return -EINVAL;
1252
1253 if ((ret = at_lookup(dirfd, path, flags, &uio, &vnode)))
1254 return ret;
1255
1256 ret = vfs_chown(vnode, owner, group, &uio);
1258 return ret;
1259}
1260
1269long sys_chown(const char *path, uid_t owner, gid_t group)
1270{
1271 syscall_log(LOG_DEBUG, "chown(path=%p, owner=%d, group=%d)\n", path, owner, group);
1272 return do_fchownat(AT_FDCWD, path, owner, group, 0);
1273}
1274
1286long sys_fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags)
1287{
1288 syscall_log(LOG_DEBUG, "fchownat(dirfd=%d, path=%p, owner=%d, group=%d, flags=%x)\n",
1289 dirfd, path, owner, group, flags);
1290 return do_fchownat(dirfd, path, owner, group, flags);
1291}
1292
1301long sys_fchown(int fd, uid_t owner, gid_t group)
1302{
1303 syscall_log(LOG_DEBUG, "fchown(fd=%d, owner=%d, group=%d)\n", fd, owner, group);
1304
1305 int ret = 0;
1306 struct vnode *vnode = fd_vnode(fd, &ret);
1307
1308 if (vnode)
1309 ret = vfs_chown(vnode, owner, group, &PROC_UIO(curproc));
1310
1311 return ret;
1312}
1313
1322long sys_lchown(const char *path, uid_t owner, gid_t group)
1323{
1324 syscall_log(LOG_DEBUG, "lchown(path=%p, owner=%d, group=%d)\n", path, owner, group);
1325 return do_fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW);
1326}
1327
1340long sys_utimensat(int dirfd, const char *path, const struct aquila_timespec times[2], int flags)
1341{
1342 syscall_log(LOG_DEBUG, "utimensat(dirfd=%d, path=%p, times=%p, flags=%x)\n", dirfd, path, times, flags);
1343
1344 struct vnode *vnode = NULL;
1345 struct uio uio = PROC_UIO(curproc);
1346 int ret = 0;
1347
1348 if (flags & ~AT_SYMLINK_NOFOLLOW) {
1349 ret = -EINVAL;
1350 goto done;
1351 }
1352
1353 struct aquila_timespec ktimes[2];
1354
1355 if (times && copyin(ktimes, times, sizeof(ktimes))) {
1356 ret = -EFAULT;
1357 goto done;
1358 }
1359
1360 if (!path) {
1361 if ((vnode = fd_vnode(dirfd, &ret)))
1362 ret = vfs_utimens(vnode, times ? ktimes : NULL, &uio);
1363
1364 goto done;
1365 }
1366
1367 if ((ret = at_lookup(dirfd, path, flags, &uio, &vnode)))
1368 goto done;
1369
1370 ret = vfs_utimens(vnode, times ? ktimes : NULL, &uio);
1372
1373done:
1374 return ret;
1375}
1376
1383long sys_rmdir(const char *path)
1384{
1385 syscall_log(LOG_DEBUG, "rmdir(path=%p)\n", path);
1386 return do_unlinkat(AT_FDCWD, path, AT_REMOVEDIR);
1387}
1388
1397long sys_symlinkat(const char *utarget, int dirfd, const char *upath)
1398{
1399 syscall_log(LOG_DEBUG, "symlinkat(target=%p, dirfd=%d, path=%p)\n", utarget, dirfd, upath);
1400
1401 char *target = NULL, *path = NULL;
1402 struct uio uio;
1403 int ret;
1404
1405 if (!(ret = upath_get(utarget, &target)) &&
1406 !(ret = upath_get(upath, &path)) &&
1407 !(ret = at_uio(dirfd, path, &uio)))
1408 ret = vfs_symlink(target, path, &uio);
1409
1410 kfree(target);
1411 kfree(path);
1412 return ret;
1413}
1414
1426long sys_readlinkat(int dirfd, const char *upath, char *buf, size_t size)
1427{
1428 syscall_log(LOG_DEBUG, "readlinkat(dirfd=%d, path=%p, buf=%p, size=%d)\n", dirfd, upath, buf, size);
1429
1430 /* read the target into a kernel buffer (it is a path, so no longer
1431 * than one), then copy it out */
1432 char *path = NULL, *target = NULL;
1433 struct uio uio;
1434 ssize_t ret;
1435
1436 if (uaccess_check(buf, size)) {
1437 return -EFAULT;
1438 }
1439
1440 if (!(ret = upath_get(upath, &path)) && !(ret = at_uio(dirfd, path, &uio))) {
1441 if (!(target = kmalloc(UPATH_MAX, &M_BUFFER, 0)))
1442 ret = -ENOMEM;
1443 else if ((ret = vfs_readlink(path, &uio, target, MIN(size, UPATH_MAX))) > 0 &&
1444 copyout(buf, target, ret))
1445 ret = -EFAULT;
1446 }
1447
1448 kfree(path);
1449 kfree(target);
1450 return ret;
1451}
1452
1464long sys_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath)
1465{
1466 syscall_log(LOG_DEBUG, "renameat(olddirfd=%d, oldpath=%p, newdirfd=%d, newpath=%p)\n",
1467 olddirfd, oldpath, newdirfd, newpath);
1468
1469 char *opath = NULL, *npath = NULL;
1470 struct uio ouio, nuio;
1471 int ret;
1472
1473 if (!(ret = at_path(olddirfd, oldpath, &opath, &ouio)) &&
1474 !(ret = at_path(newdirfd, newpath, &npath, &nuio)))
1475 ret = vfs_rename(opath, &ouio, npath, &nuio);
1476
1477 kfree(opath);
1478 kfree(npath);
1479 return ret;
1480}
1481
1490long sys_flock(int fd, int op)
1491{
1492 syscall_log(LOG_DEBUG, "flock(fd=%d, op=%d)\n", fd, op);
1493
1494 struct file *file = fd_file(fd);
1495
1496 if (!file) {
1497 return -EBADF;
1498 }
1499
1500 return vfs_file_flock(file, op);
1501}
1502
1508long sys_sync(void)
1509{
1510 syscall_log(LOG_DEBUG, "sync()\n");
1511
1512 /* writes go to the devices right away: only their caches are left */
1513 return kdev_sync();
1514}
1515
1524{
1525 syscall_log(LOG_DEBUG, "fchdir(fd=%d)\n", fd);
1526
1527 struct file *file = fd_file(fd);
1528 int ret;
1529
1530 if (!file) {
1531 ret = -EBADF;
1532 } else if (file->flags & FILE_SOCKET) {
1533 ret = -ENOTDIR;
1534 } else {
1535 /* the directory the descriptor refers to, however it was reached */
1536 file->vnode->ref++;
1537
1538 if ((ret = cwd_set(file->vnode)))
1539 vfs_close(file->vnode);
1540 }
1541
1542 return ret;
1543}
int vfs_chown(struct vnode *vnode, uid_t uid, gid_t gid, struct uio *uio)
Changes a vnode's owner and group.
Definition attr.c:68
int vfs_utimens(struct vnode *vnode, const struct aquila_timespec times[2], struct uio *uio)
Changes a vnode's access and modification times, for utimensat().
Definition attr.c:124
int vfs_chmod(struct vnode *vnode, mode_t mode, struct uio *uio)
Changes a vnode's permission bits.
Definition attr.c:38
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
Definition close.c:18
struct file * file_new(void)
Makes a new open file, with one reference.
Definition file.c:32
struct file * file_ref(struct file *file)
Adds a reference to an open file.
Definition file.c:48
int vfs_file_flock(struct file *file, int op)
Takes, changes or releases an open file's lock.
Definition flock.c:67
int vfs_file_open(struct file *file)
Opens a file whose vnode is set: a device's driver, a FIFO's pipe, or the filesystem opens it.
Definition fops.c:22
off_t vfs_file_lseek(struct file *file, off_t offset, int whence)
Moves an open file's offset.
Definition fops.c:136
ssize_t vfs_file_readdir(struct file *file, struct dirent *dirent)
Reads the next entry of an open directory.
Definition fops.c:162
int vfs_file_trunc(struct file *file, off_t len)
Changes the length of an open file.
Definition fops.c:213
ssize_t vfs_file_write(struct file *file, struct iobuf *io)
Writes to an open file, at its offset.
Definition fops.c:83
int vfs_file_ioctl(struct file *file, int request, void *argp)
Passes an ioctl() request to an open file's device or filesystem.
Definition fops.c:111
ssize_t vfs_file_read(struct file *file, struct iobuf *io)
Reads from an open file, at its offset.
Definition fops.c:52
#define FDS_COUNT
Definition config.h:46
#define MIN(a, b)
Definition system.h:11
void iobuf_init(struct iobuf *io, void *buf, size_t len, int user)
Sets up an iobuf for one buffer.
Definition iobuf.c:19
int kdev_sync(void)
Writes what the block cache holds that was written, and what the block devices hold in their write ca...
Definition kdev.c:587
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition libc.c:23
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
Definition libc.c:11
int vfs_lookup(const char *path, struct uio *uio, struct vnode **ref)
Finds the vnode a path names.
Definition lookup.c:349
int vfs_vnode_path(struct vnode *vnode, struct vnode *root, char *buf, size_t size)
Computes a vnode's path, for getcwd() and /proc/mounts: it goes up through .., and finds each directo...
Definition lookup.c:532
int vfs_mknod(const char *path, mode_t mode, dev_t dev, struct uio *uio, struct vnode **ref)
Makes a node at a path.
Definition mknod.c:21
int vfs_creat(const char *path, mode_t mode, struct uio *uio, struct vnode **ref)
Makes a regular file at a path.
Definition mknod.c:69
int vfs_mount(const char *type, const char *dir, int flags, void *data, struct uio *uio)
Mounts a filesystem of a type on a directory, for mount().
Definition mount.c:29
int pipefs_pipe(struct file *read, struct file *write)
Makes an anonymous pipe, for pipe(): one open file for each end.
Definition pipe.c:199
#define LOG_DEBUG
Definition printk.h:19
int proc_fd_get(struct proc *proc)
Reserves the lowest free descriptor of a process, while a system call sets it up: no other thread tak...
Definition proc.c:514
int proc_fd_close(struct proc *proc, int fd)
Closes a descriptor: it is free again, and its reference to the open file is dropped.
Definition proc.c:578
void proc_fd_release(struct proc *proc, int fd)
Frees a reserved descriptor that wasn't set up after all.
Definition proc.c:532
void proc_fd_install(struct proc *proc, int fd, struct file *file, int flags)
Makes a reserved descriptor refer to an open file.
Definition proc.c:547
#define PROC_UIO(proc)
Definition proc.h:210
#define curproc
Definition sched.h:13
int signal_proc_send(struct proc *proc, int signal)
Sends a signal to a process.
Definition signal.c:310
#define FILE_SOCKET
Definition socket.h:70
int socket_ioctl(struct file *file, int request, void *argp)
Handles an ioctl() on a socket, by passing it to the protocol.
Definition socket.c:399
int vfs_stat(struct vnode *vnode, struct aquila_stat *buf)
Fills a stat structure with a vnode's attributes.
Definition stat.c:16
#define NULL
Definition stddef.h:27
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
unsigned int uint32_t
Definition stddef.h:22
signed long long int int64_t
Definition stddef.h:19
A device driver: its operations, any of which may be NULL.
Definition dev.h:28
A file descriptor: the open file it refers to (fs/file.c, shared with the descriptors that dup() and ...
Definition proc.h:47
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
off_t offset
Definition vfs.h:163
int ref
Definition vfs.h:170
int flags
Definition vfs.h:164
An iobuf.
Definition iobuf.h:35
Who does a filesystem operation: where its paths start, and its credentials and umask.
Definition vfs.h:60
struct vnode * cwd
Definition vfs.h:62
uint32_t flags
Definition vfs.h:66
A file in memory (a vnode): what its inode says, and the kernel's own state.
Definition vfs.h:113
size_t ref
how many references there are to it
Definition vfs.h:133
size_t size
Definition vfs.h:115
void * p
the filesystem's own data
Definition vfs.h:130
mode_t mode
Definition vfs.h:118
struct file * fd_file(int fd)
Finds the open file that a descriptor of the current process refers to, and holds it until the system...
Definition syscall.c:22
int upath_get(const char *upath, char **path)
Copies a path from user memory into a new kernel buffer.
Definition syscall.c:46
static int cwd_set(struct vnode *vnode)
Makes vnode the working directory, if it is a directory the process may search.
Definition sys_file.c:933
long sys_utimensat(int dirfd, const char *path, const struct aquila_timespec times[2], int flags)
Implements utimensat() (and futimens()): sets a file's access and modification times.
Definition sys_file.c:1340
long sys_mkdir(const char *path, mode_t mode)
Implements mkdir(): makes a directory.
Definition sys_file.c:797
long sys_access(const char *path, int mode)
Implements access(): says whether the process may read, write or execute a file.
Definition sys_file.c:1220
long sys_fcntl(int fd, int cmd, uintptr_t arg)
Implements fcntl(): duplicates a descriptor, or reads and sets the descriptor's flags (FD_CLOEXEC) or...
Definition sys_file.c:876
long sys_linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
Implements linkat(): link(), with paths relative to directories.
Definition sys_file.c:205
#define R_OK
Definition sys_file.c:1188
long sys_ioctl(int fd, int request, void *argp)
Implements ioctl(): a device's, a socket's, or a terminal's request.
Definition sys_file.c:622
long sys_fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags)
Implements fchownat(): chown(), with the path relative to a directory.
Definition sys_file.c:1286
long sys_umask(mode_t mask)
Implements umask(): sets the permissions that new files don't get.
Definition sys_file.c:1089
static struct vnode * fd_vnode(int fd, int *err)
Returns the vnode of an open file, or NULL with *err set (-EBADF, or -EINVAL for a socket).
Definition sys_file.c:1153
long sys_open(const char *path, int oflags, mode_t mode)
Implements open(): opens a file on a new descriptor, creating it with O_CREAT.
Definition sys_file.c:424
long sys_chdir(const char *upath)
Implements chdir(): changes the working directory.
Definition sys_file.c:956
long sys_flock(int fd, int op)
Implements flock(): takes or releases an advisory lock on an open file.
Definition sys_file.c:1490
long sys_symlinkat(const char *utarget, int dirfd, const char *upath)
Implements symlinkat(): makes a symbolic link.
Definition sys_file.c:1397
long sys_close(int fildes)
Implements close(): frees a descriptor.
Definition sys_file.c:86
long sys_lseek(int fildes, off_t offset, int whence)
Implements lseek(): moves an open file's offset.
Definition sys_file.c:221
static int do_fchmodat(int dirfd, const char *path, mode_t mode, int flags)
Changes a file's permissions, for chmod() and fchmodat().
Definition sys_file.c:1101
static int do_faccessat(int dirfd, const char *path, int mode, int flags)
Checks a file's permissions, for access() and faccessat().
Definition sys_file.c:1192
long sys_sync(void)
Implements sync(): writes out what the devices' caches hold.
Definition sys_file.c:1508
#define X_OK
Definition sys_file.c:1186
long sys_pipe(int fd[2])
Implements pipe(): makes a pipe, its read end and its write end open on two new descriptors.
Definition sys_file.c:810
static int do_fstatat(int dirfd, const char *path, struct aquila_stat *buf, int flags)
Gets a file's attributes, for the stat() calls.
Definition sys_file.c:477
long sys_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath)
Implements renameat() (and rename()): moves a file to another name, replacing what was there.
Definition sys_file.c:1464
long sys_fstatat(int dirfd, const char *path, struct aquila_stat *buf, int flags)
Implements fstatat(): stat(), with the path relative to a directory.
Definition sys_file.c:520
long sys_unlinkat(int dirfd, const char *path, int flags)
Implements unlinkat(): unlink(), or rmdir() with AT_REMOVEDIR, with the path relative to a directory.
Definition sys_file.c:568
static int do_mknodat(int dirfd, const char *upath, mode_t mode, dev_t dev)
Makes a file of any type, for mknod(), mknodat() and mkdir().
Definition sys_file.c:754
long sys_lchown(const char *path, uid_t owner, gid_t group)
Implements lchown(): chown() of a symbolic link itself.
Definition sys_file.c:1322
long sys_ftruncate(int fildes, off_t len)
Implements ftruncate(): sets an open file's size.
Definition sys_file.c:1065
static int at_uio(int dirfd, const char *path, struct uio *uio)
Sets up the uio to look up path from the directory that dirfd refers to, or from the working director...
Definition sys_file.c:18
long sys_readlinkat(int dirfd, const char *upath, char *buf, size_t size)
Implements readlinkat(): what a symbolic link points to (not NUL-terminated).
Definition sys_file.c:1426
long sys_write(int fd, void *buf, size_t nbytes)
Implements write().
Definition sys_file.c:584
long sys_readdir(int fd, struct dirent *dirent)
Reads a directory's next entry, for the C library's readdir().
Definition sys_file.c:667
long sys_isatty(int fildes)
Says whether a descriptor refers to a character device, the only kind of file that can be a terminal.
Definition sys_file.c:137
long sys_fchmod(int fd, mode_t mode)
Implements fchmod(): changes an open file's permissions.
Definition sys_file.c:1172
long sys_getcwd(char *buf, size_t size)
Implements getcwd(): the working directory's path.
Definition sys_file.c:985
long sys_read(int fildes, void *buf, size_t nbytes)
Implements read().
Definition sys_file.c:454
long sys_chown(const char *path, uid_t owner, gid_t group)
Implements chown(): changes a file's owner and group.
Definition sys_file.c:1269
static int do_fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags)
Changes a file's owner and group, for the chown() calls.
Definition sys_file.c:1244
long sys_chmod(const char *path, mode_t mode)
Implements chmod(): changes a file's permissions.
Definition sys_file.c:1129
static int at_lookup(int dirfd, const char *upath, int flags, struct uio *uio, struct vnode **vnode)
Looks up a path from user memory, from dirfd; with AT_SYMLINK_NOFOLLOW in flags, a final symbolic lin...
Definition sys_file.c:60
long sys_fchmodat(int dirfd, const char *path, mode_t mode, int flags)
Implements fchmodat(): chmod(), with the path relative to a directory.
Definition sys_file.c:1145
static int do_linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags)
Makes a link, for link() and linkat().
Definition sys_file.c:157
long sys_mknodat(int dirfd, const char *path, uint32_t mode, uint32_t dev)
Implements mknodat(): mknod(), with the path relative to a directory.
Definition sys_file.c:1039
long sys_fchown(int fd, uid_t owner, gid_t group)
Implements fchown(): changes an open file's owner and group.
Definition sys_file.c:1301
long sys_lstat(const char *path, struct aquila_stat *buf)
Implements lstat(): a file's attributes, a symbolic link's own.
Definition sys_file.c:1052
long sys_stat(const char *path, struct aquila_stat *buf)
Implements stat(): a file's attributes, following a symbolic link.
Definition sys_file.c:504
long sys_openat(int dirfd, const char *path, int oflags, mode_t mode)
Implements openat(): open(), with the path relative to a directory.
Definition sys_file.c:439
static int creat_path(const char *path, struct uio *uio, char **ref)
Finds what O_CREAT should create for path: if path is a dangling symbolic link, the file it points to...
Definition sys_file.c:248
long sys_link(const char *oldpath, const char *newpath)
Implements link(): a new name for a file.
Definition sys_file.c:188
long sys_faccessat(int dirfd, const char *path, int mode, int flags)
Implements faccessat(): access(), with the path relative to a directory.
Definition sys_file.c:1236
long sys_rmdir(const char *path)
Implements rmdir(): removes an empty directory.
Definition sys_file.c:1383
long sys_fchdir(int fd)
Implements fchdir(): changes the working directory to an open directory.
Definition sys_file.c:1523
long sys_mknod(const char *path, uint32_t mode, uint32_t dev)
Implements mknod(): makes a file, a directory, a FIFO, or (only root) a device file.
Definition sys_file.c:1023
static int do_openat(int dirfd, const char *upath, int oflags, mode_t mode)
Opens (or creates) a file on a new descriptor, for open() and openat().
Definition sys_file.c:311
#define W_OK
Definition sys_file.c:1187
static int at_path(int dirfd, const char *upath, char **path, struct uio *uio)
Copies a path into the kernel (*path, which the caller frees) and sets up the uio to look it up from ...
Definition sys_file.c:42
long sys_unlink(const char *path)
Implements unlink(): removes a name of a file (not a directory's).
Definition sys_file.c:553
long sys_mount(struct aquila_mount_args *args)
Implements mount(): mounts a file system on a directory.
Definition sys_file.c:706
long sys_fstat(int fildes, struct aquila_stat *buf)
Implements fstat(): an open file's attributes.
Definition sys_file.c:103
static int do_unlinkat(int dirfd, const char *upath, int flags)
Removes a name, or a directory with AT_REMOVEDIR, for unlink(), unlinkat() and rmdir().
Definition sys_file.c:528
#define UPATH_MAX
Definition syscalls.h:54
uint16_t dev_t
Definition types.h:18
long int ssize_t
Definition types.h:12
long int off_t
Definition types.h:10
uint32_t gid_t
Definition types.h:21
uint32_t uid_t
Definition types.h:20
uint32_t mode_t
Definition types.h:15
static int uaccess_check(const void *ptr, size_t len)
Checks that [ptr, ptr + len) is in user space.
Definition uaccess.h:27
int vfs_access(struct vnode *vnode, struct uio *uio, int mode)
Checks whether a user may access a vnode in a way: the owner's permissions apply to its owner,...
Definition vfs.c:114
int vfs_perms_check(struct file *file, struct uio *uio)
Checks whether a user may open a file the way it's being opened (read, write, execute,...
Definition vfs.c:139
#define VFS_W
Definition vfs.h:296
#define VFS_X
Definition vfs.h:297
#define VFS_R
Definition vfs.h:295