exercise_5_4.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. Implement dup() and dup2() using fcntl() and, where necessary, close(). (You may
  3. ignore the fact that dup2() and fcntl() return different errno values for some error
  4. cases.) For dup2(), remember to handle the special case where oldfd equals newfd. In
  5. this case, you should check whether oldfd is valid, which can be done by, for example,
  6. checking if fcntl(oldfd, F_GETFL) succeeds. If oldfd is not valid, then the function
  7. should return –1 with errno set to EBADF .
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <fcntl.h>
  12. #include <unistd.h>
  13. #include <assert.h>
  14. #include <errno.h>
  15. int
  16. dup (int filedes)
  17. {
  18. return fcntl (filedes, F_DUPFD, 0);
  19. }
  20. int
  21. dup2 (int oldfd, int newfd)
  22. {
  23. if (fcntl (oldfd, F_GETFD) == -1 && errno == EBADF)
  24. {
  25. return -1;
  26. }
  27. if (oldfd == newfd) return oldfd;
  28. if (fcntl (newfd, F_GETFD) != -1)
  29. close (newfd);
  30. return fcntl (oldfd, F_DUPFD, newfd);
  31. }
  32. int
  33. main (void)
  34. {
  35. int fd = dup (STDOUT_FILENO);
  36. printf ("Testing dup: %d\n", fd);
  37. write (fd, "test\n", 5);
  38. close (fd);
  39. const int newfd = 5;
  40. fd = dup2 (STDOUT_FILENO, newfd);
  41. assert (fd == newfd);
  42. printf ("Testing dup2: %d\n", fd);
  43. write (fd, "test1\n", 6);
  44. close (fd);
  45. fd = open ("test", O_CREAT|O_WRONLY, S_IRWXU);
  46. dup2 (STDOUT_FILENO, fd);
  47. printf ("Testing dup2: %d\n", fd);
  48. write (fd, "test2\n", 6);
  49. assert (dup2 (10, 2) == -1);
  50. return EXIT_SUCCESS;
  51. }