shim_dup.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* Copyright (C) 2014 Stony Brook University
  4. This file is part of Graphene Library OS.
  5. Graphene Library OS is free software: you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. Graphene Library OS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * shim_clone.c
  17. *
  18. * Implementation of system call "dup", "dup2" and "dup3".
  19. */
  20. #include <shim_internal.h>
  21. #include <shim_table.h>
  22. #include <shim_thread.h>
  23. #include <shim_handle.h>
  24. #include <shim_fs.h>
  25. #include <shim_utils.h>
  26. #include <pal.h>
  27. #include <pal_error.h>
  28. #include <errno.h>
  29. int shim_do_dup (int fd)
  30. {
  31. struct shim_handle_map * handle_map = get_cur_handle_map(NULL);
  32. int flags = 0;
  33. struct shim_handle * hdl = get_fd_handle(fd, &flags, handle_map);
  34. if (!hdl)
  35. return -EBADF;
  36. int vfd = set_new_fd_handle(hdl, flags, handle_map);
  37. put_handle(hdl);
  38. return vfd < 0 ? -EMFILE : vfd;
  39. }
  40. int shim_do_dup2 (int oldfd, int newfd)
  41. {
  42. struct shim_handle_map * handle_map = get_cur_handle_map(NULL);
  43. struct shim_handle * hdl = get_fd_handle(oldfd, NULL, handle_map);
  44. if (!hdl)
  45. return -EBADF;
  46. struct shim_handle * new_hdl = detach_fd_handle(newfd, NULL, handle_map);
  47. if (new_hdl)
  48. close_handle(new_hdl);
  49. int vfd = set_new_fd_handle_by_fd(newfd, hdl, 0, handle_map);
  50. put_handle(hdl);
  51. return vfd < 0 ? -EMFILE : vfd;
  52. }
  53. int shim_do_dup3 (int oldfd, int newfd, int flags)
  54. {
  55. struct shim_handle_map * handle_map = get_cur_handle_map(NULL);
  56. struct shim_handle * hdl = get_fd_handle(oldfd, NULL, handle_map);
  57. if (!hdl)
  58. return -EBADF;
  59. struct shim_handle * new_hdl = detach_fd_handle(newfd, NULL, handle_map);
  60. if (new_hdl)
  61. close_handle(new_hdl);
  62. int vfd = set_new_fd_handle_by_fd(newfd, hdl, flags, handle_map);
  63. put_handle(hdl);
  64. return vfd < 0 ? -EMFILE : vfd;
  65. }