Subject: Re: Ctrl-Z fails to suspend Windows programs
From: John Cooper <[email-masked]>
To: "Peter A. Castro" <[email-masked]>
Cc: John Cooper <[email-masked]>, [email-masked]
Date: Fri, 18 Jun 2004 10:23:38 +0100

"Peter A. Castro" <[email-masked]> writes:

 > On Tue, 15 Jun 2004, John Cooper wrote:
 > 
 > >  > The point is that it's not about cygwin-vs-windoze apps.  It's about
 > >  > apps-that-use-console-stdin-and-stdout vs. apps-that-display-a-gui; those
 > >  > that show a gui could usefully be detached, but those that read their input
 > >  > from stdin will break if the shell detaches them.
 > 
 > Hi John,
 >   I'm the maintainer for zsh on Cygwin.
 > 
 > > Yes, you're right, the old "native" zsh option was specifically to do with GUI
 > > apps rather than "Windows" apps per se - here's the doc to for enabling the
 > > option (it was off by default):
 > >
 > >   winntwaitforguiapps: When set, makes the shell wait for win32 GUI apps to
 > >   terminate instead of spawning them asynchronously.
 > >
 > >  > I don't think there's a reliable enough mechanism by which a shell could
 > >  > detect one case from the other.
 > >
 > > Below is the code it used to determine if a program is a GUI program or not. I
 > > don't know how well it works under all conditions; however it did work fine for
 > > me.
 > >
 > > Even if not perfectly reliable, could something like this be added but disabled
 > > by default?  I for one would find it useful.
 > 
 > I guess I don't really have much of a problem with adding such a feature,
 > provided it's something that many users really want.  I can see some
 > merit to it, but is it really that much work to type '&' after the
 > command to run it in the background?

No, it's not much work to type '&' when running GUI apps; it's just that I
don't always remember and am not used to having to consider it!  At the moment,
assuming I don't want to quit the GUI app, I'm stuck with a shell window that
is essentially useless (as ^Z cannot be used to suspend the GUI app).  In
general I would have thought (Windows, at least) GUI apps are more usefully
automatically run in the background.  The only benefit to keeping them in the
foreground is that they can be terminated with ^C, but this can equally be done
with Alt-F4.  I would find such an option useful, but perhaps that is in part
due to the fact I'm used to this behavior from AmolD's old native zsh port.

Still, I'd say it's best to keep such an option off by default, to avoid
introducing any confusion.

 > Anyway, can you point me to where you got this code example?  I want to
 > see where it was originally called in zsh code and possibly adapt it to
 > the current code base.  It'll take a bit of re-writing (which I'm willing
 > to do) because this code makes liberal usage of win32 calls and
 > defines/structs, which generally aren't available/desirable to use in the
 > Cygwin runtime.  If it works well enough, though, I might submit it for
 > inclusion in the zsh base.

