popen2 strange behaviour within a function

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

popen2 strange behaviour within a function

Daniel Calvelo-2
To: [hidden email]
Cc: dcalvelo
Subject: popen2 strange behaviour within a function

Bug report for Octave 2.0.13.95 configured for i386-pc-linux-gnu

Description:
-----------

        When used insude a function, popen2 is unable to fecth output from
child process if it is requested immediately after input feeding (at least on
buffered input processes, like 'sort').

        In the interactive interpreter, it behaves as expected.

Repeat-By:
---------

Session transcript:
-------------------------------------------------------------------------------
Octave, version 2.0.13.95 (i386-pc-linux-gnu).
Copyright (C) 1996, 1997, 1998 John W. Eaton.
This is free software with ABSOLUTELY NO WARRANTY.
For details, type `warranty'.

octave:1> type ess
ess is the function defined from: /home/dcalvelo/lang/objc/ess.m

function e=ess(m)
   [in,out,pid] = popen2("sort","-n");
   fprintf(in,"%e\n",m)
   fclose(in)
   e=fscanf(out,"%e")
   fclose(out)
   waitpid(pid)
endfunction
octave:2> m=rand(10,1);
octave:3> ess(m)
ans = 19
ans = 0
e = [](0x1)
ans = 0
ans = 2920
ans = [](0x1)
octave:4>    [in,out,pid] = popen2("sort","-n");
octave:5>    fprintf(in,"%e\n",m)
ans = 19
octave:6>    fclose(in)
ans = 0
octave:7>    e=fscanf(out,"%e")
e =

  0.21444
  0.21812
  0.24042
  0.30588
  0.39884
  0.49816
  0.57548
  0.66786
  0.84487
  0.94233

octave:8>    fclose(out)
ans = 0
octave:9>    waitpid(pid)
ans = -1
octave:10>
-------------------------------------------------------------------------------

Fix:
---

        Wish I knew <sigh>.

Configuration (please do not edit this section):
-----------------------------------------------

uname output:     Linux llorio 2.2.5 #2 Thu Apr 8 19:43:40 CEST 1999 i586 unknown
configure opts:   --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --with-g77 --enable-dl --enable-shared --enable-lite-kernel --host i386-linux
Fortran compiler: g77
FFLAGS:           -O2
F2C:              
F2CFLAGS:        
FLIBS:            -lg2c -lm -L/usr/lib/gcc-lib/i486-linux/egcs-2.91.60 -lm
CPPFLAGS:        
INCFLAGS:         -I/usr/include -I/usr/include/octave-2.0.13.95
C compiler:       egcc, version 2.7.2.3
CFLAGS:           -DHAVE_CONFIG_H -mieee-fp -O2
CPICFLAG:         -fPIC
C++ compiler:     c++, version 2.91.60 19981201 (egcs-1.1.1 release)
CXXFLAGS:         -DHAVE_CONFIG_H -mieee-fp -fno-rtti -fno-exceptions -fno-implicit-templates -O2
CXXPICFLAG:       -fPIC
LDFLAGS:          -s
LIBFLAGS:         -L/usr/lib/octave-2.0.13.95
RLD_FLAG:         -Xlinker -rpath -Xlinker /usr/lib/octave-2.0.13.95
TERMLIBS:         -lncurses
LIBS:            
LEXLIB:          
LIBPLPLOT:        
LIBDLFCN:        
DEFS:

  -DOCTAVE_SOURCE=1 -DSEPCHAR=':' -DSEPCHAR_STR=":" -DUSE_READLINE=1
  -D__NO_MATH_INLINES=1 -DCXX_NEW_FRIEND_TEMPLATE_DECL=1 -DHAVE_LIBM=1
  -DF77_APPEND_UNDERSCORE=1 -DOCTAVE_LITE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4
  -DSIZEOF_LONG=4 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DNPOS=string::npos
  -DSTDC_HEADERS=1 -DHAVE_DIRENT_H=1 -DTIME_WITH_SYS_TIME=1
  -DHAVE_SYS_WAIT_H=1 -DHAVE_ASSERT_H=1 -DHAVE_CURSES_H=1 -DHAVE_DLFCN_H=1
  -DHAVE_FCNTL_H=1 -DHAVE_FLOAT_H=1 -DHAVE_FNMATCH_H=1 -DHAVE_GLOB_H=1
  -DHAVE_GRP_H=1 -DHAVE_LIMITS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_NAN_H=1
  -DHAVE_NCURSES_H=1 -DHAVE_PWD_H=1 -DHAVE_SGTTY_H=1 -DHAVE_STDLIB_H=1
  -DHAVE_STRING_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_RESOURCE_H=1
  -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TIME_H=1
  -DHAVE_SYS_TIMES_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_UTSNAME_H=1
  -DHAVE_TERMCAP_H=1 -DHAVE_TERMIO_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_UNISTD_H=1
  -DHAVE_VARARGS_H=1 -DHAVE_ATEXIT=1 -DHAVE_BCOPY=1 -DHAVE_BZERO=1
  -DHAVE_DUP2=1 -DHAVE_ENDGRENT=1 -DHAVE_ENDPWENT=1 -DHAVE_EXECVP=1
  -DHAVE_FCNTL=1 -DHAVE_FORK=1 -DHAVE_GETCWD=1 -DHAVE_GETEGID=1
  -DHAVE_GETEUID=1 -DHAVE_GETGID=1 -DHAVE_GETGRENT=1 -DHAVE_GETGRGID=1
  -DHAVE_GETGRNAM=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETPGRP=1 -DHAVE_GETPID=1
  -DHAVE_GETPPID=1 -DHAVE_GETPWENT=1 -DHAVE_GETPWNAM=1 -DHAVE_GETPWUID=1
  -DHAVE_GETTIMEOFDAY=1 -DHAVE_GETUID=1 -DHAVE_GETWD=1 -DHAVE_LSTAT=1
  -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1 -DHAVE_MKFIFO=1 -DHAVE_ON_EXIT=1
  -DHAVE_PIPE=1 -DHAVE_PUTENV=1 -DHAVE_RENAME=1 -DHAVE_RINDEX=1
  -DHAVE_RMDIR=1 -DHAVE_SETGRENT=1 -DHAVE_SETPWENT=1 -DHAVE_SETVBUF=1
  -DHAVE_SIGACTION=1 -DHAVE_SIGPENDING=1 -DHAVE_SIGPROCMASK=1
  -DHAVE_SIGSUSPEND=1 -DHAVE_STAT=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1
  -DHAVE_STRERROR=1 -DHAVE_STRNCASECMP=1 -DHAVE_TEMPNAM=1 -DHAVE_UMASK=1
  -DHAVE_UNLINK=1 -DHAVE_USLEEP=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
  -DHAVE_WAITPID=1 -DSMART_PUTENV=1 -DHAVE_PROGRAM_INVOCATION_NAME=1
  -DHAVE_LIBDL=1 -DHAVE_DLOPEN=1 -DHAVE_DLSYM=1 -DHAVE_DLERROR=1
  -DHAVE_DLCLOSE=1 -DWITH_DL=1 -DWITH_DYNAMIC_LINKING=1 -DHAVE_FINITE=1
  -DHAVE_ISNAN=1 -DHAVE_ISINF=1 -DHAVE_ACOSH=1 -DHAVE_ASINH=1
  -DHAVE_ATANH=1 -DHAVE_ERF=1 -DHAVE_ERFC=1 -DHAVE_ST_BLKSIZE=1
  -DHAVE_ST_BLOCKS=1 -DHAVE_ST_RDEV=1 -DHAVE_TM_ZONE=1 -DHAVE_GR_PASSWD=1
  -DEXCEPTION_IN_MATH=1 -DRETSIGTYPE=void -DSYS_SIGLIST_DECLARED=1
  -DHAVE_SYS_SIGLIST=1 -DHAVE_POSIX_SIGNALS=1 -DHAVE_GETRUSAGE=1
  -DHAVE_TIMES=1 -DGNUPLOT_HAS_MULTIPLOT=1 -DGNUPLOT_HAS_FRAMES=1


Reply | Threaded
Open this post in threaded view
|

popen2 strange behaviour within a function

John W. Eaton-6
On 14-Apr-1999, Daniel Calvelo <[hidden email]> wrote:

| To: [hidden email]
| Cc: dcalvelo
| Subject: popen2 strange behaviour within a function
|
| Bug report for Octave 2.0.13.95 configured for i386-pc-linux-gnu
|
| Description:
| -----------
|
| When used insude a function, popen2 is unable to fecth output from
| child process if it is requested immediately after input feeding (at least on
| buffered input processes, like 'sort').
|
| In the interactive interpreter, it behaves as expected.

As far as I know, this is the result of a race condition.  If you
write:

  function e=ess(m)
    [in,out,pid] = popen2("sort","-n");
    fprintf(in,"%e\n",m)
    fclose(in)
    sleep(seconds_to_sleep)
    e=fscanf(out,"%e")
    fclose(out)
    waitpid(pid)
  endfunction

for a sufficiently large value of `seconds_to_sleep', I think you will
see the results you expect.  The reason it works when you type the
commands at the command line is that there is a sufficient delay to
allow the subprocess to run.

