naga@wet.UUCP (Peter Davidson) (05/07/91)
>>In article <collinsa.672410890@p4.cs.man.ac.uk>, collinsa@p4.cs.man.ac.uk >>(Adrian Collins) writes: >>>[deletions] >>> As I've had quite a few requests for responses to my original query, here >>> is a method of working out whether STDIN and STDOUT are being redirected. >>> This is a slightly altered version of the code sent to me by >>> Nick FitzGerald. >> >>Adrian should have pointed out that the code I sent him was posted late >>last year (to this group ?) by Peter Davidson. >> >>If Peter's still reading along, thanks and apologies (I'm presumptuous >>enough to extend apologies on Adrian's behalf as well, 8-) ). >> >>Nick. > >Oops. sorry about that. Thanks Peter Davidson, and sorry about that Nick. > >Adrian Well actually my attention was temporarily distracted by the goings-on in alt.msdos and comp.lang.c. I'm glad that the code to detect redir- ection of stdout has been found useful (it sure gets around). I should, however, point out that Adrian's alteration of the bit mask, from 0x2 to 0x82, is unnecessary. My original code (given below) detects redirection both to the printer and to a disk file. unsigned int get_device_data(int handle) { union REGS regs; regs.h.ah = 0x44; /* function number */ regs.h.al = 0; /* subfunction number */ regs.x.bx = handle; /* file or device handle */ int86(0x21,®s,®s); return ( regs.x.dx ); } int output_redirected(void) { return ( ! ( get_device_data(fileno(stdout)) & 0x2 ) ); } To detect redirection of stdout the only question is whether bit 1 of the value returned by get_device_data() is 0 or 1. Changing the bit mask as suggested has no effect on the behavior of the function, regardless of whether redirection is to printer or to file. Thanks, however, to Adrian for suggesting the adaptation for redirection of stdin. And following up on Adrian's concern with bit 7, the code can be modified to return explicitly whether redirection (if in effect) is to (or from) a device or a disk file, as follows: /* this returns * 0 if output not redirected from stdout * 1 if redirected to printer or some other device * 2 if redirected to a disk file */ int output_redirected(void) { int result = 0; switch ( get_device_data(fileno(stdout)) & 0x82 ) { case 0x0: result++; /* no break */ case 0x80: result++; } return ( result ); } /* this returns * 0 if input not redirected from stdin * 1 if redirected from some other device * 2 if redirected from a disk file */ int input_redirected(void) { int result = 0; switch ( get_device_data(fileno(stdin)) & 0x81 ) { case 0x0: result++; /* no break */ case 0x80: result++; } return ( result ); } To test these functions one can use: void main(void) { switch ( output_redirected() ) { case 0: printf("\nOutput not redirected.\n"); break; case 1: printf("\nOutput redirected to device.\n"); break; case 2: printf("\nOutput redirected to disk file.\n"); } switch ( input_redirected() ) { case 0: printf("\nInput not redirected.\n"); break; case 1: printf("\nInput redirected from device.\n"); break; case 2: printf("\nInput redirected from disk file.\n"); } } These functions are part of a library of useful routines I'm about to release. Anyone wanting further information about this library (and others) should send a real-world mailing address to wet!naga@cca.ucsf.edu (or to naga@wet.UUCP). I have lots of useful stuff lying around here, but it's quite an effort to pack it all up nicely and get the word out. Still, I try. By the way, I wish to relocate permanently to Europe, Canada or perhaps Oz/NZ, so if anyone knows of someone who can use a good C programmer ...