file_syscalls.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include <types.h>
  2. #include <kern/errno.h>
  3. #include <kern/unistd.h>
  4. #include <lib.h>
  5. #include <uio.h>
  6. #include <syscall.h>
  7. #include <vnode.h>
  8. #include <vfs.h>
  9. #include <current.h>
  10. #include <proc.h>
  11. /* handler for write() system call */
  12. /*
  13. * n.b.
  14. * This implementation handles only writes to standard output
  15. * and standard error, both of which go to the console.
  16. * Also, it does not provide any synchronization, so writes
  17. * are not atomic.
  18. *
  19. * You will need to improve this implementation
  20. */
  21. int
  22. sys_write(int fdesc,userptr_t ubuf,unsigned int nbytes,int *retval)
  23. {
  24. struct iovec iov;
  25. struct uio u;
  26. int res;
  27. DEBUG(DB_SYSCALL,"Syscall: write(%d,%x,%d)\n",fdesc,(unsigned int)ubuf,nbytes);
  28. /* only stdout and stderr writes are currently implemented */
  29. if (!((fdesc==STDOUT_FILENO)||(fdesc==STDERR_FILENO))) {
  30. return EUNIMP;
  31. }
  32. KASSERT(curproc != NULL);
  33. KASSERT(curproc->console != NULL);
  34. KASSERT(curproc->p_addrspace != NULL);
  35. /* set up a uio structure to refer to the user program's buffer (ubuf) */
  36. iov.iov_ubase = ubuf;
  37. iov.iov_len = nbytes;
  38. u.uio_iov = &iov;
  39. u.uio_iovcnt = 1;
  40. u.uio_offset = 0; /* not needed for the console */
  41. u.uio_resid = nbytes;
  42. u.uio_segflg = UIO_USERSPACE;
  43. u.uio_rw = UIO_WRITE;
  44. u.uio_space = curproc->p_addrspace;
  45. res = VOP_WRITE(curproc->console,&u);
  46. if (res) {
  47. return res;
  48. }
  49. /* pass back the number of bytes actually written */
  50. *retval = nbytes - u.uio_resid;
  51. KASSERT(*retval >= 0);
  52. return 0;
  53. }