__int64 xftell64 (FILE *f, const char *filename) { #if _MSC_VER > 1200 __int64 where; where = _ftelli64(f); if (where < (__int64)0) FATAL_PERROR(filename); #else __int64 where, filepos; int fd; fd = fileno(f); if(f->_cnt < 0) f->_cnt = 0; if((filepos = _lseeki64(fd, (__int64)0, SEEK_CUR)) < (__int64)0) { FATAL_PERROR(filename); return (__int64)(-1); } if(filepos == (__int64)0) where = (__int64)(f->_ptr - f->_base); else where = filepos - f->_cnt; #endif return where; }
/* * Look for the archive identified by path into the ARCHIVE_STATUS pool archive_pool. * If the archive is found, a pointer to the associated ARCHIVE_STATUS is returned * otherwise the needed archive is opened and added to the pool and then returned. * If an error occurs, returns NULL. * * Having several archives is useful for sharing binary dependencies with several * executables (multipackage feature). */ static ARCHIVE_STATUS * _get_archive(ARCHIVE_STATUS *archive_pool[], const char *path) { ARCHIVE_STATUS *archive = NULL; int index = 0; int SELF = 0; VS("LOADER: Getting file from archive.\n"); if (pyi_create_temp_path(archive_pool[SELF]) == -1) { return NULL; } for (index = 1; archive_pool[index] != NULL; index++) { if (strcmp(archive_pool[index]->archivename, path) == 0) { VS("LOADER: Archive found: %s\n", path); return archive_pool[index]; } VS("LOADER: Checking next archive in the list...\n"); } archive = (ARCHIVE_STATUS *) malloc(sizeof(ARCHIVE_STATUS)); if (archive == NULL) { FATAL_PERROR("malloc", "Error allocating memory for status\n"); return NULL; } strncpy(archive->archivename, path, PATH_MAX); strncpy(archive->homepath, archive_pool[SELF]->homepath, PATH_MAX); strncpy(archive->temppath, archive_pool[SELF]->temppath, PATH_MAX); if (archive->archivename[PATH_MAX-1] != '\0' || archive->homepath[PATH_MAX-1] != '\0' || archive->temppath[PATH_MAX-1] != '\0') { FATALERROR("Archive path exceeds PATH_MAX\n"); free(archive); return NULL; } /* * Setting this flag prevents creating another temp directory and * the directory from the main archive status is used. */ archive->has_temp_directory = archive_pool[SELF]->has_temp_directory; if (pyi_arch_open(archive)) { FATAL_PERROR("malloc", "Error opening archive %s\n", path); free(archive); return NULL; } archive_pool[index] = archive; return archive; }
/* xfopen by file system codepage */ FILE * fsyscp_xfopen (const char *filename, const char *mode) { FILE *f; wchar_t *fnamew, modew[4]; int i; #if defined (KPSE_COMPAT_API) kpathsea kpse; #endif assert(filename && mode); fnamew = get_wstring_from_fsyscp(filename, fnamew=NULL); for(i=0; (modew[i]=(wchar_t)mode[i]); i++) {} /* mode[i] must be ASCII */ f = _wfopen(fnamew, modew); if (f == NULL) FATAL_PERROR(filename); #if defined (KPSE_COMPAT_API) kpse = kpse_def; if (KPATHSEA_DEBUG_P (KPSE_DEBUG_FOPEN)) { DEBUGF_START (); fprintf (stderr, "fsyscp_xfopen(%s [", filename); WriteConsoleW( GetStdHandle( STD_ERROR_HANDLE ), fnamew, wcslen( fnamew ), NULL, NULL ); #if defined(_WIN64) fprintf (stderr, "], %s) => 0x%I64x\n", mode, (unsigned __int64) f); #else fprintf (stderr, "], %s) => 0x%lx\n", mode, (unsigned long) f); #endif DEBUGF_END (); } #endif free(fnamew); return f; }
void xfseek64 (FILE *f, __int64 offset, int wherefrom, const char *filename) { #if _MSC_VER > 1200 if (_fseeki64(f, offset, wherefrom) < (__int64)0) FATAL_PERROR(filename); #else if(wherefrom == SEEK_CUR) { offset += xftell64(f, filename); wherefrom = SEEK_SET; } fflush(f); if (_lseeki64(fileno(f), offset, wherefrom) < (__int64)0) FATAL_PERROR(filename); #endif }
pksearch P6C(char *, path, char *, file, char *, mode, halfword, dpi, char **, name_ret, int *, dpi_ret) { FILE *ret; kpse_glyph_file_type font_file; string found_name = kpse_find_pk (file, dpi, &font_file); if (found_name) { ret = fopen (found_name, mode); if (!ret) FATAL_PERROR (name); /* Free result of previous search. */ if (realnameoffile) free (realnameoffile); /* Save in `name' and `realnameoffile' because other routines access those globals. Sigh. */ realnameoffile = found_name; strcpy(name, realnameoffile); *name_ret = font_file.name; *dpi_ret = font_file.dpi; } else ret = NULL; return ret; } /* end search */
void xfclose P2C(FILE *, f, const_string, filename) { assert(f); if (fclose(f) == EOF) FATAL_PERROR(filename); }
xopendir P1C(string, dirname) { DIR *d = opendir (dirname); if (d == NULL) FATAL_PERROR (dirname); return d; }
/* // We declared lstat to prevent a warning during development. This // turns out to be more trouble than it is worth. // extern int lstat (); */ struct stat xlstat P1C(const_string, path) { struct stat s; if (lstat(path, &s) != 0) FATAL_PERROR(path); return s; }
unsigned long xftell (FILE *f, const_string filename) { long where = ftello (f); if (where < 0) FATAL_PERROR(filename); return where; }
off_t xftello P2C(FILE *, f, string, filename) { off_t where = ftello (f); if (where < 0) FATAL_PERROR(filename); return where; }
xfopen P2C(const_string, filename, const_string, mode) { FILE *f; assert(filename && mode); f = fopen(filename, mode); if (f == NULL) FATAL_PERROR(filename); return f; }
void init_display (bitmap_font_type f) { string server_identity; /* Do nothing unless the user wants us to. */ if (!wants_display) return; server_identity = get_identity (); #ifndef STANDALONE_SERVER { /* Fork our server. This is the production case. */ unsigned design_size; int pid = fork (); switch (pid) { case -1: FATAL_PERROR ("fork"); case 0: { /* We are the child, i.e., the server. Convert the design size, which we have in points, to pixels. `start_server' never returns, because it waits forever for events. */ design_size = (BITMAP_FONT_DESIGN_SIZE (f) * atof (dpi) / POINTS_PER_INCH); start_server (design_size, server_identity); FATAL ("init_display: start_server returned"); } default: /* We are the parent, i.e., the main process. Continue outside the switch. */ ; } } #endif /* not STANDALONE_SERVER */ /* Assign to the globals so that our other routines can send messages. */ get_server_info (&server_window, &display, server_identity); /* Register our message atoms with the X server. */ foserver_exit_atom = XInternAtom (display, FOSERVER_EXIT_ATOM, False); foserver_update_pixmap_atom = XInternAtom (display, FOSERVER_UPDATE_PIXMAP_ATOM, False); }
search P3C(kpse_file_format_type, format, char *, file, char *, mode) { FILE *ret; string found_name; #ifdef SECURE /* This change suggested by [email protected] to disallow reading of arbitrary files. */ if (secure && kpse_absolute_p (file)) return NULL; #endif /* Most file looked for through here must exist -- the exception is VF's. Bitmap fonts go through pksearch. */ found_name = kpse_find_file (file, format, format != vfpath); if (found_name) { unsigned len = strlen (found_name); #ifndef AMIGA if ((format == figpath || format == headerpath) && ((len > 2 && FILESTRCASEEQ (found_name + len - 2, ".Z")) || (len > 3 && FILESTRCASEEQ (found_name + len - 3, ".gz")))) { /* FIXME : use zlib instead of gzip ! */ char *cmd = concat3 (GUNZIP, " -c ", found_name); ret = popen (cmd, "r"); to_close = USE_PCLOSE ; } else { #endif /* not AMIGA */ ret = fopen (found_name, mode); to_close = USE_FCLOSE ; #ifndef AMIGA } #endif /* not AMIGA */ if (!ret) FATAL_PERROR (found_name); /* Free result of previous search. */ if (realnameoffile) free (realnameoffile); /* Save in `name' and `realnameoffile' because other routines access those globals. Sigh. */ realnameoffile = found_name; strcpy(name, realnameoffile); } else ret = NULL; return ret; } /* end search */
void xfseek (FILE *f, long offset, int wherefrom, string filename) { if (fseek (f, offset, wherefrom) < 0) FATAL_PERROR (filename); }
string xgetcwd (void) { /* If the system provides getcwd, use it. If not, use getwd if available. But provide a way not to use getcwd: on some systems getcwd forks, which is expensive and may in fact be impossible for large programs like tex. If your system needs this define and it is not detected by configure, let me know. -- Olaf Weber <[email protected] */ #if defined (HAVE_GETCWD) && !defined (GETCWD_FORKS) char path[PATH_MAX + 1]; #if defined(WIN32) string pp; #endif if (getcwd (path, PATH_MAX + 1) == NULL) { FATAL_PERROR ("getcwd"); } #if defined(WIN32) for (pp = path; *pp; pp++) { if (*pp == '\\') *pp = '/'; #if defined (KPSE_COMPAT_API) else if (IS_KANJI(pp)) pp++; #endif } #endif return xstrdup (path); #elif defined (HAVE_GETWD) char path[PATH_MAX + 1]; if (getwd (path) == NULL) { FATAL_PERROR ("getwd"); } return xstrdup (path); #else /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */ struct stat root_stat, cwd_stat; string cwd_path = (string)xmalloc(2); /* In case we assign "/" below. */ *cwd_path = 0; /* Find the inodes of the root and current directories. */ root_stat = xstat("/"); cwd_stat = xstat("."); /* Go up the directory hierarchy until we get to root, prepending each directory we pass through to `cwd_path'. */ while (!SAME_FILE_P(root_stat, cwd_stat)) { struct dirent *e; DIR *parent_dir; boolean found = false; xchdir(".."); parent_dir = xopendir("."); /* Look through the parent directory for the entry with the same inode, so we can get its name. */ while ((e = readdir (parent_dir)) != NULL && !found) { struct stat test_stat; test_stat = xlstat(e->d_name); if (SAME_FILE_P(test_stat, cwd_stat)) { /* We've found it. Prepend the pathname. */ string temp = cwd_path; cwd_path = concat3("/", e->d_name, cwd_path); free(temp); /* Set up to test the next parent. */ cwd_stat = xstat("."); /* Stop reading this directory. */ found = true; } } if (!found) LIB_FATAL2("No inode %d/device %d in parent directory", cwd_stat.st_ino, cwd_stat.st_dev); xclosedir(parent_dir); } /* If the current directory is the root, cwd_path will be the empty string, and we will have not gone through the loop. */ if (*cwd_path == 0) strcpy(cwd_path, "/"); else /* Go back to where we were. */ xchdir(cwd_path); #ifdef DOSISH /* Prepend the drive letter to CWD_PATH, since this technique never tells us what the drive is. Note that on MS-DOS/MS-Windows, the branch that works around missing `getwd' will probably only work for DJGPP (which does have `getwd'), because only DJGPP reports meaningful st_ino numbers. But someday, somebody might need this... */ { char drive[3]; string temp = cwd_path; /* Make the drive letter lower-case, unless it is beyond Z: (yes, there ARE such drives, in case of Novell Netware on MS-DOS). */ drive[0] = root_stat.st_dev + (root_stat.st_dev < 26 ? 'a' : 'A'); drive[1] = ':'; drive[2] = '\0'; cwd_path = concat(drive, cwd_path); free(temp); } #endif return cwd_path; #endif /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */ }
/* sec 0597 */ void write_dvi(size_t a, size_t b) { if (fwrite((char *)&dvi_buf[a], sizeof(dvi_buf[a]), (b - a + 1), dvi_file) != (b - a + 1)) FATAL_PERROR("\n! dvi file"); }
void xfseek P4C(FILE *, f, long, offset, int, wherefrom, string, filename) { if (fseek (f, offset, wherefrom) < 0) FATAL_PERROR (filename); }