ftp://ftp.blarg.net/users/amol/zsh/zshsrc.tar.gz

    --- John

 > >
 > > /*
 > > How To Determine Whether an Application is Console or GUI     [win32sdk]
 > > ID: Q90493     CREATED: 15-OCT-1992   MODIFIED: 16-DEC-1996
 > > */
 > > #include <winnt.h>
 > > #define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
 > > #define xfree(p) HeapFree(GetProcessHeap(),0,(p))
 > > #define XFER_BUFFER_SIZE 2048
 > >
 > > int is_gui(char *exename) {
 > >
 > > 	HANDLE hImage;
 > >
 > > 	DWORD  bytes;
 > > 	DWORD  SectionOffset;
 > > 	DWORD  CoffHeaderOffset;
 > > 	DWORD  MoreDosHeader[16];
 > >
 > > 	ULONG  ntSignature;
 > >
 > > 	IMAGE_DOS_HEADER      image_dos_header;
 > > 	IMAGE_FILE_HEADER     image_file_header;
 > > 	IMAGE_OPTIONAL_HEADER image_optional_header;
 > >
 > >
 > > 	hImage = CreateFile(exename, GENERIC_READ, FILE_SHARE_READ, NULL,
 > > 			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 > >
 > > 	if (INVALID_HANDLE_VALUE == hImage) {
 > > 		return 0;
 > > 	}
 > >
 > > 	/*
 > > 	 *  Read the MS-DOS image header.
 > > 	 */
 > > 	if (!ReadFile(hImage, &image_dos_header, sizeof(IMAGE_DOS_HEADER),
 > > 			&bytes,NULL)){
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic) {
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	/*
 > > 	 *  Read more MS-DOS header.       */
 > > 	if (!ReadFile(hImage, MoreDosHeader, sizeof(MoreDosHeader),
 > > 			&bytes,NULL)){
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	/*
 > > 	 *  Get actual COFF header.
 > > 	 */
 > > 	CoffHeaderOffset = SetFilePointer(hImage, image_dos_header.e_lfanew,
 > > 			NULL,FILE_BEGIN);
 > >
 > > 	if (CoffHeaderOffset == (DWORD) -1){
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	CoffHeaderOffset += sizeof(ULONG);
 > >
 > > 	if (!ReadFile (hImage, &ntSignature, sizeof(ULONG),
 > > 			&bytes,NULL)){
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	if (IMAGE_NT_SIGNATURE != ntSignature) {
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	SectionOffset = CoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER +
 > > 		IMAGE_SIZEOF_NT_OPTIONAL_HEADER;
 > >
 > > 	if (!ReadFile(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER,
 > > 			&bytes, NULL)){
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	/*
 > > 	 *  Read optional header.
 > > 	 */
 > > 	if (!ReadFile(hImage, &image_optional_header,
 > > 			IMAGE_SIZEOF_NT_OPTIONAL_HEADER,&bytes,NULL)) {
 > > 		CloseHandle(hImage);
 > > 		return 0;
 > > 	}
 > >
 > > 	CloseHandle(hImage);
 > >
 > > 	if (image_optional_header.Subsystem ==IMAGE_SUBSYSTEM_WINDOWS_GUI)
 > > 		return 1;
 > > 	return 0;
 > > }
 > > int is_9x_gui(char *prog) {
 > >
 > > 	char *progpath;
 > > 	DWORD dwret;
 > > 	char *pathbuf;
 > > 	char *pext;
 > >
 > > 	pathbuf=xmalloc(MAX_PATH);
 > >
 > > 	progpath=xmalloc(MAX_PATH<<1);
 > >
 > > 	if (GetEnvironmentVariable("PATH",pathbuf,MAX_PATH) ==0) {
 > > 		goto failed;
 > > 	}
 > >
 > > 	pathbuf[MAX_PATH]=0;
 > >
 > > 	dwret = SearchPath(pathbuf,prog,".EXE",MAX_PATH<<1,progpath,&pext);
 > >
 > > 	if ( (dwret == 0) || (dwret > (MAX_PATH<<1) ) )
 > > 		goto failed;
 > >
 > > 	dprintf("progpath is %s\n",progpath);
 > > 	dwret = is_gui(progpath);
 > >
 > > 	xfree(pathbuf);
 > > 	xfree(progpath);
 > >
 > > 	return dwret;
 > >
 > > failed:
 > > 	xfree(pathbuf);
 > > 	xfree(progpath);
 > > 	return 0;
 > >
 > >
 > > }
 > >
 > >
 > >
 > >     --- John
 > >
 > > -----Original Message-----
 > > From: Dave Korn [mailto:[email-masked]]
 > > Sent: 15 June 2004 15:40
 > > To: 'John Cooper'; [email-masked]
 > > Subject: RE: Ctrl-Z fails to suspend Windows programs
 > >
 > > > -----Original Message-----
 > > > From: cygwin-owner On Behalf Of John Cooper
 > > > Sent: 15 June 2004 15:05
 > > > To: cygwin
 > > > Subject: RE: Ctrl-Z fails to suspend Windows programs
 > > >
 > > > The old native (non-cygwin) port of zsh would somehow detect if it was
 > > > about to exec a Windows app, and run it as a background process, thus
 > > > returning a zsh prompt immediately.  Could something like this be
 > > > added to cygwin bash/zsh?
 > >
 > >   AFAICS the ability is already there.  Just enter "windows_app.exe &" at a bash shell.
 > >
 > > > This was very useful.  With the cygwin zsh, I often find myself
 > > > invoking a Windows app and not being able to get back to the shell
 > > > window without first terminating the Windows app.
 > >
 > > Well, the same goes if you run a cygwin app: you don't get the prompt back until it exits.
 > >
 > > The point is that it's not about cygwin-vs-windoze apps.  It's about
 > > apps-that-use-console-stdin-and-stdout vs. apps-that-display-a-gui; those that
 > > show a gui could usefully be detached, but those that read their input from
 > > stdin will break if the shell detaches them.  I don't think there's a reliable
 > > enough mechanism by which a shell could detect one case from the other.
 > >
 > > Try starting insight (gui version of gdb) from the bash prompt.  You also won't
 > > get a shell back until it exits.
 > >
 > >
 > >     cheers,
 > >       DaveK
 > > --
 > > Can't think of a witty .sigline today....
 > >
 > >
 > > --
 > > Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
 > > Problem reports:       http://cygwin.com/problems.html
 > > Documentation:         http://cygwin.com/docs.html
 > > FAQ:                   http://cygwin.com/faq/
 > >

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/