/* Copyright (C) 1999 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gp_mshdl.c,v 1.2.6.1.2.1 2003/01/17 00:49:02 giles Exp $ */ /* %handle% IODevice */ #include "errno_.h" #include "stdio_.h" #include "string_.h" #include "ctype_.h" #include #include "gserror.h" #include "gstypes.h" #include "gsmemory.h" /* for gxiodev.h */ #include "gxiodev.h" /* The MS-Windows handle IODevice */ /* This allows an MS-Windows file handle to be passed in to * Ghostscript as %handle%NNNNNNNN where NNNNNNNN is the hexadecimal * value of the handle. * The typical use is for another program to create a pipe, * pass the write end into Ghostscript using * -sOutputFile="%handle%NNNNNNNN" * so that Ghostscript printer output can be captured by the * other program. The handle would be created with CreatePipe(). * If Ghostscript is not a DLL, the pipe will have to be inheritable * by the Ghostscript process. */ private iodev_proc_fopen(mswin_handle_fopen); private iodev_proc_fclose(mswin_handle_fclose); const gx_io_device gs_iodev_handle = { "%handle%", "FileSystem", {iodev_no_init, iodev_no_open_device, NULL /*iodev_os_open_file */ , mswin_handle_fopen, mswin_handle_fclose, iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status, iodev_no_enumerate_files, NULL, NULL, iodev_no_get_params, iodev_no_put_params } }; /* The file device procedures */ #ifndef INVALID_HANDLE_VALUE #define INVALID_HANDLE_VALUE (-1) #endif /* Allow printer filename specified by -sOutputFile="..." * to contain a hexadecimal encoded OS file handle in the * form -sOutputFile="\\handle\\000001c5" * * Returns: * The OS file handle on success. * INVALID_HANDLE_VALUE on failure. * * This allows the caller to create an OS pipe and give us a * handle to the write end of the pipe. * If we are called as an EXE, the OS file handle must be * inherited by Ghostscript. * Pipes aren't supported under Win32s. */ private long get_os_handle(const char *name) { ulong hfile; /* This must be as long as the longest handle. */ /* This is correct for Win32, maybe wrong for Win64. */ int i, ch; for (i = 0; (ch = name[i]) != 0; ++i) if (!isxdigit(ch)) return (long)INVALID_HANDLE_VALUE; if (sscanf(name, "%lx", &hfile) != 1) return (long)INVALID_HANDLE_VALUE; return (long)hfile; } private int mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { int fd; long hfile; /* Correct for Win32, may be wrong for Win64 */ errno = 0; if ((hfile = get_os_handle(fname)) == (long)INVALID_HANDLE_VALUE) return_error(gs_fopen_errno_to_code(EBADF)); /* associate a C file handle with an OS file handle */ fd = _open_osfhandle((long)hfile, 0); if (fd == -1) return_error(gs_fopen_errno_to_code(EBADF)); /* associate a C file stream with C file handle */ *pfile = fdopen(fd, (char *)access); if (*pfile == NULL) return_error(gs_fopen_errno_to_code(errno)); if (rfname != NULL) strcpy(rfname, fname); return 0; } private int mswin_handle_fclose(gx_io_device * iodev, FILE * file) { fclose(file); return 0; }