compiling lua

Carlos carlos-smith at sympatico.ca
Wed Sep 17 19:04:15 PDT 2008


: is anybody able to compile lua 5.1.4 with dmc?

Using: Digital Mars C/C++ Compiler Version 8.51.0n
    and lua 5.1.4 source code.

The following command:
    dmc -DLUA_WIN -DWITH_POPEN -olua.exe lua.c @c.lst popen.c

does produce lua.exe:

E:\lua-5.1.4\src>lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>

When tested with the following lua program:

  f = io.popen("cmd.exe /c dir *.*", "r")
  for line in f:lines() do   -- line 5
    print(line)
  end
  io.close(f)

produce a directory listing, but terminates with an error:

---[ data snipped ] ---

               2 Rép(s)  69,243,314,176 octets libres
E:\lua-5.1.4\src\lua.exe: pp.lua:5: Bad file descriptor
stack traceback:
        [C]: in function '(for generator)'
        pp.lua:5: in main chunk
        [C]: ?

And, i think it's a problem within the DMC runtime.
I used Visual C++ V6, to compile Lua, making sure i am using
the custom _Popen and _Pclose, and lua.exe works fine.
ie, the pp.lua program does not terminate in error.

There has been problems in the past with fdopen().

You will find the popen.c source code at the end of this post.

i had to modify luaconf.h (to force usa of custom popen):

#elif defined(LUA_WIN)
  #ifdef WITH_POPEN
    #define lua_popen(L,c,m) ((void)L, _Popen(c,m))
    #define lua_pclose(L,file) ((void)L, (_Pclose(file) != -1))
  #else
    #define lua_popen(L,c,m) ((void)L, _popen(c,m))
    #define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
  #endif

and liolib.c (to declare _Popen and _Pclose):

#ifdef WITH_POPEN
extern FILE *_Popen(const char*,const char*);
extern int _Pclose(FILE*);
#endif

--- popen.c ---

/*
 * COPYRIGHT:   See COPYING in the top level directory
 * PROJECT:     ReactOS system libraries
 * FILE:        lib/crt/??????
 * PURPOSE:     Unknown
 * PROGRAMER:   Unknown
 * UPDATE HISTORY:
 *    25/11/05: Created
 */

#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include <io.h>
#include <fcntl.h>

FILE *_Popen(const char*,const char*);
int _Pclose(FILE*);
FILE *_Popencmd(const char*,const char*);

FILE *_Popen( const char *command, const char *mode )
{
  char *szCmdLine=NULL;
  char *szComSpec=NULL;
  char *s;
  FILE *pf;
  HANDLE hReadPipe, hWritePipe;
  int fd;
  BOOL result;
  STARTUPINFO StartupInfo;
  PROCESS_INFORMATION ProcessInformation;
  SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

  if( command == NULL )
  {
    printf("command==null\n");
    return( NULL );
  }

  if( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024))
  {
    fprintf(stderr, "CreatePipe error\n");
    return NULL;
  }

  memset(&StartupInfo, 0, sizeof(STARTUPINFO));
  StartupInfo.cb = sizeof(STARTUPINFO);

  if (*mode == 'r' )
  {
   StartupInfo.hStdOutput = hWritePipe;
   StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  }
  else if ( *mode == 'w' )
  {
   StartupInfo.hStdInput = hReadPipe;
   StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  }

  result = CreateProcess(
    NULL,
   (char*) command,
  NULL,
  NULL,
  TRUE,
  0,
  NULL,
  NULL,
  &StartupInfo,
  &ProcessInformation);

  if (result == FALSE)
  {
    CloseHandle(hReadPipe);
    CloseHandle(hWritePipe);
    fprintf(stderr,"CreateProcess error\n");
    return NULL;
  }

  CloseHandle(ProcessInformation.hThread);
  if( *mode == 'r' )
  {
    fd = _open_osfhandle((int)hReadPipe, _O_RDONLY|_O_TEXT);
    CloseHandle(hWritePipe);
  }
  else
  {
    fd = _open_osfhandle((int)hWritePipe, _O_WRONLY|_O_TEXT);
    CloseHandle(hReadPipe);
  }

  pf = fdopen(fd,mode);
  return( pf );
}

int _Pclose( FILE *pp )
{
  return fclose(pp);
}


FILE *_Popencmd(const char *cmd, const char *mode)
{
  FILE *f;
  char *fullcommand, *comspec;

  comspec = getenv("ComSpec");
  if(comspec==0)
    comspec = "cmd.exe";

  fullcommand = (char*) malloc( 4 + strlen(comspec) + strlen(cmd) );
  if(fullcommand==0)
    return 0;
  sprintf(fullcommand, "%s /c %s", comspec, cmd);
  f = _Popen(fullcommand, mode);
  free(fullcommand);
  return f;
}


#ifdef UNITTEST

int main( int argc, char ** argv )
{
  char buf[1024];
  FILE *f;

  //f = popen( "cmd.exe /c dir *.c /b", "rw" );
  f = popen( "netstat -an", "r" );
  if( f == 0 )
  { printf( "_popen error\n" );
    return 0;
  }

  while( fgets(buf, 1024, f) )
    printf( "%s", buf );
  pclose( f );

  return 0;
}

#endif


-- Carlos







More information about the Digitalmars-d-learn mailing list