Mail Archives: cygwin/2011/05/29/07:40:28
Actually there are two different problems related to my implementation of a
Common Lisp environment, ecl (http://ecls.sf.net)
The first one has to do with fork() not working, due to the fact that ECL
injects DLLs using dlopen() and they are then improperly loaded. I have seen in
the mailing list that this is a known problem with no solution so far.
To cope with that problem I had to resort to CreateProcess, a Windows routine
that allows us to redirect the input/output/error channels of a process as
needed. The problem I have is that the C streams that result from the Windows
handle can only be read with read() and not with fread(). This is a problem
because the ECL environment needs buffered I/O, with locking and so on, and we
rely on C streams for that.
I attach a small test program that segfaults when using fread() on the stream
created with fdopen(). notice that read() works.
Any help is really welcome and appreciated.
Juanjo
/* -*- mode: c; c-basic-offset: 8 -*- */
/*
unixsys.s -- Unix shell interface.
*/
/*
Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya.
Copyright (c) 1990, Giuseppe Attardi.
Copyright (c) 2001, Juan Jose Garcia Ripoll.
ECL is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
See file '../Copyright' for full details.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/cygwin.h> /* For cygwin_attach_handle_to_fd() */
#include <windows.h>
int main()
{
BOOL ok;
STARTUPINFO st_info;
PROCESS_INFORMATION pr_info;
HANDLE child_stdout, child_stdin, child_stderr;
HANDLE current = GetCurrentProcess();
SECURITY_ATTRIBUTES attr;
int parent_read;
ZeroMemory(&attr, sizeof(attr));
attr.nLength = sizeof(attr);
attr.lpSecurityDescriptor = NULL;
attr.bInheritHandle = TRUE;
/* Creates a pipe that we can write to and the
child reads from. We duplicate one extreme of the
pipe so that the child does not inherit it. */
child_stdin = NULL;
child_stderr = NULL;
{
HANDLE tmp;
ok = CreatePipe(&tmp, &child_stdout, &attr, 0);
if (ok) {
ok = DuplicateHandle(current, tmp, current,
&tmp, 0, FALSE,
DUPLICATE_CLOSE_SOURCE |
DUPLICATE_SAME_ACCESS);
if (ok) {
parent_read =
cygwin_attach_handle_to_fd
(0, -1, tmp, S_IRWXU, GENERIC_READ);
printf("parent_read=%d\n",parent_read);
if (parent_read < 0)
printf("open_osfhandle failed\n");
}
}
}
/* Launches the process
*/
ZeroMemory(&st_info, sizeof(st_info));
st_info.cb = sizeof(st_info);
st_info.lpTitle = NULL; /* No window title, just exec name */
st_info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; /* Specify
std{in,out,err} */
st_info.wShowWindow = SW_HIDE;
st_info.hStdInput = child_stdin;
st_info.hStdOutput = child_stdout;
st_info.hStdError = child_stderr;
ZeroMemory(&pr_info, sizeof(pr_info));
ok = CreateProcess(NULL, "c:\\cygwin\\bin\\echo.exe \"--version\"",
NULL, NULL, /* lpProcess/ThreadAttributes */
TRUE, /* Inherit handles (for files) */
/*CREATE_NEW_CONSOLE |*/
0 /*(input == Ct || output == Ct || error == Ct ? 0 : CREATE_NO_WINDOW)*/,
NULL, /* Inherit environment */
NULL, /* Current directory */
&st_info, /* Startup info */
&pr_info); /* Process info */
if (!ok) {
char *message;
printf("ABORT\n");
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
0, GetLastError(), 0, (void*)&message, 0, NULL);
printf("%s\n", message);
LocalFree(message);
return 1;
}
/* Now reads. No problem with C read */
{
char c[100];
int n = read(parent_read, c, 10);
c[n] = 0;
printf("c[%d] = %s\n", n, c);
}
/* But this segfaults */
{
FILE *f= fdopen(parent_read, "rb");
char c[100];
int n;
printf("fp=%p\n", f);
n = fread(c, 4, 1, f);
c[n] = 0;
printf("c[%d] = %s\n", n, c);
}
return 0;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -