From owner-freebsd-hackers@FreeBSD.ORG Wed Dec 29 23:05:23 2004 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F289C16A4CE for ; Wed, 29 Dec 2004 23:05:22 +0000 (GMT) Received: from smtp.k12us.com (smtp.k12us.com [65.112.222.15]) by mx1.FreeBSD.org (Postfix) with SMTP id 620C043D2D for ; Wed, 29 Dec 2004 23:05:22 +0000 (GMT) (envelope-from csw@k12hq.com) Received: (qmail 81046 invoked by uid 1001); 29 Dec 2004 23:05:21 -0000 Date: Wed, 29 Dec 2004 18:05:21 -0500 From: Christopher Weimann To: freebsd-hackers@freebsd.org Message-ID: <20041229230521.GB31984@smtp.k12us.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.4i Subject: execl bug? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Dec 2004 23:05:23 -0000 It seems that the open handle is carried through and usable by the child program unless the parent has done something to move the file pointer. For example the program below (tst.c) opens a file, reads a line, rewinds then uses execl to call "cat -" which ought to send the file to stdout. I thought I must be misunderstanding how execl is supposed to work so I tried it on a Redhat box to see if everything behaves the same. It doesn't. On Redhat the file is displayed just as I would expect. At first I thought this was a close-on-exec problem but that is not set, plus it works if I remove the fgets call. What am I missing? #include #include #include #include #include #include #include #include #include int main(argc, argv) int argc; char **argv; { pid_t pid; int status ; char buff[ 513 ]; int tempfd = -1 ; if ((tempfd=open("tst.c", O_RDWR|O_CREAT, 0600)) < 0) { perror("open"); } close(0); dup(tempfd); close(tempfd); printf( "\nclose on exec is %d \n" , fcntl( fileno(stdin), F_GETFD) && FD_CLOEXEC ) ; /* comment out the following three lines and all is well on FreeBSD */ fgets( buff, 512, stdin ) ; printf( "%s", buff ) ; rewind( stdin ) ; if ( (pid = fork()) < 0){ perror("execl error"); _exit(1) ; } else if (pid == 0) { /* child */ if (execl( "/bin/cat","cat", "-" , (char *) 0) < 0) { perror("execl error"); _exit(1) ; } } if (waitpid(pid, &status, 0) < 0){ /* parent */ perror("execl error"); exit(1) ; } if( WIFEXITED(status) ) { exit(WEXITSTATUS(status)); }else{ exit( 1 ) ; } } --