io.c revision f765521f
15dfecf96Smrg/* 25dfecf96Smrg * Copyright (c) 2002 by The XFree86 Project, Inc. 35dfecf96Smrg * 45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a 55dfecf96Smrg * copy of this software and associated documentation files (the "Software"), 65dfecf96Smrg * to deal in the Software without restriction, including without limitation 75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the 95dfecf96Smrg * Software is furnished to do so, subject to the following conditions: 105dfecf96Smrg * 115dfecf96Smrg * The above copyright notice and this permission notice shall be included in 125dfecf96Smrg * all copies or substantial portions of the Software. 135dfecf96Smrg * 145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 205dfecf96Smrg * SOFTWARE. 215dfecf96Smrg * 225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall 235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other 245dfecf96Smrg * dealings in this Software without prior written authorization from the 255dfecf96Smrg * XFree86 Project. 265dfecf96Smrg * 275dfecf96Smrg * Author: Paulo César Pereira de Andrade 285dfecf96Smrg */ 295dfecf96Smrg 305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/io.c,v 1.16tsi Exp $ */ 315dfecf96Smrg 325dfecf96Smrg#include "lisp/io.h" 335dfecf96Smrg#include <errno.h> 345dfecf96Smrg#include <fcntl.h> 355dfecf96Smrg#include <stdarg.h> 365dfecf96Smrg#include <sys/types.h> 375dfecf96Smrg#include <sys/stat.h> 385dfecf96Smrg 395dfecf96Smrg/* Match the FILE_XXX flags */ 405dfecf96Smrg#define READ_BIT 0x01 415dfecf96Smrg#define WRITE_BIT 0x02 425dfecf96Smrg#define APPEND_BIT 0x04 435dfecf96Smrg#define BUFFERED_BIT 0x08 445dfecf96Smrg#define UNBUFFERED_BIT 0x10 455dfecf96Smrg#define BINARY_BIT 0x20 465dfecf96Smrg 475dfecf96Smrg 485dfecf96Smrg/* 495dfecf96Smrg * Initialization 505dfecf96Smrg */ 515dfecf96Smrgextern int pagesize; 525dfecf96Smrg 535dfecf96Smrg/* 545dfecf96Smrg * Implementation 555dfecf96Smrg */ 565dfecf96Smrgint 575dfecf96SmrgLispGet(void) 585dfecf96Smrg{ 595dfecf96Smrg int ch = EOF; 605dfecf96Smrg LispUngetInfo *unget = lisp__data.unget[lisp__data.iunget]; 615dfecf96Smrg 625dfecf96Smrg if (unget->offset) 635dfecf96Smrg ch = ((unsigned char*)unget->buffer)[--unget->offset]; 645dfecf96Smrg else if (SINPUT->data.stream.readable) { 655dfecf96Smrg LispFile *file = NULL; 665dfecf96Smrg 675dfecf96Smrg switch (SINPUT->data.stream.type) { 685dfecf96Smrg case LispStreamStandard: 695dfecf96Smrg case LispStreamFile: 705dfecf96Smrg file = FSTREAMP(SINPUT); 715dfecf96Smrg break; 725dfecf96Smrg case LispStreamPipe: 735dfecf96Smrg file = IPSTREAMP(SINPUT); 745dfecf96Smrg break; 755dfecf96Smrg case LispStreamString: 765dfecf96Smrg ch = LispSgetc(SSTREAMP(SINPUT)); 775dfecf96Smrg break; 785dfecf96Smrg default: 795dfecf96Smrg ch = EOF; 805dfecf96Smrg break; 815dfecf96Smrg } 825dfecf96Smrg if (file != NULL) { 835dfecf96Smrg if (file->nonblock) { 845dfecf96Smrg if (fcntl(file->descriptor, F_SETFL, 0) < 0) 855dfecf96Smrg LispDestroy("fcntl: %s", strerror(errno)); 865dfecf96Smrg file->nonblock = 0; 875dfecf96Smrg } 885dfecf96Smrg ch = LispFgetc(file); 895dfecf96Smrg } 905dfecf96Smrg } 915dfecf96Smrg else 925dfecf96Smrg LispDestroy("cannot read from *STANDARD-INPUT*"); 935dfecf96Smrg 945dfecf96Smrg if (ch == EOF) 955dfecf96Smrg lisp__data.eof = 1; 965dfecf96Smrg 975dfecf96Smrg return (ch); 985dfecf96Smrg} 995dfecf96Smrg 1005dfecf96Smrgint 1015dfecf96SmrgLispUnget(int ch) 1025dfecf96Smrg{ 1035dfecf96Smrg LispUngetInfo *unget = lisp__data.unget[lisp__data.iunget]; 1045dfecf96Smrg 105c05e22d7Smrg if ((ch & 0xff) == ch) { 106c05e22d7Smrg if (unget->offset == sizeof(unget->buffer)) { 107c05e22d7Smrg LispWarning("character %c lost at LispUnget()", unget->buffer[0]); 108c05e22d7Smrg memmove(unget->buffer, unget->buffer + 1, unget->offset - 1); 109c05e22d7Smrg unget->buffer[unget->offset - 1] = ch; 110c05e22d7Smrg } 111c05e22d7Smrg else 112c05e22d7Smrg unget->buffer[unget->offset++] = ch; 1135dfecf96Smrg } 1145dfecf96Smrg 1155dfecf96Smrg return (ch); 1165dfecf96Smrg} 1175dfecf96Smrg 1185dfecf96Smrgvoid 1195dfecf96SmrgLispPushInput(LispObj *stream) 1205dfecf96Smrg{ 1215dfecf96Smrg if (!STREAMP(stream) || !stream->data.stream.readable) 1225dfecf96Smrg LispDestroy("bad stream at PUSH-INPUT"); 1235dfecf96Smrg lisp__data.input_list = CONS(stream, lisp__data.input_list); 1245dfecf96Smrg SINPUT = stream; 1255dfecf96Smrg if (lisp__data.iunget + 1 == lisp__data.nunget) { 1265dfecf96Smrg LispUngetInfo **info = 1275dfecf96Smrg realloc(lisp__data.unget, 1285dfecf96Smrg sizeof(LispUngetInfo) * (lisp__data.nunget + 1)); 1295dfecf96Smrg 1305dfecf96Smrg if (!info || 1315dfecf96Smrg (info[lisp__data.nunget] = 1325dfecf96Smrg calloc(1, sizeof(LispUngetInfo))) == NULL) 1335dfecf96Smrg LispDestroy("out of memory"); 1345dfecf96Smrg lisp__data.unget = info; 1355dfecf96Smrg ++lisp__data.nunget; 1365dfecf96Smrg } 1375dfecf96Smrg ++lisp__data.iunget; 1385dfecf96Smrg memset(lisp__data.unget[lisp__data.iunget], '\0', sizeof(LispUngetInfo)); 1395dfecf96Smrg lisp__data.eof = 0; 1405dfecf96Smrg} 1415dfecf96Smrg 1425dfecf96Smrgvoid 1435dfecf96SmrgLispPopInput(LispObj *stream) 1445dfecf96Smrg{ 1455dfecf96Smrg if (!CONSP(lisp__data.input_list) || stream != CAR(lisp__data.input_list)) 1465dfecf96Smrg LispDestroy("bad stream at POP-INPUT"); 1475dfecf96Smrg lisp__data.input_list = CDR(lisp__data.input_list); 1485dfecf96Smrg SINPUT = CONSP(lisp__data.input_list) ? 1495dfecf96Smrg CAR(lisp__data.input_list) : lisp__data.input_list; 1505dfecf96Smrg --lisp__data.iunget; 1515dfecf96Smrg lisp__data.eof = 0; 1525dfecf96Smrg} 1535dfecf96Smrg 1545dfecf96Smrg/* 1555dfecf96Smrg * Low level functions 1565dfecf96Smrg */ 1575dfecf96Smrgstatic int 158f765521fSmrgcalculate_line(const void *data, int size) 1595dfecf96Smrg{ 1605dfecf96Smrg int line = 0; 161f765521fSmrg const char *str, *ptr; 1625dfecf96Smrg 163f765521fSmrg for (str = (const char *)data, ptr = (const char *)data + size; 164f765521fSmrg str < ptr; str++) 1655dfecf96Smrg if (*ptr == '\n') 1665dfecf96Smrg ++line; 1675dfecf96Smrg 1685dfecf96Smrg return (line); 1695dfecf96Smrg} 1705dfecf96Smrg 1715dfecf96Smrgstatic int 172f765521fSmrgcalculate_column(const void *data, int size, int column) 1735dfecf96Smrg{ 174f765521fSmrg const char *str, *ptr; 1755dfecf96Smrg 1765dfecf96Smrg /* search for newline in data */ 177f765521fSmrg for (str = (const char *)data, ptr = (const char *)data + size - 1; 178f765521fSmrg ptr >= str; ptr--) 1795dfecf96Smrg if (*ptr == '\n') 1805dfecf96Smrg break; 1815dfecf96Smrg 1825dfecf96Smrg /* newline found */ 1835dfecf96Smrg if (ptr >= str) 1845dfecf96Smrg return (size - (ptr - str) - 1); 1855dfecf96Smrg 1865dfecf96Smrg /* newline not found */ 1875dfecf96Smrg return (column + size); 1885dfecf96Smrg} 1895dfecf96Smrg 1905dfecf96SmrgLispFile * 1915dfecf96SmrgLispFdopen(int descriptor, int mode) 1925dfecf96Smrg{ 1935dfecf96Smrg LispFile *file = calloc(1, sizeof(LispFile)); 1945dfecf96Smrg 1955dfecf96Smrg if (file) { 1965dfecf96Smrg struct stat st; 1975dfecf96Smrg 1985dfecf96Smrg file->descriptor = descriptor; 1995dfecf96Smrg file->readable = (mode & READ_BIT) != 0; 2005dfecf96Smrg file->writable = (mode & WRITE_BIT) != 0; 2015dfecf96Smrg 2025dfecf96Smrg if (fstat(descriptor, &st) == 0) 2035dfecf96Smrg file->regular = S_ISREG(st.st_mode); 2045dfecf96Smrg else 2055dfecf96Smrg file->regular = 0; 2065dfecf96Smrg 2075dfecf96Smrg file->buffered = (mode & BUFFERED_BIT) != 0; 2085dfecf96Smrg if ((mode & UNBUFFERED_BIT) == 0) 2095dfecf96Smrg file->buffered = file->regular; 2105dfecf96Smrg 2115dfecf96Smrg if (file->buffered) { 2125dfecf96Smrg file->buffer = malloc(pagesize); 2135dfecf96Smrg if (file->buffer == NULL) 2145dfecf96Smrg file->buffered = 0; 2155dfecf96Smrg } 2165dfecf96Smrg file->line = 1; 2175dfecf96Smrg file->binary = (mode & BINARY_BIT) != 0; 2185dfecf96Smrg file->io_write = write; 2195dfecf96Smrg } 2205dfecf96Smrg 2215dfecf96Smrg return (file); 2225dfecf96Smrg} 2235dfecf96Smrg 2245dfecf96SmrgLispFile * 225f765521fSmrgLispFopen(const char *path, int mode) 2265dfecf96Smrg{ 2275dfecf96Smrg LispFile *file; 2285dfecf96Smrg int descriptor; 2295dfecf96Smrg int flags = O_NOCTTY; 2305dfecf96Smrg 2315dfecf96Smrg /* check read/write attributes */ 2325dfecf96Smrg if ((mode & (READ_BIT | WRITE_BIT)) == (READ_BIT | WRITE_BIT)) 2335dfecf96Smrg flags |= O_RDWR; 2345dfecf96Smrg else if (mode & READ_BIT) 2355dfecf96Smrg flags |= O_RDONLY; 2365dfecf96Smrg else if (mode & WRITE_BIT) 2375dfecf96Smrg flags |= O_WRONLY; 2385dfecf96Smrg 2395dfecf96Smrg /* create if does not exist */ 2405dfecf96Smrg if (mode & WRITE_BIT) { 2415dfecf96Smrg flags |= O_CREAT; 2425dfecf96Smrg 2435dfecf96Smrg /* append if exists? */ 2445dfecf96Smrg if (mode & APPEND_BIT) 2455dfecf96Smrg flags |= O_APPEND; 2465dfecf96Smrg else 2475dfecf96Smrg flags |= O_TRUNC; 2485dfecf96Smrg } 2495dfecf96Smrg 2505dfecf96Smrg /* open file */ 2515dfecf96Smrg descriptor = open(path, flags, 0666); 2525dfecf96Smrg if (descriptor < 0) 2535dfecf96Smrg return (NULL); 2545dfecf96Smrg 2555dfecf96Smrg /* initialize LispFile structure */ 2565dfecf96Smrg file = LispFdopen(descriptor, mode); 2575dfecf96Smrg if (file == NULL) 2585dfecf96Smrg close(descriptor); 2595dfecf96Smrg 2605dfecf96Smrg return (file); 2615dfecf96Smrg} 2625dfecf96Smrg 2635dfecf96Smrgvoid 2645dfecf96SmrgLispFclose(LispFile *file) 2655dfecf96Smrg{ 2665dfecf96Smrg /* flush any pending output */ 2675dfecf96Smrg LispFflush(file); 2685dfecf96Smrg /* cleanup */ 2695dfecf96Smrg close(file->descriptor); 2705dfecf96Smrg if (file->buffer) 2715dfecf96Smrg free(file->buffer); 2725dfecf96Smrg free(file); 2735dfecf96Smrg} 2745dfecf96Smrg 2755dfecf96Smrgio_write_fn 2765dfecf96SmrgLispSetFileWrite(LispFile *file, io_write_fn new_write) 2775dfecf96Smrg{ 2785dfecf96Smrg io_write_fn old_write = file->io_write; 2795dfecf96Smrg 2805dfecf96Smrg file->io_write = new_write; 2815dfecf96Smrg 2825dfecf96Smrg return (old_write); 2835dfecf96Smrg} 2845dfecf96Smrg 2855dfecf96Smrgint 2865dfecf96SmrgLispFflush(LispFile *file) 2875dfecf96Smrg{ 2885dfecf96Smrg if (file->writable && file->length) { 2895dfecf96Smrg int length = (*file->io_write)(file->descriptor, 2905dfecf96Smrg file->buffer, file->length); 2915dfecf96Smrg 2925dfecf96Smrg if (length > 0) { 2935dfecf96Smrg if (file->length > length) 2945dfecf96Smrg memmove(file->buffer, file->buffer + length, 2955dfecf96Smrg file->length - length); 2965dfecf96Smrg file->length -= length; 2975dfecf96Smrg } 2985dfecf96Smrg return (length); 2995dfecf96Smrg } 3005dfecf96Smrg 3015dfecf96Smrg return (0); 3025dfecf96Smrg} 3035dfecf96Smrg 3045dfecf96Smrgint 3055dfecf96SmrgLispFungetc(LispFile *file, int ch) 3065dfecf96Smrg{ 3075dfecf96Smrg if (file->readable) { 3085dfecf96Smrg file->available = 1; 3095dfecf96Smrg file->unget = ch; 3105dfecf96Smrg /* this should never happen */ 3115dfecf96Smrg if (ch == '\n' && !file->binary) 3125dfecf96Smrg --file->line; 3135dfecf96Smrg } 3145dfecf96Smrg 3155dfecf96Smrg return (ch); 3165dfecf96Smrg} 3175dfecf96Smrg 3185dfecf96Smrgint 3195dfecf96SmrgLispFgetc(LispFile *file) 3205dfecf96Smrg{ 3215dfecf96Smrg int ch; 3225dfecf96Smrg 3235dfecf96Smrg if (file->readable) { 3245dfecf96Smrg unsigned char c; 3255dfecf96Smrg 3265dfecf96Smrg if (file->available) { 3275dfecf96Smrg ch = file->unget; 3285dfecf96Smrg file->available = 0; 3295dfecf96Smrg } 3305dfecf96Smrg else if (file->buffered) { 3315dfecf96Smrg if (file->writable) { 3325dfecf96Smrg LispFflush(file); 3335dfecf96Smrg if (read(file->descriptor, &c, 1) == 1) 3345dfecf96Smrg ch = c; 3355dfecf96Smrg else 3365dfecf96Smrg ch = EOF; 3375dfecf96Smrg } 3385dfecf96Smrg else { 3395dfecf96Smrg if (file->offset < file->length) 3405dfecf96Smrg ch = ((unsigned char*)file->buffer)[file->offset++]; 3415dfecf96Smrg else { 3425dfecf96Smrg int length = read(file->descriptor, 3435dfecf96Smrg file->buffer, pagesize); 3445dfecf96Smrg 3455dfecf96Smrg if (length >= 0) 3465dfecf96Smrg file->length = length; 3475dfecf96Smrg else 3485dfecf96Smrg file->length = 0; 3495dfecf96Smrg file->offset = 0; 3505dfecf96Smrg if (file->length) 3515dfecf96Smrg ch = ((unsigned char*)file->buffer)[file->offset++]; 3525dfecf96Smrg else 3535dfecf96Smrg ch = EOF; 3545dfecf96Smrg } 3555dfecf96Smrg } 3565dfecf96Smrg } 3575dfecf96Smrg else if (read(file->descriptor, &c, 1) == 1) 3585dfecf96Smrg ch = c; 3595dfecf96Smrg else 3605dfecf96Smrg ch = EOF; 3615dfecf96Smrg } 3625dfecf96Smrg else 3635dfecf96Smrg ch = EOF; 3645dfecf96Smrg 3655dfecf96Smrg if (ch == '\n' && !file->binary) 3665dfecf96Smrg ++file->line; 3675dfecf96Smrg 3685dfecf96Smrg return (ch); 3695dfecf96Smrg} 3705dfecf96Smrg 3715dfecf96Smrgint 3725dfecf96SmrgLispFputc(LispFile *file, int ch) 3735dfecf96Smrg{ 3745dfecf96Smrg if (file->writable) { 3755dfecf96Smrg unsigned char c = ch; 3765dfecf96Smrg 3775dfecf96Smrg if (file->buffered) { 3785dfecf96Smrg if (file->length + 1 >= pagesize) 3795dfecf96Smrg LispFflush(file); 3805dfecf96Smrg file->buffer[file->length++] = c; 3815dfecf96Smrg } 3825dfecf96Smrg else if ((*file->io_write)(file->descriptor, &c, 1) != 1) 3835dfecf96Smrg ch = EOF; 3845dfecf96Smrg 3855dfecf96Smrg if (!file->binary) { 3865dfecf96Smrg /* update column number */ 3875dfecf96Smrg if (ch == '\n') 3885dfecf96Smrg file->column = 0; 3895dfecf96Smrg else 3905dfecf96Smrg ++file->column; 3915dfecf96Smrg } 3925dfecf96Smrg } 3935dfecf96Smrg 3945dfecf96Smrg return (ch); 3955dfecf96Smrg} 3965dfecf96Smrg 3975dfecf96Smrgint 3985dfecf96SmrgLispSgetc(LispString *string) 3995dfecf96Smrg{ 4005dfecf96Smrg int ch; 4015dfecf96Smrg 4025dfecf96Smrg if (string->input >= string->length) 4035dfecf96Smrg return (EOF); /* EOF reading from string */ 4045dfecf96Smrg 4055dfecf96Smrg ch = ((unsigned char*)string->string)[string->input++]; 4065dfecf96Smrg if (ch == '\n' && !string->binary) 4075dfecf96Smrg ++string->line; 4085dfecf96Smrg 4095dfecf96Smrg return (ch); 4105dfecf96Smrg} 4115dfecf96Smrg 4125dfecf96Smrgint 4135dfecf96SmrgLispSputc(LispString *string, int ch) 4145dfecf96Smrg{ 4155dfecf96Smrg if (string->output + 1 >= string->space) { 4165dfecf96Smrg if (string->fixed) 4175dfecf96Smrg return (EOF); 4185dfecf96Smrg else { 4195dfecf96Smrg char *tmp = realloc(string->string, string->space + pagesize); 4205dfecf96Smrg 4215dfecf96Smrg if (tmp == NULL) 4225dfecf96Smrg return (EOF); 4235dfecf96Smrg string->string = tmp; 4245dfecf96Smrg string->space += pagesize; 4255dfecf96Smrg } 4265dfecf96Smrg } 4275dfecf96Smrg 4285dfecf96Smrg string->string[string->output++] = ch; 4295dfecf96Smrg if (string->length < string->output) 4305dfecf96Smrg string->length = string->output; 4315dfecf96Smrg 4325dfecf96Smrg /* update column number */ 4335dfecf96Smrg if (!string->binary) { 4345dfecf96Smrg if (ch == '\n') 4355dfecf96Smrg string->column = 0; 4365dfecf96Smrg else 4375dfecf96Smrg ++string->column; 4385dfecf96Smrg } 4395dfecf96Smrg 4405dfecf96Smrg return (ch); 4415dfecf96Smrg} 4425dfecf96Smrg 4435dfecf96Smrgchar * 4445dfecf96SmrgLispFgets(LispFile *file, char *string, int size) 4455dfecf96Smrg{ 4465dfecf96Smrg int ch, offset = 0; 4475dfecf96Smrg 4485dfecf96Smrg if (size < 1) 4495dfecf96Smrg return (string); 4505dfecf96Smrg 4515dfecf96Smrg for (;;) { 4525dfecf96Smrg if (offset + 1 >= size) 4535dfecf96Smrg break; 4545dfecf96Smrg if ((ch = LispFgetc(file)) == EOF) 4555dfecf96Smrg break; 4565dfecf96Smrg string[offset++] = ch; 4575dfecf96Smrg /* line number is calculated in LispFgetc */ 4585dfecf96Smrg if (ch == '\n') 4595dfecf96Smrg break; 4605dfecf96Smrg } 4615dfecf96Smrg string[offset] = '\0'; 4625dfecf96Smrg 4635dfecf96Smrg return (offset ? string : NULL); 4645dfecf96Smrg} 4655dfecf96Smrg 4665dfecf96Smrgint 467f765521fSmrgLispFputs(LispFile *file, const char *buffer) 4685dfecf96Smrg{ 4695dfecf96Smrg return (LispFwrite(file, buffer, strlen(buffer))); 4705dfecf96Smrg} 4715dfecf96Smrg 4725dfecf96Smrgint 473f765521fSmrgLispSputs(LispString *string, const char *buffer) 4745dfecf96Smrg{ 4755dfecf96Smrg return (LispSwrite(string, buffer, strlen(buffer))); 4765dfecf96Smrg} 4775dfecf96Smrg 4785dfecf96Smrgint 4795dfecf96SmrgLispFread(LispFile *file, void *data, int size) 4805dfecf96Smrg{ 4815dfecf96Smrg int bytes, length; 4825dfecf96Smrg char *buffer; 4835dfecf96Smrg 4845dfecf96Smrg if (!file->readable) 4855dfecf96Smrg return (EOF); 4865dfecf96Smrg 4875dfecf96Smrg if (size <= 0) 4885dfecf96Smrg return (size); 4895dfecf96Smrg 4905dfecf96Smrg length = 0; 4915dfecf96Smrg buffer = (char*)data; 4925dfecf96Smrg 4935dfecf96Smrg /* check if there is an unget character */ 4945dfecf96Smrg if (file->available) { 4955dfecf96Smrg *buffer++ = file->unget; 4965dfecf96Smrg file->available = 0; 4975dfecf96Smrg if (--size == 0) { 4985dfecf96Smrg if (file->unget == '\n' && !file->binary) 4995dfecf96Smrg ++file->line; 5005dfecf96Smrg 5015dfecf96Smrg return (1); 5025dfecf96Smrg } 5035dfecf96Smrg 5045dfecf96Smrg length = 1; 5055dfecf96Smrg } 5065dfecf96Smrg 5075dfecf96Smrg if (file->buffered) { 5085dfecf96Smrg void *base_data = (char*)data - length; 5095dfecf96Smrg 5105dfecf96Smrg if (file->writable) { 5115dfecf96Smrg LispFflush(file); 5125dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5135dfecf96Smrg if (bytes < 0) 5145dfecf96Smrg bytes = 0; 5155dfecf96Smrg if (!file->binary) 5165dfecf96Smrg file->line += calculate_line(base_data, length + bytes); 5175dfecf96Smrg 5185dfecf96Smrg return (length + bytes); 5195dfecf96Smrg } 5205dfecf96Smrg 5215dfecf96Smrg /* read anything that is in the buffer */ 5225dfecf96Smrg if (file->offset < file->length) { 5235dfecf96Smrg bytes = file->length - file->offset; 5245dfecf96Smrg if (bytes > size) 5255dfecf96Smrg bytes = size; 5265dfecf96Smrg memcpy(buffer, file->buffer + file->offset, bytes); 5275dfecf96Smrg buffer += bytes; 5285dfecf96Smrg file->offset += bytes; 5295dfecf96Smrg size -= bytes; 5305dfecf96Smrg } 5315dfecf96Smrg 5325dfecf96Smrg /* if there is still something to read */ 5335dfecf96Smrg if (size) { 5345dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5355dfecf96Smrg if (bytes < 0) 5365dfecf96Smrg bytes = 0; 5375dfecf96Smrg 5385dfecf96Smrg length += bytes; 5395dfecf96Smrg } 5405dfecf96Smrg 5415dfecf96Smrg if (!file->binary) 5425dfecf96Smrg file->line += calculate_line(base_data, length); 5435dfecf96Smrg 5445dfecf96Smrg return (length); 5455dfecf96Smrg } 5465dfecf96Smrg 5475dfecf96Smrg bytes = read(file->descriptor, buffer, size); 5485dfecf96Smrg if (bytes < 0) 5495dfecf96Smrg bytes = 0; 5505dfecf96Smrg if (!file->binary) 5515dfecf96Smrg file->line += calculate_line(buffer - length, length + bytes); 5525dfecf96Smrg 5535dfecf96Smrg return (length + bytes); 5545dfecf96Smrg} 5555dfecf96Smrg 5565dfecf96Smrgint 557f765521fSmrgLispFwrite(LispFile *file, const void *data, int size) 5585dfecf96Smrg{ 5595dfecf96Smrg if (!file->writable || size < 0) 5605dfecf96Smrg return (EOF); 5615dfecf96Smrg 5625dfecf96Smrg if (!file->binary) 5635dfecf96Smrg file->column = calculate_column(data, size, file->column); 5645dfecf96Smrg 5655dfecf96Smrg if (file->buffered) { 5665dfecf96Smrg int length, bytes; 567f765521fSmrg const char *buffer = (const char *)data; 5685dfecf96Smrg 5695dfecf96Smrg length = 0; 5705dfecf96Smrg if (size + file->length > pagesize) { 5715dfecf96Smrg /* fill remaining space in buffer and flush */ 5725dfecf96Smrg bytes = pagesize - file->length; 5735dfecf96Smrg memcpy(file->buffer + file->length, buffer, bytes); 5745dfecf96Smrg file->length += bytes; 5755dfecf96Smrg LispFflush(file); 5765dfecf96Smrg 5775dfecf96Smrg /* check if all data was written */ 5785dfecf96Smrg if (file->length) 5795dfecf96Smrg return (pagesize - file->length); 5805dfecf96Smrg 5815dfecf96Smrg length = bytes; 5825dfecf96Smrg buffer += bytes; 5835dfecf96Smrg size -= bytes; 5845dfecf96Smrg } 5855dfecf96Smrg 5865dfecf96Smrg while (size > pagesize) { 5875dfecf96Smrg /* write multiple of pagesize */ 5885dfecf96Smrg bytes = (*file->io_write)(file->descriptor, buffer, 5895dfecf96Smrg size - (size % pagesize)); 5905dfecf96Smrg if (bytes <= 0) 5915dfecf96Smrg return (length); 5925dfecf96Smrg 5935dfecf96Smrg length += bytes; 5945dfecf96Smrg buffer += bytes; 5955dfecf96Smrg size -= bytes; 5965dfecf96Smrg } 5975dfecf96Smrg 5985dfecf96Smrg if (size) { 5995dfecf96Smrg /* keep remaining data in buffer */ 6005dfecf96Smrg switch (size) { 6015dfecf96Smrg case 8: 6025dfecf96Smrg file->buffer[file->length++] = *buffer++; 6035dfecf96Smrg case 7: 6045dfecf96Smrg file->buffer[file->length++] = *buffer++; 6055dfecf96Smrg case 6: 6065dfecf96Smrg file->buffer[file->length++] = *buffer++; 6075dfecf96Smrg case 5: 6085dfecf96Smrg file->buffer[file->length++] = *buffer++; 6095dfecf96Smrg case 4: 6105dfecf96Smrg file->buffer[file->length++] = *buffer++; 6115dfecf96Smrg case 3: 6125dfecf96Smrg file->buffer[file->length++] = *buffer++; 6135dfecf96Smrg case 2: 6145dfecf96Smrg file->buffer[file->length++] = *buffer++; 6155dfecf96Smrg case 1: 6165dfecf96Smrg file->buffer[file->length++] = *buffer++; 6175dfecf96Smrg break; 6185dfecf96Smrg default: 6195dfecf96Smrg memcpy(file->buffer + file->length, buffer, size); 6205dfecf96Smrg file->length += size; 6215dfecf96Smrg break; 6225dfecf96Smrg } 6235dfecf96Smrg length += size; 6245dfecf96Smrg } 6255dfecf96Smrg 6265dfecf96Smrg return (length); 6275dfecf96Smrg } 6285dfecf96Smrg 6295dfecf96Smrg return ((*file->io_write)(file->descriptor, data, size)); 6305dfecf96Smrg} 6315dfecf96Smrg 6325dfecf96Smrgint 633f765521fSmrgLispSwrite(LispString *string, const void *data, int size) 6345dfecf96Smrg{ 635f14f4646Smrg int bytes; 636f14f4646Smrg 6375dfecf96Smrg if (size < 0) 6385dfecf96Smrg return (EOF); 6395dfecf96Smrg 6405dfecf96Smrg if (string->output + size >= string->space) { 6415dfecf96Smrg if (string->fixed) { 6425dfecf96Smrg /* leave space for a ending nul character */ 643f14f4646Smrg bytes = string->space - string->output - 1; 644f14f4646Smrg 645f14f4646Smrg if (bytes < size) 646f14f4646Smrg size = bytes; 6475dfecf96Smrg 6485dfecf96Smrg if (size <= 0) 6495dfecf96Smrg return (-1); 6505dfecf96Smrg } 6515dfecf96Smrg else { 652f14f4646Smrg char *tmp; 653f14f4646Smrg 654f14f4646Smrg bytes = string->space + size; 655f14f4646Smrg bytes += pagesize - (bytes % pagesize); 656f14f4646Smrg tmp = realloc(string->string, bytes); 6575dfecf96Smrg 6585dfecf96Smrg if (tmp == NULL) 6595dfecf96Smrg return (-1); 6605dfecf96Smrg 6615dfecf96Smrg string->string = tmp; 662f14f4646Smrg string->space = bytes; 6635dfecf96Smrg } 6645dfecf96Smrg } 6655dfecf96Smrg memcpy(string->string + string->output, data, size); 6665dfecf96Smrg string->output += size; 6675dfecf96Smrg if (string->length < string->output) 6685dfecf96Smrg string->length = string->output; 6695dfecf96Smrg 6705dfecf96Smrg if (!string->binary) 6715dfecf96Smrg string->column = calculate_column(data, size, string->column); 6725dfecf96Smrg 6735dfecf96Smrg return (size); 6745dfecf96Smrg} 6755dfecf96Smrg 676f765521fSmrgconst char * 6775dfecf96SmrgLispGetSstring(LispString *string, int *length) 6785dfecf96Smrg{ 6795dfecf96Smrg if (string->string == NULL || string->length <= 0) { 6805dfecf96Smrg *length = 0; 6815dfecf96Smrg 6825dfecf96Smrg return (""); 6835dfecf96Smrg } 6845dfecf96Smrg *length = string->length; 6855dfecf96Smrg if (string->string[string->length -1] != '\0') { 6865dfecf96Smrg if (string->length < string->space) 6875dfecf96Smrg string->string[string->length] = '\0'; 6885dfecf96Smrg else if (string->fixed && string->space) 6895dfecf96Smrg string->string[string->space - 1] = '\0'; 6905dfecf96Smrg else { 6915dfecf96Smrg char *tmp = realloc(string->string, string->space + pagesize); 6925dfecf96Smrg 6935dfecf96Smrg if (tmp == NULL) 6945dfecf96Smrg string->string[string->space - 1] = '\0'; 6955dfecf96Smrg else { 6965dfecf96Smrg string->string = tmp; 6975dfecf96Smrg string->space += pagesize; 6985dfecf96Smrg string->string[string->length] = '\0'; 6995dfecf96Smrg } 7005dfecf96Smrg } 7015dfecf96Smrg } 7025dfecf96Smrg 7035dfecf96Smrg return (string->string); 7045dfecf96Smrg} 7055dfecf96Smrg 7065dfecf96Smrgint 707f765521fSmrgLispRename(const char *from, const char *to) 7085dfecf96Smrg{ 7095dfecf96Smrg return (rename(from, to)); 7105dfecf96Smrg} 7115dfecf96Smrg 7125dfecf96Smrgint 713f765521fSmrgLispUnlink(const char *name) 7145dfecf96Smrg{ 7155dfecf96Smrg return (unlink(name)); 7165dfecf96Smrg} 717