As far as I can tell, close-exec is not working correctly in 2.6.9
or 2.6.10-1.741_FC3smp.

The attached program generates a file /tmp/cl_foo.output
which has this data:


[EMAIL PROTECTED] ~]$ more /tmp/cl_foo.output total 5 lrwx------ 1 greear greear 64 Jan 30 23:49 0 -> /dev/pts/3 l-wx------ 1 greear greear 64 Jan 30 23:49 1 -> /tmp/cl_foo.output l-wx------ 1 greear greear 64 Jan 30 23:49 2 -> /tmp/cl_foo.output lr-x------ 1 greear greear 64 Jan 30 23:49 3 -> /etc/passwd lr-x------ 1 greear greear 64 Jan 30 23:49 4 -> /proc/7020/fd


I would not expect to see the /etc/passwd entry since I marked it close-exec in the parent process before forking and running the system() command.

Am I confused about things, or is this a real bug?

Thanks,
Ben

--
Ben Greear <[EMAIL PROTECTED]>
Candela Technologies Inc  http://www.candelatech.com


#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <errno.h>

using namespace std;

void close_exec(int s) {
   int  flags;

   flags = fcntl(s, F_GETFL);
   flags |= (FD_CLOEXEC);
   if (fcntl(s, F_SETFL, flags) < 0) {
      cerr << "ERROR:  fcntl, executing close_exec:  " << strerror(errno)
           << endl;
   }
}//close_exec

int main() {
   ofstream script("/tmp/cl_foo.bash");
   script << "#!/bin/bash\nls -l /proc/self/fd > /tmp/cl_foo.output 2>&1\n";
   script.close();
   
   if (chmod("/tmp/cl_foo.bash",
             S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) < 0) {
      cerr << "ERROR:  Failed to chmod /tmp/cl_foo.bash, error: "
           << strerror(errno) << endl;
      exit(7);
   }

   int fd = open("/etc/passwd", O_RDONLY);
   if (fd < 0) {
      cerr << "ERROR:  Failed to open /etc/passwd: " << strerror(errno) << endl;
   }
   else {
      close_exec(fd);
   }

   int rv = fork();
   if (rv < 0) {
      cerr << "ERROR from fork: " << strerror(errno) << endl;
   }
   else if (rv == 0) {
      // Child
      system("/tmp/cl_foo.bash");
      exit(7);
   }
   else {
      // parent, done
      sleep(5);
   }
   return 0;
}//main

Reply via email to