11 #include <sys/types.h>
14 static void err_exit(char *op, int errn)
16 fprintf(stderr, "%s: %s\n", op, strerror(errn));
20 void *thread_fn(void *arg)
22 /* execve will release threads */
34 static void checklock(int fd)
40 err_exit("fork", errno);
43 if (fcntl(fd, F_GETLK, &fl) < 0)
44 err_exit("getlk", errno);
45 if (fl.l_type == F_UNLCK) {
46 printf("record lock is not preserved across execve(2)\n");
52 waitpid(pid, NULL, 0);
57 int main(int argc, char **argv)
61 char *newargv[] = { argv[0], argv[1], fdstr, NULL };
64 /* passing fd in argv[2] in execve */
70 fd = open(argv[1], O_WRONLY|O_CREAT, 0755);
72 err_exit("open", errno);
73 if (fcntl(fd, F_SETLK, &fl) < 0)
74 err_exit("setlk", errno);
76 /* require multithread process to reproduce the issue */
77 pthread_create(&th, NULL, thread_fn, &fd);
79 if ((flags = fcntl(fd, F_GETFD)) < 0)
80 err_exit("getfd", errno);
82 if (fcntl(fd, F_SETFD, flags) < 0)
83 err_exit("setfd", errno);
85 snprintf(fdstr, sizeof(fdstr), "%d", fd);
86 execve(argv[0], newargv, NULL);