Sweden-Number/scheduler/client.c

309 lines
8.1 KiB
C
Raw Normal View History

Release 980712 Sun Jul 12 16:23:36 1998 Alexandre Julliard <julliard@lrc.epfl.ch> * [server/*] [scheduler/client.c] (new files) [scheduler/sysdeps.c] [scheduler/thread.c] [scheduler/process.c] Beginnings of client/server communication for inter-process synchronisation. Sat Jul 11 19:45:45 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de> * [include/bitmap.h] [objects/bitmap.c] [objects/dib.c] [objects/oembitmap.c] Speed up DIB section handling by using pre-allocated colormap and XImage. Moved DIB section data out of general BITMAPOBJ structure. Bugfix: GetDIBits32 would overwrite one byte beyond bitmap data. * [if1632/shell.spec] [if1632/kernel.spec] [win32/kernel32.c] More verbose error message if ThunkConnect fails. Implemented KERNEL_475. * [files/profile.c] [ole/ole2nls.c] Minor bugfixes. * [if1632/builtin.c] [if1632/kernel.spec] [include/task.h] [loader/ne/module.c] [loader/task.c] Implemented KERNEL.THHOOK. * [if1632/wprocs.spec] [include/process.h] [msdos/dpmi.c] [msdos/vxd.c] Implemented Win32s VxD services (W32S.386). Sat Jul 11 17:52:23 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk> * [graphics/x11drv/xfont.c] [graphics/x11drv/text.c] [include/x11font.h] Improve handling of rotated X11 fonts. Metrics/extents should now be correct. ExtTextOut should behave better (still doesn't handle lpDx). * [graphics/painting.c] DrawFocusRect32: Don't do anything if width or height are zero. Sat Jul 11 15:21:35 1998 Andreas Mohr <100.30936@germany.net> * [files/profile.c] [include/windows.h] The length arguments of *Profile*() need to be treated as UINTxx instead of INTxx. * [graphics/env.c] [graphics/win16drv/init.c] [include/print.h] [misc/printdrv.c] Many printer driver fixes/changes (many thanks go to Huw !). Most printers should work again ;) * [memory/atom.c] Fixed ATOM_AddAtom to store atoms exactly like Windows. * [*/*] Fixed misc compiler warnings. Fri Jul 10 15:58:36 1998 Marcus Meissner <marcus@jet.franken.de> * [files/drive.c] Fixed GetDriveType16 to return DRIVE_REMOTE again. * [loader/pe_image.c][loader/module.c] Look for modules that have the same modulename or the same filename (they sometimes differ). Fixed up fixup_imports, removed one of the loops. * [windows/winpos.c] Added some NULL ptr checks. Needs more. * [graphics/ddraw.c] Some stubs added. * [if1632/snoop.c] Updated, made WINELIB compatible. Fri Jul 10 04:39:56 1998 Douglas Ridgway <ridgway@winehq.com> * [objects/enhmetafile.c] [relay32/gdi32.spec] Small tweaks for documentation system. Thu Jul 9 22:00:18 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de> * [controls/commctrl.c][include/commctrl.h][relay32/comctl32.spec] Fixed GetEffectiveClientRect, CreateToolbarEx and CreateMappedBitmap. Added stub for ShowHideMenuCtl. Added some documentation. * [documentation/common_controls] Added and updated some information. * [controls/toolbar.c][include/toolbar.h] Added string support. * [misc/shell.c][misc/shellord.c][relay32/shell.spec] Changed names of undocumented functions to their real names and fixed the export table. * [controls/imagelist.c][relay32/comctl32.spec] Added stub for ImageList_SetFilter. Fixed some minor bugs and typos. * [objects/font.c][include/windows.h][relay32/gdi32.spec] Added stubs for GetCharacterPlacement32[A/W]. * [objects/region.c][relay32/gdi32.spec] Added stub for UNDOCUMENTED GetRandomRgn. * [controls/commctrl.c][controls/*.c][include/*.h] Added dummy listview, pager, rebar, tooltips, trackbar and treeview control. This keeps some programs from complaining. Thu Jul 9 11:23:58 1998 Rein Klazes <rklazes@casema.net> * [graphics/painting.c] [graphics/*/init.c] [graphics/x11drv/graphics.c] [relay32/gdi32.spec] [if1632/gdi.spec] [include/gdi.h] [include/x11drv.h] Implemented drawing bezier curves: PolyBezier16/32 and PolyBezierTo16/32. * [graphics/x11drv/graphics.c] Improved accuracy of several graphic routines, especially the drawing of pie's. * [include/windows.h] [misc/spy.c] Added 25 window messages related to programs based on MFC and/or OLE. Wed Jul 8 22:00:00 1998 James Juran <jrj120@psu.edu> * [documentation/wine.man] Updated manpage. * [wine.ini] Added section for Win95Look=true (commented out by default). Wed Jul 8 06:23:19 1998 Matthew Becker <mbecker@glasscity.net> * [misc/registry.c] Fixed a crash in RegEnumValue32A when the dwType parameter is NULL. * [programs/regtest/regtest.c] Improved the printing of errors. * [misc/ntdll.c] Added stub for RtlFormatCurrentUserKeyPath. * [win32/console.c] Added stub for ScrollConsoleScreenBuffer. Mon Jul 6 16:41:47 1998 Per Lindström <pelinstr@algonet.se> * [include/windows.h] [relay32/kernel.spec] [win32/newfns.c] Added stubs for SleepEx and TerminateProcess. * [rc/README] Corrected a grammatical error. Mon Jul 3 12:00:00 1998 Juergen Schmied <juergen.schmied@metronet.de> * [misc/shellord.c] Put some TRACE in. * [memory/string.c] Deleted unused variable in lstrcmpi32A. * [include/windows.h][memory/string.c] Added functions WideCharToLocal32 LocalToWideChar32 for OLE-strings * [include/shlobj.h][include/winerror.h][misc/shell.c] [ole/folders.c] Added definition of internal class pidlmgr. Changed definitions of EnumIDList, IShellFolder. Added some OLE error constants. Implemented EnumIDList, IShellFolder, IClassFactory, PidlMgr, SHELL32_DllGetClassObject, SHGetDesktopFolder, SHGetSpecialFolderLocation (half), SHGetPathFromIDList (!!This stuff is not finished yet!!) * [include/windows.h][misc/network][reley32/mpr.spec] Added stubs for WNetConnectionDialog32[A|W|API]. Added struct LPCONNECTDLGSTRUCT32[A|W] and some constants. Added some SetLastError(WN_NO_NETWORK) to the stubs. Fixed bufferhandling in WNetCancelConnection Added stub for MultinetGetErrorText[A|W] * [ole/ole2nls.c] Rewrote GetTimeFormat32A. Fri Jul 3 10:27:30 1998 Michael Poole <poole+@andrew.cmu.edu> * [graphics/ddraw.c] [tsx11/X11_calls] Implement IDirectDrawPalette_GetEntries. Use CopyColormapAndFree to avoid erasing previously-set palette entries. * [graphics/ddraw.c] [include/ddraw.h] [tools/make_X11wrappers] [tsx11/X11_calls] Provide a preliminary, not-yet-working framework for doing DirectDraw via Xlib or XShm as well as DGA. Tue Jun 30 00:16:09 1998 Marcel Baur <mbaur@g26.ethz.ch> * [ole/nls/*.nls] Added remaining 22 locales (including arabic locales).
1998-07-12 21:29:36 +02:00
/*
* Client part of the client/server communication
*
* Copyright (C) 1998 Alexandre Julliard
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include "process.h"
#include "thread.h"
#include "server.h"
#include "winerror.h"
/***********************************************************************
* CLIENT_SendRequest_v
*
* Send a request to the server.
*/
static void CLIENT_SendRequest_v( enum request req, int pass_fd,
struct iovec *vec, int veclen )
{
THDB *thdb = THREAD_Current();
struct { struct cmsghdr hdr; int fd; } cmsg =
{ { sizeof(cmsg), SOL_SOCKET, SCM_RIGHTS }, pass_fd };
struct msghdr msghdr;
struct header head;
int i, ret, len;
msghdr.msg_name = NULL;
msghdr.msg_namelen = 0;
assert( veclen > 0 );
vec[0].iov_base = &head;
vec[0].iov_len = sizeof(head);
msghdr.msg_iov = vec;
msghdr.msg_iovlen = veclen;
for (i = len = 0; i < veclen; i++) len += vec[i].iov_len;
assert( len <= MAX_MSG_LENGTH );
head.type = req;
head.len = len;
head.seq = thdb->seq++;
if (pass_fd == -1) /* no fd to pass */
{
msghdr.msg_control = NULL;
msghdr.msg_controllen = 0;
}
else
{
msghdr.msg_control = &cmsg;
msghdr.msg_controllen = sizeof(cmsg);
}
if ((ret = sendmsg( thdb->socket, &msghdr, 0 )) < len)
{
fprintf( stderr, "Fatal protocol error: " );
if (ret == -1) perror( "sendmsg" );
else fprintf( stderr, "partial msg sent %d/%d\n", ret, len );
ExitThread(1);
}
/* we passed the fd now we can close it */
if (pass_fd != -1) close( pass_fd );
}
/***********************************************************************
* CLIENT_SendRequest
*
* Send a request to the server.
*/
static void CLIENT_SendRequest( enum request req, int pass_fd,
int n, ... /* arg_1, len_1, etc. */ )
{
struct iovec vec[16];
va_list args;
int i;
n++; /* for vec[0] */
assert( n < 16 );
va_start( args, n );
for (i = 1; i < n; i++)
{
vec[i].iov_base = va_arg( args, void * );
vec[i].iov_len = va_arg( args, int );
}
va_end( args );
return CLIENT_SendRequest_v( req, pass_fd, vec, n );
}
/***********************************************************************
* CLIENT_WaitReply_v
*
* Wait for a reply from the server.
* Returns the error code (or 0 if OK).
*/
static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd,
struct iovec *vec, int veclen )
{
THDB *thdb = THREAD_Current();
struct { struct cmsghdr hdr; int fd; } cmsg =
{ { sizeof(cmsg), SOL_SOCKET, SCM_RIGHTS }, -1 };
struct msghdr msghdr;
struct header head;
int ret, remaining;
assert( veclen > 0 );
vec[0].iov_base = &head;
vec[0].iov_len = sizeof(head);
msghdr.msg_name = NULL;
msghdr.msg_namelen = 0;
msghdr.msg_iov = vec;
msghdr.msg_iovlen = veclen;
msghdr.msg_control = &cmsg;
msghdr.msg_controllen = sizeof(cmsg);
if ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1)
{
fprintf( stderr, "Fatal protocol error: " );
perror("recvmsg");
ExitThread(1);
}
if (ret < sizeof(head))
{
fprintf( stderr,
"Fatal protocol error: partial header received %d/%d\n",
ret, sizeof(head));
ExitThread(1);
}
if ((head.len < sizeof(head)) || (head.len > MAX_MSG_LENGTH))
{
fprintf( stderr, "Fatal protocol error: header length %d\n",
head.len );
ExitThread(1);
}
if (head.seq != thdb->seq++)
{
fprintf( stderr,
"Fatal protocol error: sequence %08x instead of %08x\n",
head.seq, thdb->seq - 1 );
ExitThread(1);
}
if (head.type != ERROR_SUCCESS)
{
SetLastError( head.type );
}
else if (passed_fd)
{
*passed_fd = cmsg.fd;
cmsg.fd = -1;
}
if (len) *len = ret - sizeof(head);
if (cmsg.fd != -1) close( cmsg.fd );
remaining = head.len - ret;
while (remaining > 0) /* drop remaining data */
{
char buffer[1024];
int len = remaining < sizeof(buffer) ? remaining : sizeof(buffer);
if ((len = recv( thdb->socket, buffer, len, 0 )) == -1)
{
fprintf( stderr, "Fatal protocol error: " );
perror( "recv" );
ExitThread(1);
}
remaining -= len;
}
return head.type; /* error code */
}
/***********************************************************************
* CLIENT_WaitReply
*
* Wait for a reply from the server.
*/
static unsigned int CLIENT_WaitReply( int *len, int *passed_fd,
int n, ... /* arg_1, len_1, etc. */ )
{
struct iovec vec[16];
va_list args;
int i;
n++; /* for vec[0] */
assert( n < 16 );
va_start( args, n );
for (i = 1; i < n; i++)
{
vec[i].iov_base = va_arg( args, void * );
vec[i].iov_len = va_arg( args, int );
}
va_end( args );
return CLIENT_WaitReply_v( len, passed_fd, vec, n );
}
/***********************************************************************
* send_new_thread
*
* Send a new thread request. Helper function for CLIENT_NewThread.
*/
static int send_new_thread( THDB *thdb )
{
struct new_thread_request request;
struct new_thread_reply reply;
int len, fd[2];
if (socketpair( AF_UNIX, SOCK_STREAM, PF_UNIX, fd ) == -1)
{
SetLastError( ERROR_TOO_MANY_OPEN_FILES ); /* FIXME */
return -1;
}
request.pid = thdb->process->server_pid;
CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) );
if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) )) goto error;
if (len < sizeof(reply)) goto error;
thdb->server_tid = reply.tid;
thdb->process->server_pid = reply.pid;
if (thdb->socket != -1) close( thdb->socket );
thdb->socket = fd[0];
thdb->seq = 0; /* reset the sequence number for the new fd */
return 0;
error:
close( fd[0] );
return -1;
}
/***********************************************************************
* CLIENT_NewThread
*
* Send a new thread request.
*/
int CLIENT_NewThread( THDB *thdb )
{
extern BOOL32 THREAD_InitDone;
if (!THREAD_InitDone) /* first thread -> start the server */
{
int tmpfd[2];
char buffer[16];
if (socketpair( AF_UNIX, SOCK_STREAM, PF_UNIX, tmpfd ) == -1)
{
perror("socketpair");
exit(1);
}
switch(fork())
{
case -1: /* error */
perror("fork");
exit(1);
case 0: /* child */
close( tmpfd[0] );
sprintf( buffer, "%d", tmpfd[1] );
#ifdef EXEC_SERVER
execlp( "wineserver", "wineserver", buffer, NULL );
execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL );
execl( "./server/wineserver", "wineserver", buffer, NULL );
#endif
server_main_loop( tmpfd[1] );
exit(0);
default: /* parent */
close( tmpfd[1] );
SET_CUR_THREAD( thdb );
THREAD_InitDone = TRUE;
thdb->socket = tmpfd[0];
break;
}
}
return send_new_thread( thdb );
}
/***********************************************************************
* CLIENT_InitThread
*
* Send an init thread request. Return 0 if OK.
*/
int CLIENT_InitThread(void)
{
THDB *thdb = THREAD_Current();
struct init_thread_request init;
int len = strlen( thdb->process->env_db->cmd_line );
init.pid = getpid();
len = MIN( len, MAX_MSG_LENGTH - sizeof(init) );
CLIENT_SendRequest( REQ_INIT_THREAD, -1, 2,
&init, sizeof(init),
thdb->process->env_db->cmd_line, len );
return CLIENT_WaitReply( NULL, NULL, NULL, 0 );
}