📄 file.c
字号:
/* * "$Id: file.c,v 1.12 2005/01/03 19:29:59 mike Exp $" * * File functions for the Common UNIX Printing System (CUPS). * * Since stdio files max out at 256 files on many systems, we have to * write similar functions without this limit. At the same time, using * our own file functions allows us to provide transparent support of * gzip'd print files, PPD files, etc. * * Copyright 1997-2005 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal * copyright law. Distribution and use rights are outlined in the file * "LICENSE.txt" which should have been included with this file. If this * file is missing or damaged please contact Easy Software Products * at: * * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 * Hollywood, Maryland 20636 USA * * Voice: (301) 373-9600 * EMail: cups-info@cups.org * WWW: http://www.cups.org * * Contents: * * cupsFileClose() - Close a CUPS file. * cupsFileFlush() - Flush pending output. * cupsFileGetChar() - Get a single character from a file. * cupsFileGets() - Get a CR and/or LF-terminated line. * cupsFileOpen() - Open a CUPS file. * cupsFilePrintf() - Write a formatted string. * cupsFilePutChar() - Write a character. * cupsFilePuts() - Write a string. * cupsFileRead() - Read from a file. * cupsFileSeek() - Seek in a file. * cupsFileWrite() - Write to a file. * cups_fill() - Fill the input buffer... * cups_read() - Read from a file descriptor. * cups_write() - Write to a file descriptor. *//* * Include necessary headers... */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#if 0#include <cups/string.h>#else#include "string.h"#endif#include <errno.h>#ifdef WIN32# include <io.h>#else# include <unistd.h># include <fcntl.h>#endif /* WIN32 */#include "file.h"/* * Local functions... */static int cups_fill(cups_file_t *fp);static int cups_read(int fd, char *buf, int bytes);static int cups_write(int fd, const char *buf, int bytes);/* * 'cupsFileClose()' - Close a CUPS file. */int /* O - 0 on success, -1 on error */cupsFileClose(cups_file_t *fp) /* I - CUPS file */{ int fd; /* File descriptor */ /* * Range check... */ if (!fp) return (-1);#if 0#ifdef HAVE_LIBZ /* * Free decompression data as needed... */ if (fp->compressed && fp->mode == 'r') inflateEnd(&fp->stream);#endif /* HAVE_LIBZ */#endif if (fp->mode == 'w') cupsFileFlush(fp); /* * Save the file descriptor we used and free memory... */ fd = fp->fd; free(fp); /* * Close the file, returning the close status... */ return (close(fd));}/* * 'cupsFileFlush()' - Flush pending output. */int /* O - 0 on success, -1 on error */cupsFileFlush(cups_file_t *fp) /* I - CUPS file */{ int bytes; /* Bytes to write */ /* * Range check input... */ if (!fp || fp->mode != 'w') return (-1); bytes = fp->ptr - fp->buf; if (bytes > 0) { if (cups_write(fp->fd, fp->buf, bytes) < bytes) return (-1); fp->ptr = fp->buf; } return (0);}/* * 'cupsFileGetChar()' - Get a single character from a file. */int /* O - Character or -1 on EOF */cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */{ /* * Range check input... */ if (!fp || fp->mode != 'r') return (-1); /* * If the input buffer is empty, try to read more data... */ if (fp->ptr >= fp->end) if (cups_fill(fp) < 0) return (-1); /* * Return the next character in the buffer... */ return (*(fp->ptr)++ & 255);}/* * 'cupsFileGets()' - Get a CR and/or LF-terminated line. */char * /* O - Line read or NULL on eof/error */cupsFileGets(cups_file_t *fp, /* I - CUPS file */ char *buf, /* O - String buffer */ int buflen) /* I - Size of string buffer */{ int ch; /* Character from file */ char *ptr, /* Current position in line buffer */ *end; /* End of line buffer */ /* * Range check input... */ if (!fp || fp->mode != 'r' || !buf || buflen < 2) return (NULL); /* * Now loop until we have a valid line... */ for (ptr = buf, end = buf + buflen - 1; ptr < end ;) { if (fp->ptr >= fp->end) if (cups_fill(fp) <= 0) { if (ptr == buf) return (NULL); else break; } ch = *(fp->ptr)++; if (ch == '\r') { /* * Check for CR LF... */ if (fp->ptr >= fp->end) if (cups_fill(fp) <= 0) break; if (*(fp->ptr) == '\n') fp->ptr ++; break; } else if (ch == '\n') { /* * Line feed ends a line... */ break; } else *ptr++ = ch; } *ptr = '\0'; return (buf);}/* * 'cupsFileOpen()' - Open a CUPS file. */cups_file_t * /* O - CUPS file or NULL */cupsFileOpen(const char *filename, /* I - Name of file */ const char *mode) /* I - Open mode */{ cups_file_t *fp; /* New CUPS file */ int o; /* Open mode bits */ /* * Range check input... */ if (!filename || !mode || (*mode != 'r' && *mode != 'w' && *mode != 'a')) return (NULL); /* * Allocate memory... */ if ((fp = calloc(1, sizeof(cups_file_t))) == NULL) return (NULL); /* * Open the file... */ switch (*mode) { case 'a' : o = O_RDWR | O_CREAT; fp->mode = 'w'; break; case 'r' : o = O_RDONLY; fp->mode = 'r'; break; case 'w' : o = O_WRONLY | O_TRUNC | O_CREAT; fp->mode = 'w'; break; default : /* Remove bogus compiler warning... */ return (NULL); } if ((fp->fd = open(filename, o, 0644)) < 0) { /* * Can't open file! */ free(fp); return (NULL); } /* * Don't pass this file to child processes... */ fcntl(fp->fd, F_SETFD, fcntl(fp->fd, F_GETFD) | FD_CLOEXEC); if (*mode == 'a') fp->pos = lseek(fp->fd, 0, SEEK_END); else fp->pos = 0; if (*mode != 'r') { fp->ptr = fp->buf; fp->end = fp->buf + sizeof(fp->buf); } return (fp);}/* * 'cupsFilePrintf()' - Write a formatted string. */int /* O - Number of bytes written or -1 */cupsFilePrintf(cups_file_t *fp, /* I - CUPS file */ const char *format, /* I - Printf-style format string */ ...) /* I - Additional args as necessary */{ va_list ap; /* Argument list */ int bytes; /* Formatted size */ char buf[2048]; /* Formatted text */ if (!fp || !format || fp->mode != 'w') return (-1); va_start(ap, format); bytes = vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); if ((fp->ptr + bytes) > fp->end) if (cupsFileFlush(fp)) return (-1); fp->pos += bytes; if (bytes > sizeof(fp->buf)) return (cups_write(fp->fd, buf, bytes)); else { memcpy(fp->ptr, buf, bytes); fp->ptr += bytes; return (bytes); }}/* * 'cupsFilePutChar()' - Write a character. */int /* O - 0 on success, -1 on error */cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */ int c) /* I - Character to write */{ /* * Range check input... */ if (!fp || fp->mode != 'w') return (-1); /* * Buffer it up... */ if (fp->ptr >= fp->end) if (cupsFileFlush(fp)) return (-1); *(fp->ptr) ++ = c; fp->pos ++; return (0);}/* * 'cupsFilePuts()' - Write a string. */int /* O - Number of bytes written or -1 */cupsFilePuts(cups_file_t *fp, /* I - CUPS file */ const char *s) /* I - String to write */{ int bytes; /* Bytes to write */ /* * Range check input... */ if (!fp || !s || fp->mode != 'w') return (-1); /* * Write the string... */ bytes = strlen(s); if ((fp->ptr + bytes) > fp->end) if (cupsFileFlush(fp)) return (-1); fp->pos += bytes; if (bytes > sizeof(fp->buf)) return (cups_write(fp->fd, s, bytes)); else { memcpy(fp->ptr, s, bytes); fp->ptr += bytes; return (bytes); }}/* * 'cupsFileRead()' - Read from a file. */int /* O - Number of bytes read or -1 */cupsFileRead(cups_file_t *fp, /* I - CUPS file */ char *buf, /* O - Buffer */ int bytes) /* I - Number of bytes to read */{ int total, /* Total bytes read */ count; /* Bytes read */ /* * Range check input... */ if (!fp || !buf || bytes < 0 || fp->mode != 'r') return (-1); if (bytes == 0) return (0); /* * Loop until all bytes are read... */ total = 0; while (bytes > 0) { if (fp->ptr >= fp->end) if (cups_fill(fp) <= 0) { if (total > 0) return (total); else return (-1); } count = fp->end - fp->ptr; if (count > bytes) count = bytes; memcpy(buf, fp->ptr, count); fp->ptr += count; /* * Update the counts for the last read... */ bytes -= count; total += count; buf += count; } /* * Return the total number of bytes read... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -