static 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; }
static int pipe_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { errno = 0; /* * Some platforms allow opening a pipe with a '+' in the access * mode, even though pipes are not positionable. Detect this here. */ if (strchr(access, '+')) return_error(gs_error_invalidfileaccess); /* * The OSF/1 1.3 library doesn't include const in the * prototype for popen, so we have to break const here. */ *pfile = popen((char *)fname, (char *)access); if (*pfile == NULL) return_error(gs_fopen_errno_to_code(errno)); if (rfname != NULL) strcpy(rfname, fname); return 0; }
static int os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { os2_printer_t *pr = (os2_printer_t *)iodev->state; char driver_name[256]; /* Make sure that printer exists. */ if (pm_find_queue(pr->memory, fname, driver_name)) { /* error, list valid queue names */ emprintf(pr->memory, "Invalid queue name. Use one of:\n"); pm_find_queue(pr->memory, NULL, NULL); return_error(gs_error_undefinedfilename); } strncpy(pr->queue, fname, sizeof(pr->queue)-1); /* Create a temporary file */ *pfile = gp_open_scratch_file(pr->memory, "gs", pr->filename, access); if (*pfile == NULL) return_error(gs_fopen_errno_to_code(errno)); return 0; }
static int mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { DWORD version = GetVersion(); HANDLE hprinter; int pipeh[2]; unsigned long tid; HANDLE hthread; char pname[gp_file_name_sizeof]; unsigned long *ptid = &((tid_t *)(iodev->state))->tid; /* Win32s supports neither pipes nor Win32 printers. */ if (((HIWORD(version) & 0x8000) != 0) && ((HIWORD(version) & 0x4000) == 0)) return_error(gs_error_invalidfileaccess); /* Make sure that printer exists. */ if (!OpenPrinter((LPTSTR)fname, &hprinter, NULL)) return_error(gs_error_invalidfileaccess); ClosePrinter(hprinter); /* Create a pipe to connect a FILE pointer to a Windows printer. */ if (_pipe(pipeh, 4096, _O_BINARY) != 0) return_error(gs_fopen_errno_to_code(errno)); *pfile = fdopen(pipeh[1], (char *)access); if (*pfile == NULL) { close(pipeh[0]); close(pipeh[1]); return_error(gs_fopen_errno_to_code(errno)); } /* start a thread to read the pipe */ tid = _beginthread(&mswin_printer_thread, 32768, (void *)(pipeh[0])); if (tid == -1) { fclose(*pfile); close(pipeh[0]); return_error(gs_error_invalidfileaccess); } /* Duplicate thread handle so we can wait on it * even if original handle is closed by CRTL * when the thread finishes. */ if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)tid, GetCurrentProcess(), &hthread, 0, FALSE, DUPLICATE_SAME_ACCESS)) { fclose(*pfile); return_error(gs_error_invalidfileaccess); } *ptid = (unsigned long)hthread; /* Give the name of the printer to the thread by writing * it to the pipe. This is avoids elaborate thread * synchronisation code. */ strncpy(pname, fname, sizeof(pname)); fwrite(pname, 1, sizeof(pname), *pfile); return 0; }