Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File::Temp::tempdir(CLEANUP=>1) broken when forking #7749

Closed
p5pRT opened this issue Jan 12, 2005 · 7 comments
Closed

File::Temp::tempdir(CLEANUP=>1) broken when forking #7749

p5pRT opened this issue Jan 12, 2005 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 12, 2005

Migrated from rt.perl.org#33769 (status was 'resolved')

Searchable as RT33769$

@p5pRT
Copy link
Author

p5pRT commented Jan 12, 2005

From dmacks@netspace.org

Created by dmacks@netspace.org

File​::Temp​::tempdir() implements the CLEANUP option by setting an END
block to recursively delete the dir. If the process then forks, both
parent and child have that END, and so it runs when either parent or
child exit. That means when the child ends, it deletes the parent's
tempdir. Test case​:

  my $dir = File​::Temp​::tempdir(CLEANUP=>1);
  printf "start​: %s\n", (-d $dir ? "Y" : "N");
  if (not open(KID, "-|")) {
  printf "child​: %s\n", (-d $dir ? "Y" : "N");
  exit;
  } else {
  while (<KID>) {
  print; # spool child's STDOUT to parent's
  }
  printf "later​: %s\n", (-d $dir ? "Y" : "N");
  }

gives me​:
  start​: Y
  child​: Y
  later​: N
under File​::Temp 0.14 (part of core, and latest in CPAN).

Neither this effect (children can delete parent's or sibling's
tempdir) nor the implementation of CLEANUP is documented in the POD.

Proposed solution​: the underlying _deferred_unlink() function could
store the current pid along with the dirname, and the END would only
delete if the pid were the same.

Maintainer emailed 2 weeks ago, no response.

Perl Info

Flags:
    category=library
    severity=medium

This perlbug was built using Perl v5.8.5 in the Red Hat build system.
It is being executed now by Perl v5.8.5 - Fri Aug 27 14:46:14 EDT 2004.

Site configuration information for perl v5.8.5:

Configured by Red Hat, Inc. at Fri Aug 27 14:46:14 EDT 2004.

Summary of my perl5 (revision 5 version 8 subversion 5) configuration:
  Platform:
    osname=linux, osvers=2.6.7-1.499smp, archname=x86_64-linux-thread-multi
    uname='linux thor.perf.redhat.com 2.6.7-1.499smp #1 smp wed jul 28 12:34:13 edt 2004 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -m64 -Dversion=5.8.5 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Dprivlib=/usr/lib/perl5/5.8.5 -Dsitelib=/usr/lib/perl5/site_perl/5.8.5 -Dvendorlib=/usr/lib/perl5/vendor_perl/5.8.5 -Darchlib=/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi -Dsitearch=/usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi -Darchname=x86_64-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dinc_version_list=5.8.4 5.8.3 5.8.2 5.8.1 5.8.0'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=define uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
    optimize='-O2 -g -pipe -m64',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm'
    ccversion='', gccversion='3.4.1 20040815 (Red Hat 3.4.1-9)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =''
    libpth=/usr/local/lib64 /lib64 /usr/lib64
    libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.3.3.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.3.3'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared'

Locally applied patches:
    


