This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

System(command) call returns immediately, command still running



Hello Cygwin mailing list participants !

I have a problem with the cygwin run-time environment
under a common circumstance and was hoping someone
in the mailing list has some ideas regarding this.

main() { system(command); } works fine, however
when I run a similiar instruction from a dll
accessed from a non-cygwin application - I can
see the "command" run in the background even
after the .dll code I invoked is over and done
with.

I think this is related to the problems I have
using stdin, stdout, stderr and other general
problems with the run-time environment in such
a situation.  The other problems, I re-coded to
work around.  This problem - I don't see the
solution.  Fork/exec() is not the way to go with
me.  Pipe() won't work if std* is unusuable.
I think system() was my last option.  I do have
another work around, but it is such a hack
it makes me choke and probably won't be practical.

I want the run-time to know enough that when
system(command) spawns command - it knows to wait
until command finishes before returning.

I've included the cmex script which contains
the dll initialization code also.

Thank You !

Rob Morris












#!bash

# required import libraries
IMPDEFS="matlab.exe libmx.dll libmccmx.dll libmmfile.dll libmcc.dll libmatlb.dll libmat.dll"

# ***Fill in your path to libcygwin.a here (with no trailing slash)***
LIBPATH=/cygwin-b20/H-i586-cygwin32/i586-cygwin32/lib

# ***Fill in your path to the matlab 5 root here (with no trailing slash)***
MATLAB=/home/matlab

# ***Fill in your path to place to store .def files generated by this script
LIBMEX=$MATLAB/bin/implibs

