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