@INC for perl v5.8.5:
    /home/dmacks/lib/perl5/site_perl/5.8.5/x86_64-linux-thread-multi
    /home/dmacks/lib/perl5/site_perl/5.8.5
    /home/dmacks/lib/perl5/site_perl/x86_64-linux-thread-multi
    /home/dmacks/lib/perl5/site_perl/5.8.4
    /home/dmacks/lib/perl5/site_perl/5.8.3
    /home/dmacks/lib/perl5/site_perl/5.8.2
    /home/dmacks/lib/perl5/site_perl/5.8.1
    /home/dmacks/lib/perl5/site_perl/5.8.0
    /home/dmacks/lib/perl5/site_perl
    /home/dmacks/lib64/perl5/5.8.5/x86_64-linux-thread-multi
    /home/dmacks/lib64/perl5/5.8.5
    /home/dmacks/lib64/perl5/x86_64-linux-thread-multi
    /home/dmacks/lib64/perl5/5.8.4
    /home/dmacks/lib64/perl5/5.8.3
    /home/dmacks/lib64/perl5/5.8.2
    /home/dmacks/lib64/perl5/5.8.1
    /home/dmacks/lib64/perl5/5.8.0
    /home/dmacks/lib64/perl5
    /usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi
    /usr/lib/perl5/5.8.5
    /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.4/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.3/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.2/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.1/x86_64-linux-thread-multi
    /usr/lib64/perl5/site_perl/5.8.0/x86_64-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.5
    /usr/lib/perl5/site_perl/5.8.4
    /usr/lib/perl5/site_perl/5.8.3
    /usr/lib/perl5/site_perl/5.8.2
    /usr/lib/perl5/site_perl/5.8.1
    /usr/lib/perl5/site_perl/5.8.0
    /usr/lib/perl5/site_perl
    /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.4/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.3/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.2/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.1/x86_64-linux-thread-multi
    /usr/lib64/perl5/vendor_perl/5.8.0/x86_64-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.5
    /usr/lib/perl5/vendor_perl/5.8.4
    /usr/lib/perl5/vendor_perl/5.8.3
    /usr/lib/perl5/vendor_perl/5.8.2
    /usr/lib/perl5/vendor_perl/5.8.1
    /usr/lib/perl5/vendor_perl/5.8.0
    /usr/lib/perl5/vendor_perl
    .


Environment for perl v5.8.5:
    HOME=/home/dmacks
    LANG=POSIX
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/dmacks/bin:/usr/kerberos/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/bin/games:.
    PERL5LIB=/home/dmacks/lib/perl5/site_perl:/home/dmacks/lib64/perl5
    PERL_BADLANG (unset)
    SHELL=/bin/tcsh

@p5pRT
Copy link
Author

p5pRT commented Jan 12, 2005

From perl5-porters@ton.iguana.be

In article <rt-3.0.11-33769-105541.8.59233924008095@​perl.org>,
  Daniel Macks (via RT) <perlbug-followup@​perl.org> writes​:

[Please enter your report here]

File​::Temp​::tempdir() implements the CLEANUP option by setting an END
block to recursively delete the dir. If the process then forks, both
parent and child have that END, and so it runs when either parent or
child exit. That means when the child ends, it deletes the parent's
tempdir. Test case​:

Easy enough to change by checking $$ at least on unix. But actually
I think nothing should be done since there is no real reason to assume
that the parent has somehow more "right" to the file than the child.
Think for example of daemonizing with the double fork trick where it's the
child that keeps running, not the parent.

Just document it so there's less change of people being caught by surprise.

@p5pRT
Copy link
Author

p5pRT commented Jan 12, 2005

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 13, 2005

From @nwc10

On Wed, Jan 12, 2005 at 11​:36​:16PM +0000, Ton Hospel wrote​:

Easy enough to change by checking $$ at least on unix. But actually
I think nothing should be done since there is no real reason to assume
that the parent has somehow more "right" to the file than the child.
Think for example of daemonizing with the double fork trick where it's the
child that keeps running, not the parent.

Well, I think that it might be worth adding a line to the perlfunc entry for
fork mentioning something like

  If both the parent and child processes exit normally then END blocks
  will run in both. If your child process does not C<exec> another program
  be careful not to create bugs where the child exits while the parent is
  still running, and END blocks have unwanted external effects such as
  deleting temporary files.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jan 13, 2005

From Robin.Barker@npl.co.uk

It may be appropriate to call POSIX​::_exit(0) in the child,
because _exit avoid END blocks. i.e. the documentation should
suggest using C<POSIX​::_exit(0)>.

This was a useful workaround for perl bug #30040.

