13 static void err_exit(char *op, int errn)
15 fprintf(stderr, "%s: %s\n", op, strerror(errn));
19 void *thread_fn(void *arg)
21 /* execve will release threads */
33 static void checklock(int fd)
35 if (fcntl(fd, F_GETLK, &fl) < 0)
36 err_exit("getlk", errno);
37 if (fl.l_type == F_UNLCK) {
38 printf("record lock is not preserved across execve(2)\n");
44 int main(int argc, char **argv)
48 char *newargv[] = { argv[0], argv[1], fdstr, NULL };
51 /* passing fd in argv[2] in execve */
58 fd = open(argv[1], O_WRONLY|O_CREAT, 0755);
60 err_exit("open", errno);
61 if (fcntl(fd, F_SETLK, &fl) < 0)
62 err_exit("setlk", errno);
64 /* require multithread process to reproduce the issue */
65 pthread_create(&th, NULL, thread_fn, &fd);
67 if ((flags = fcntl(fd, F_GETFD)) < 0)
68 err_exit("getfd", errno);
70 if (fcntl(fd, F_SETFD, flags) < 0)
71 err_exit("setfd", errno);
73 snprintf(fdstr, sizeof(fdstr), "%d", fd);
74 execve(argv[0], newargv, NULL);