gp_mshdl.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gp_mshdl.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
  14. /* %handle% IODevice */
  15. #include "errno_.h"
  16. #include "stdio_.h"
  17. #include "string_.h"
  18. #include "ctype_.h"
  19. #include <io.h>
  20. #include "gserror.h"
  21. #include "gstypes.h"
  22. #include "gsmemory.h" /* for gxiodev.h */
  23. #include "gxiodev.h"
  24. /* The MS-Windows handle IODevice */
  25. /* This allows an MS-Windows file handle to be passed in to
  26. * Ghostscript as %handle%NNNNNNNN where NNNNNNNN is the hexadecimal
  27. * value of the handle.
  28. * The typical use is for another program to create a pipe,
  29. * pass the write end into Ghostscript using
  30. * -sOutputFile="%handle%NNNNNNNN"
  31. * so that Ghostscript printer output can be captured by the
  32. * other program. The handle would be created with CreatePipe().
  33. * If Ghostscript is not a DLL, the pipe will have to be inheritable
  34. * by the Ghostscript process.
  35. */
  36. private iodev_proc_fopen(mswin_handle_fopen);
  37. private iodev_proc_fclose(mswin_handle_fclose);
  38. const gx_io_device gs_iodev_handle = {
  39. "%handle%", "FileSystem",
  40. {iodev_no_init, iodev_no_open_device,
  41. NULL /*iodev_os_open_file */ , mswin_handle_fopen, mswin_handle_fclose,
  42. iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,
  43. iodev_no_enumerate_files, NULL, NULL,
  44. iodev_no_get_params, iodev_no_put_params
  45. }
  46. };
  47. /* The file device procedures */
  48. #ifndef INVALID_HANDLE_VALUE
  49. #define INVALID_HANDLE_VALUE (-1)
  50. #endif
  51. /* Allow printer filename specified by -sOutputFile="..."
  52. * to contain a hexadecimal encoded OS file handle in the
  53. * form -sOutputFile="\\handle\\000001c5"
  54. *
  55. * Returns:
  56. * The OS file handle on success.
  57. * INVALID_HANDLE_VALUE on failure.
  58. *
  59. * This allows the caller to create an OS pipe and give us a
  60. * handle to the write end of the pipe.
  61. * If we are called as an EXE, the OS file handle must be
  62. * inherited by Ghostscript.
  63. * Pipes aren't supported under Win32s.
  64. */
  65. private long
  66. get_os_handle(const char *name)
  67. {
  68. ulong hfile; /* This must be as long as the longest handle. */
  69. /* This is correct for Win32, maybe wrong for Win64. */
  70. int i, ch;
  71. for (i = 0; (ch = name[i]) != 0; ++i)
  72. if (!isxdigit(ch))
  73. return (long)INVALID_HANDLE_VALUE;
  74. if (sscanf(name, "%lx", &hfile) != 1)
  75. return (long)INVALID_HANDLE_VALUE;
  76. return (long)hfile;
  77. }
  78. private int
  79. mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access,
  80. FILE ** pfile, char *rfname, uint rnamelen)
  81. {
  82. int fd;
  83. long hfile; /* Correct for Win32, may be wrong for Win64 */
  84. errno = 0;
  85. if ((hfile = get_os_handle(fname)) == (long)INVALID_HANDLE_VALUE)
  86. return_error(gs_fopen_errno_to_code(EBADF));
  87. /* associate a C file handle with an OS file handle */
  88. fd = _open_osfhandle((long)hfile, 0);
  89. if (fd == -1)
  90. return_error(gs_fopen_errno_to_code(EBADF));
  91. /* associate a C file stream with C file handle */
  92. *pfile = fdopen(fd, (char *)access);
  93. if (*pfile == NULL)
  94. return_error(gs_fopen_errno_to_code(errno));
  95. if (rfname != NULL)
  96. strcpy(rfname, fname);
  97. return 0;
  98. }
  99. private int
  100. mswin_handle_fclose(gx_io_device * iodev, FILE * file)
  101. {
  102. fclose(file);
  103. return 0;
  104. }