Robin
-----Original Message-----
From​: Nicholas Clark [mailto​:nick@​ccl4.org]
Sent​: 13 January 2005 12​:14
To​: Ton Hospel
Cc​: perl5-porters@​perl.org
Subject​: Re​: [perl #33769] File​::Temp​::tempdir(CLEANUP=>1) broken when
forking

On Wed, Jan 12, 2005 at 11​:36​:16PM +0000, Ton Hospel wrote​:

Easy enough to change by checking $$ at least on unix. But actually
I think nothing should be done since there is no real reason to assume
that the parent has somehow more "right" to the file than the child.
Think for example of daemonizing with the double fork trick where it's the
child that keeps running, not the parent.

Well, I think that it might be worth adding a line to the perlfunc entry for
fork mentioning something like

  If both the parent and child processes exit normally then END blocks
  will run in both. If your child process does not C<exec> another program
  be careful not to create bugs where the child exits while the parent is
  still running, and END blocks have unwanted external effects such as
  deleting temporary files.

Nicholas Clark


This e-mail and any attachments may contain confidential and/or
privileged material; it is for the intended addressee(s) only.
If you are not a named addressee, you must not use, retain or
disclose such information.

NPL Management Ltd cannot guarantee that the e-mail or any
attachments are free from viruses.

NPL Management Ltd. Registered in England and Wales. No​: 2937881
Registered Office​: Teddington, Middlesex, United Kingdom TW11 0LW.


@p5pRT
Copy link
Author

p5pRT commented Jan 13, 2005

From @timj

Yes. I was contacted over Christmas and was away and forgot to deal with
it when I came back. Sorry. I will definitely document this in the next
release and from the discussion here it's not clear it's obvious whether I
should do anything else but I will consider having the behaviour under
user control (or equivalently provide a means for removing a file from
the cleanup list).

Can you file this fault on the perl module RT rather than the perl RT so
that I don't lose it? I'm travelling again at the moment but I will try to
deal with the outstanding File​::Temp requests shortly.

Tim

On Tue, 12 Jan 2005, Daniel Macks wrote​:

# New Ticket Created by Daniel Macks
# Please include the string​: [perl #33769]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=33769 >

This is a bug report for perl from dmacks@​netspace.org,
generated with the help of perlbug 1.35 running under perl v5.8.5.

-----------------------------------------------------------------
[Please enter your report here]

File​::Temp​::tempdir() implements the CLEANUP option by setting an END
block to recursively delete the dir. If the process then forks, both
parent and child have that END, and so it runs when either parent or
child exit. That means when the child ends, it deletes the parent's
tempdir. Test case​:

my $dir = File​::Temp​::tempdir(CLEANUP=>1);
printf "start​: %s\n", (-d $dir ? "Y" : "N");
if (not open(KID, "-|")) {
printf "child​: %s\n", (-d $dir ? "Y" : "N");
exit;
} else {
while (<KID>) {
print; # spool child's STDOUT to parent's
}
printf "later​: %s\n", (-d $dir ? "Y" : "N");
}

gives me​:
start​: Y
child​: Y
later​: N
under File​::Temp 0.14 (part of core, and latest in CPAN).

Neither this effect (children can delete parent's or sibling's
tempdir) nor the implementation of CLEANUP is documented in the POD.

Proposed solution​: the underlying _deferred_unlink() function could
store the current pid along with the dirname, and the END would only
delete if the pid were the same.

Maintainer emailed 2 weeks ago, no response.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=library
severity=medium
---
This perlbug was built using Perl v5.8.5 in the Red Hat build system.
It is being executed now by Perl v5.8.5 - Fri Aug 27 14​:46​:14 EDT 2004.

Site configuration information for perl v5.8.5​:

Configured by Red Hat, Inc. at Fri Aug 27 14​:46​:14 EDT 2004.

Summary of my perl5 (revision 5 version 8 subversion 5) configuration​:
Platform​:
osname=linux, osvers=2.6.7-1.499smp, archname=x86_64-linux-thread-multi
uname='linux thor.perf.redhat.com 2.6.7-1.499smp #1 smp wed jul 28 12​:34​:13 edt 2004 x86_64 x86_64 x86_64 gnulinux '
config_args='-des -Doptimize=-O2 -g -pipe -m64 -Dversion=5.8.5 -Dmyhostname=localhost -Dperladmin=root@​localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Dprivlib=/usr/lib/perl5/5.8.5 -Dsitelib=/usr/lib/perl5/site_perl/5.8.5 -Dvendorlib=/usr/lib/perl5/vendor_perl/5.8.5 -Darchlib=/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi -Dsitearch=/usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi -Darchname=x86_64-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dinc_version_list=5.8.4 5.8.3 5.8.2 5.8.1 5.8.0'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=define uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
optimize='-O2 -g -pipe -m64',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm'
ccversion='', gccversion='3.4.1 20040815 (Red Hat 3.4.1-9)', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='gcc', ldflags =''
libpth=/usr/local/lib64 /lib64 /usr/lib64
libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
libc=/lib/libc-2.3.3.so, so=so, useshrplib=true, libperl=libperl.so
gnulibc_version='2.3.3'
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/CORE'
cccdlflags='-fPIC', lddlflags='-shared'

Locally applied patches​:

---
@​INC for perl v5.8.5​:
/home/dmacks/lib/perl5/site_perl/5.8.5/x86_64-linux-thread-multi
/home/dmacks/lib/perl5/site_perl/5.8.5
/home/dmacks/lib/perl5/site_perl/x86_64-linux-thread-multi
/home/dmacks/lib/perl5/site_perl/5.8.4
/home/dmacks/lib/perl5/site_perl/5.8.3
/home/dmacks/lib/perl5/site_perl/5.8.2
/home/dmacks/lib/perl5/site_perl/5.8.1
/home/dmacks/lib/perl5/site_perl/5.8.0
/home/dmacks/lib/perl5/site_perl
/home/dmacks/lib64/perl5/5.8.5/x86_64-linux-thread-multi
/home/dmacks/lib64/perl5/5.8.5
/home/dmacks/lib64/perl5/x86_64-linux-thread-multi
/home/dmacks/lib64/perl5/5.8.4
/home/dmacks/lib64/perl5/5.8.3
/home/dmacks/lib64/perl5/5.8.2
/home/dmacks/lib64/perl5/5.8.1
/home/dmacks/lib64/perl5/5.8.0
/home/dmacks/lib64/perl5
/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi
/usr/lib/perl5/5.8.5
/usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.8.4/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.8.3/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.8.2/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.8.1/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.8.0/x86_64-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.5
/usr/lib/perl5/site_perl/5.8.4
/usr/lib/perl5/site_perl/5.8.3
/usr/lib/perl5/site_perl/5.8.2
/usr/lib/perl5/site_perl/5.8.1
/usr/lib/perl5/site_perl/5.8.0
/usr/lib/perl5/site_perl
/usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.8.4/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.8.3/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.8.2/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.8.1/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.8.0/x86_64-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.5
/usr/lib/perl5/vendor_perl/5.8.4
/usr/lib/perl5/vendor_perl/5.8.3
/usr/lib/perl5/vendor_perl/5.8.2
/usr/lib/perl5/vendor_perl/5.8.1
/usr/lib/perl5/vendor_perl/5.8.0
/usr/lib/perl5/vendor_perl
.

---
Environment for perl v5.8.5​:
HOME=/home/dmacks
LANG=POSIX
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/dmacks/bin​:/usr/kerberos/bin​:/usr/bin​:/bin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/X11R6/bin​:/usr/bin/games​:.
PERL5LIB=/home/dmacks/lib/perl5/site_perl​:/home/dmacks/lib64/perl5
PERL_BADLANG (unset)
SHELL=/bin/tcsh

--
Tim Jenness
JAC software
http​://www.jach.hawaii.edu/~timj

@p5pRT
Copy link
Author

p5pRT commented May 30, 2008

p5p@spam.wizbit.be - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant