Wednesday, 22 February 2017

Test cases of dup3() for radix tree__alloc_fd

I have written dup3() test case.
I am going to run this test case for the close_on_exec patch.
Also, I have written one program (child_process.c) which will run on exec and try to open the file using fdopen().

dup3() test case is given below,

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * This is dup3() functionality testcase. 
 * The dup3() is duplicate a file descriptor to a given number, 
 * with flags.
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

extern char **environ;

#define WRONG_FLAG -1

int dup3_basic_tests () {

 int oldfd, newfd;
 int ret;

 oldfd = open("/tmp/file1",O_CREAT | O_RDWR, 0644);
 if (oldfd < 0) {
  printf("open() error \n");
  return -1;
 }
 ret = fcntl(oldfd, F_GETFD);
 if (ret != FD_CLOEXEC)
  printf("test 1 : pass\n");
 else
  printf("test 1 : fail\n");

 ret = dup3(oldfd, newfd, O_CLOEXEC);
 if (ret == -1) {
  printf("dup3() error \n");
  return -1;
 }

 ret = fcntl(newfd, F_GETFD);   /* Read the file descriptor flags */

 if (ret == FD_CLOEXEC)
  printf("test 2 : pass\n");
 else
  printf("test 2 : fail\n");

 close(newfd);

 ret = dup3(oldfd, newfd, 0);
 if (ret == -1) {
  printf("dup3() error \n");
  return -1;
 }

 ret = fcntl(newfd, F_GETFD);

 if (ret != FD_CLOEXEC)
  printf("test 3 : pass\n");
 else
  printf("test 3 : fail\n");

 close(newfd);

 ret = dup3(oldfd, newfd, WRONG_FLAG);
 if (ret == -1)
  printf("test 4 : pass \n");
 else
  printf("test 4 : fail \n");

 close(oldfd);
 unlink("/tmp/file1");
 return 0;
}

int dup3_loop() {
 int i,ret;
 int oldfd, newfd;

 oldfd = open("/tmp/file2",O_CREAT | O_RDWR, 0644);
 if (oldfd < 0) {
  printf("open() error \n");
  return -1;
 }

 for (i = 3; i < 100; i++) {
  ret = dup3(oldfd, i, O_CLOEXEC);
  if (ret < 0) {
   printf("dup3_loop : dup3() error\n");
   return -1;
  }  
 }
 for (i = 3; i < 100; i++) {
  ret = fcntl(i, F_GETFD);
  if (ret < 0) {
   printf("dup3_loop : fcntl() error\n");
   return -1;
  }
  if (ret == FD_CLOEXEC)
   printf("dup3_loop() : pass.%d\n",i);
  else
   printf("dup3_loop() : fail.%d\n",i);

  close(i);
 }

 unlink("/tmp/file2");
}

void fork_exec() {
 int fd,new_fd = 4;
 int pid,ret;
 char fd_buf[10];
 char *argv[3] = {"child_process",fd_buf, NULL};

 fd = open("/tmp/file3",O_CREAT | O_RDWR, 0644);
 if (fd < 0){
  printf("fork_exec : open failed\n");
  exit(-1); 
 }

 ret = dup3(fd, new_fd, O_CLOEXEC);
 printf("parent process new_fd %d\n", new_fd);
 if (ret < 0){
  printf("dup3 : dup3 failed\n");
  exit(-1);
 }

 pid = fork();

 if (pid == 0) {
  sprintf(fd_buf,"%d",new_fd);
  ret = execvp("./child_process", argv);
  if (ret < 0) {
   printf("execv() failed...\n");
   exit(-1);
  }
 }
}

int main() {
 int ret;
 ret = dup3_basic_tests();
 if (ret == -1)
  return -1;
 ret = dup3_loop();
 if (ret == -1)
  return -1;
 fork_exec();
 return 0; 
}



Program for child_process.c which will run on exec,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {

 int fd,ret;
 FILE *file;

 if (argc < 2) {
  printf("Usage : %s fd\n",argv[0]);
  return -1;
 }

 fd = atoi(argv[1]);
 printf("child process fd %d\n", fd); 
 file = fdopen(fd, "r+");
 if (file == NULL)
  printf("fork-exec : test pass\n");
 else
  printf("fork-exec : test fail\n");
 
 return 0;
}

No comments:

Post a Comment