# check for arguments
if [ $# -lt 1 ]; then
 echo "usage: cmex [-cig5] source"
 exit
fi

debug=0
inline=0
type=-mno-cygwin
arch=i686
while getopts cig5? v; do
 if [ "$v" == "?" ]; then
  echo "usage: cmex [-cig5] source"
  echo "   c : link to cygwin1.dll (default:mingw)"
  echo "   i : inline array access"
  echo "   g : include debug info"
  echo "   5 : optimize for pentium (default:686)"
  exit

 else
  case $v in
   (g) debug=1;;
   (i) inline=1;;
   (5) arch=i586;;
   (c) type= ;;
  esac
 fi
done

while [ $OPTIND -gt 1 ]; do
 shift
 OPTIND=$(($OPTIND - 1))
done

# debug or what?
if [ $debug -eq 1 ]; then
 gccopts="-Wall -g $type"
else
 gccopts="-Wall -O6 $type -march=$arch -ffast-math -fstrict-aliasing -malign-double -DDODS_DEBUG -DHAVE_CONFIG_H -DUSE_LIBGXX_INLINES -DARCH_32BIT -DV4_COMPAT -I/home/rmorris/data/build/DODS/include -I/home/matlab/extern/include -I/home/rmorris/data/build/DODS/packages-2.17/include -I/home/rmorris/data/build/DODS/packages-2.17/include/w3c -I/usr/local/include"
fi

# inline array access?
if [ $inline -eq 0 ]; then
 rcopts=
else
 rcopts="--define ARRAY_ACCESS_INLINING"
 gccopts="$gccopts -DARRAY_ACCESS_INLINING"
fi

# source file name(s)
source=$*
base=${1%.*}
objs=${*//%.*/.o}

# Compile source file(s):
echo "windres $rcopts -i $MATLAB/extern/include/mexversion.rc -o mexversion.o"
windres $rcopts -i $MATLAB/extern/include/mexversion.rc -o mexversion.o || exit
echo "gcc -c $gccopts -DMATLAB_MEX_FILE -I$MATLAB/extern/include ${source}"
gcc -c $gccopts -DMATLAB_MEX_FILE -I$MATLAB/extern/include ${source} || exit

# Create fixup.o which is needed to terminate the
# import list and the relocation section in the dll.
cat > fixup.c << EOF
/* Copied from winsup/dcrt0.cc in the cygwin32 source distribution. */
asm(".section .idata\$3\n" ".long 0,0,0,0, 0,0,0,0");
/* Next one is needed to properly terminate the .reloc section in the dll
*/
asm(".section .reloc\n" ".long 0,8");
EOF
gcc -c $gccopts fixup.c

# Create a very minimalist startup routine for the dll.
# C copy of winsup/init.cc in the cygwin32 source distribution.
cat > init.c << EOF
#include <windows.h>
#include <stdio.h>

extern void __main( void );
extern struct _reent *__imp_reent_data;
extern void cygwin_crt0( void *mainFunc );

static struct Globals
{
  HANDLE cygwinDLLEvent;
  HANDLE cygwinDLLThread;
} G;

static int MLXCygwinDLLCallback(int argc,char **argv)
{
   __main();  /*  Initialize C++ runtime ...  */
   G.cygwinDLLEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
   WaitForSingleObject(G.cygwinDLLEvent,INFINITE);
   return 0;
}

static DWORD WINAPI initCygwinDLL(void *dummy)
{
   cygwin_crt0(MLXCygwinDLLCallback);
   return 0;
}

int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr)
{
   DWORD threadId;
   _impure_ptr = __imp_reent_data;

   switch (reason)
    {
    case DLL_PROCESS_ATTACH:
      G.cygwinDLLThread = CreateThread(NULL,0,initCygwinDLL,(void *)NULL,
        0,&threadId);
      SetThreadPriority(G.cygwinDLLThread,THREAD_PRIORITY_HIGHEST);
      break;
    case DLL_PROCESS_DETACH:
      PulseEvent(G.cygwinDLLEvent);
      break;
    case DLL_THREAD_ATTACH:
      break;
    case DLL_THREAD_DETACH:
      break;
    }

  return 1;
}
EOF
gcc -c $gccopts init.c

# create import libraries if needed...
# Note:
#    Dlltool release does not like .def files to start with a line 'LIBRARY
#    '.  Therefore this workaround: extract library name from line 1
#    into variable libname and feed dlltool with a .def file with the 1st
#    line stripped so the .def file starts with the line 'EXPORTS'

IMPLIBS=
if [ ! -d $LIBMEX ];then
 mkdir -p $LIBMEX
fi
for libname in ${IMPDEFS}; do
 if [ ! -f $LIBMEX/${libname%.*}.a ];then
  cd $MATLAB/bin
  echo "Creating $libname import library..."
#mbs...  tail +2l $MATLAB/extern/include/matlab.def > temp.def
#mbs...
  if [ "$libname" == "matlab.exe" ]; then
     tail +2l $MATLAB/extern/include/matlab.def > temp.def
  else
     echo "tail +2 $MATLAB/extern/include/${libname%.*}.def > temp.def"
     tail +2 $MATLAB/extern/include/${libname%.*}.def > temp.def
  fi
#mbs...
  echo dlltool --def temp.def --dllname $libname --output-lib $LIBMEX/${libname%.*}.a
  dlltool --def temp.def --dllname $libname --output-lib $LIBMEX/${libname%.*}.a || exit
  rm temp.def
  cd -
 else
  echo "Will use existing import library $LIBMEX/${libname%.*}.a"
 fi
 IMPLIBS="${IMPLIBS} $LIBMEX/${libname%.*}.a"
done

# Make .def file:
echo EXPORTS > ${base}.def
echo mexFunction >> ${base}.def

# Link DLL.
echo 'Linking DLL...'
dllwrap -o ${base}.dll --def ${base}.def --entry _dll_entry@12 \
 ${objs} init.o fixup.o mexversion.o ${IMPLIBS} $LIBPATH/libcygwin.a /usr/local/lib/libcygipc.a /usr/local/lib/librpclib.a

# Clean up
rm ${base}.o init.c init.o fixup.c fixup.o mexversion.o ${base}.def



--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]