Note that it may work in some cases to call waitpid instead of
sleeping, but only if the input to and output from the subprocess are
sufficiently small amounts of data.  For example, try the following

  function e=ess(m)
    [in,out,pid] = popen2("sort","-n");
    fprintf(in,"%e\n",m)
    fclose(in)
    waitpid(pid)
    e=fscanf(out,"%e")
    fclose(out)
  endfunction

for larger and larger vectors.  Given enough data (not really all that
much, either), this solution will hang on the waitpid call.

If anyone knows the correct solution for avoiding this race condition,
it would be great if you could clue the rest of us in on the secret.

Thanks,

jwe


| Repeat-By:
| ---------
|
| Session transcript:
| -------------------------------------------------------------------------------
| Octave, version 2.0.13.95 (i386-pc-linux-gnu).
| Copyright (C) 1996, 1997, 1998 John W. Eaton.
| This is free software with ABSOLUTELY NO WARRANTY.
| For details, type `warranty'.
|
| octave:1> type ess
| ess is the function defined from: /home/dcalvelo/lang/objc/ess.m
|
| function e=ess(m)
|    [in,out,pid] = popen2("sort","-n");
|    fprintf(in,"%e\n",m)
|    fclose(in)
|    e=fscanf(out,"%e")
|    fclose(out)
|    waitpid(pid)
| endfunction
| octave:2> m=rand(10,1);
| octave:3> ess(m)
| ans = 19
| ans = 0
| e = [](0x1)
| ans = 0
| ans = 2920
| ans = [](0x1)
| octave:4>    [in,out,pid] = popen2("sort","-n");
| octave:5>    fprintf(in,"%e\n",m)
| ans = 19
| octave:6>    fclose(in)
| ans = 0
| octave:7>    e=fscanf(out,"%e")
| e =
|
|   0.21444
|   0.21812
|   0.24042
|   0.30588
|   0.39884
|   0.49816
|   0.57548
|   0.66786
|   0.84487
|   0.94233
|
| octave:8>    fclose(out)
| ans = 0
| octave:9>    waitpid(pid)
| ans = -1
| octave:10>