histfile.c (47558) | histfile.c (58310) |
---|---|
1/* histfile.c - functions to manipulate the history file. */ 2 3/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. 4 5 This file contains the GNU History Library (the Library), a set of 6 routines for managing the text of previously typed lines. 7 8 The Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by | 1/* histfile.c - functions to manipulate the history file. */ 2 3/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. 4 5 This file contains the GNU History Library (the Library), a set of 6 routines for managing the text of previously typed lines. 7 8 The Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by |
10 the Free Software Foundation; either version 1, or (at your option) | 10 the Free Software Foundation; either version 2, or (at your option) |
11 any later version. 12 13 The Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 The GNU General Public License is often shipped with GNU software, and 19 is generally kept in a file called COPYING or LICENSE. If you do not 20 have a copy of the license, write to the Free Software Foundation, | 11 any later version. 12 13 The Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 The GNU General Public License is often shipped with GNU software, and 19 is generally kept in a file called COPYING or LICENSE. If you do not 20 have a copy of the license, write to the Free Software Foundation, |
21 675 Mass Ave, Cambridge, MA 02139, USA. */ | 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ |
22 23/* The goal is to make the implementation transparent, so that you 24 don't have to know what data types are used, just what functions 25 you can call. I think I have done that. */ 26#define READLINE_LIBRARY 27 28#if defined (HAVE_CONFIG_H) 29# include <config.h> 30#endif 31 32#include <stdio.h> 33 34#include <sys/types.h> 35#ifndef _MINIX 36# include <sys/file.h> 37#endif | 22 23/* The goal is to make the implementation transparent, so that you 24 don't have to know what data types are used, just what functions 25 you can call. I think I have done that. */ 26#define READLINE_LIBRARY 27 28#if defined (HAVE_CONFIG_H) 29# include <config.h> 30#endif 31 32#include <stdio.h> 33 34#include <sys/types.h> 35#ifndef _MINIX 36# include <sys/file.h> 37#endif |
38#include <sys/stat.h> | 38#include "posixstat.h" |
39#include <fcntl.h> 40 41#if defined (HAVE_STDLIB_H) 42# include <stdlib.h> 43#else 44# include "ansi_stdlib.h" 45#endif /* HAVE_STDLIB_H */ 46 47#if defined (HAVE_UNISTD_H) 48# include <unistd.h> 49#endif 50 51#if defined (HAVE_STRING_H) 52# include <string.h> 53#else 54# include <strings.h> 55#endif /* !HAVE_STRING_H */ 56 | 39#include <fcntl.h> 40 41#if defined (HAVE_STDLIB_H) 42# include <stdlib.h> 43#else 44# include "ansi_stdlib.h" 45#endif /* HAVE_STDLIB_H */ 46 47#if defined (HAVE_UNISTD_H) 48# include <unistd.h> 49#endif 50 51#if defined (HAVE_STRING_H) 52# include <string.h> 53#else 54# include <strings.h> 55#endif /* !HAVE_STRING_H */ 56 |
57#if defined (__EMX__) | 57 58/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment 59 on win 95/98/nt), we want to open files with O_BINARY mode so that there 60 is no \n -> \r\n conversion performed. On other systems, we don't want to 61 mess around with O_BINARY at all, so we ensure that it's defined to 0. */ 62#if defined (__EMX__) || defined (__CYGWIN__) |
58# ifndef O_BINARY 59# define O_BINARY 0 60# endif | 63# ifndef O_BINARY 64# define O_BINARY 0 65# endif |
61#else /* !__EMX__ */ 62 /* If we're not compiling for __EMX__, we don't want this at all. Ever. */ | 66#else /* !__EMX__ && !__CYGWIN__ */ |
63# undef O_BINARY 64# define O_BINARY 0 | 67# undef O_BINARY 68# define O_BINARY 0 |
65#endif /* !__EMX__ */ | 69#endif /* !__EMX__ && !__CYGWIN__ */ |
66 67#include <errno.h> 68#if !defined (errno) 69extern int errno; 70#endif /* !errno */ 71 72#include "history.h" 73#include "histlib.h" 74 | 70 71#include <errno.h> 72#if !defined (errno) 73extern int errno; 74#endif /* !errno */ 75 76#include "history.h" 77#include "histlib.h" 78 |
75/* Functions imported from shell.c */ 76extern char *get_env_value (); | 79#include "rlshell.h" 80#include "xmalloc.h" |
77 | 81 |
78extern char *xmalloc (), *xrealloc (); 79 | |
80/* Return the string that should be used in the place of this 81 filename. This only matters when you don't specify the 82 filename to read_history (), or write_history (). */ 83static char * 84history_filename (filename) 85 char *filename; 86{ 87 char *return_val, *home; --- 12 unchanged lines hidden (view full) --- 100 home_len = 1; 101 } 102 else 103 home_len = strlen (home); 104 105 return_val = xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ 106 strcpy (return_val, home); 107 return_val[home_len] = '/'; | 82/* Return the string that should be used in the place of this 83 filename. This only matters when you don't specify the 84 filename to read_history (), or write_history (). */ 85static char * 86history_filename (filename) 87 char *filename; 88{ 89 char *return_val, *home; --- 12 unchanged lines hidden (view full) --- 102 home_len = 1; 103 } 104 else 105 home_len = strlen (home); 106 107 return_val = xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ 108 strcpy (return_val, home); 109 return_val[home_len] = '/'; |
110#if defined (__MSDOS__) 111 strcpy (return_val + home_len + 1, "_history"); 112#else |
|
108 strcpy (return_val + home_len + 1, ".history"); | 113 strcpy (return_val + home_len + 1, ".history"); |
114#endif |
|
109 110 return (return_val); 111} 112 113/* Add the contents of FILENAME to the history list, a line at a time. 114 If FILENAME is NULL, then read from ~/.history. Returns 0 if 115 successful, or errno if not. */ 116int --- 10 unchanged lines hidden (view full) --- 127 ~/.history. Returns 0 if successful, or errno if not. */ 128int 129read_history_range (filename, from, to) 130 char *filename; 131 int from, to; 132{ 133 register int line_start, line_end; 134 char *input, *buffer; | 115 116 return (return_val); 117} 118 119/* Add the contents of FILENAME to the history list, a line at a time. 120 If FILENAME is NULL, then read from ~/.history. Returns 0 if 121 successful, or errno if not. */ 122int --- 10 unchanged lines hidden (view full) --- 133 ~/.history. Returns 0 if successful, or errno if not. */ 134int 135read_history_range (filename, from, to) 136 char *filename; 137 int from, to; 138{ 139 register int line_start, line_end; 140 char *input, *buffer; |
135 int file, current_line; | 141 int file, current_line, chars_read; |
136 struct stat finfo; 137 size_t file_size; 138 139 buffer = (char *)NULL; 140 input = history_filename (filename); 141 file = open (input, O_RDONLY|O_BINARY, 0666); 142 143 if ((file < 0) || (fstat (file, &finfo) == -1)) --- 6 unchanged lines hidden (view full) --- 150 { 151#if defined (EFBIG) 152 errno = EFBIG; 153#endif 154 goto error_and_exit; 155 } 156 157 buffer = xmalloc (file_size + 1); | 142 struct stat finfo; 143 size_t file_size; 144 145 buffer = (char *)NULL; 146 input = history_filename (filename); 147 file = open (input, O_RDONLY|O_BINARY, 0666); 148 149 if ((file < 0) || (fstat (file, &finfo) == -1)) --- 6 unchanged lines hidden (view full) --- 156 { 157#if defined (EFBIG) 158 errno = EFBIG; 159#endif 160 goto error_and_exit; 161 } 162 163 buffer = xmalloc (file_size + 1); |
158#if 0 159 if (read (file, buffer, file_size) != file_size) 160#else 161 if (read (file, buffer, file_size) < 0) 162#endif | 164 165 chars_read = read (file, buffer, file_size); 166 if (chars_read < 0) |
163 { 164 error_and_exit: 165 if (file >= 0) 166 close (file); 167 168 FREE (input); 169 FREE (buffer); 170 171 return (errno); 172 } 173 174 close (file); 175 176 /* Set TO to larger than end of file if negative. */ 177 if (to < 0) | 167 { 168 error_and_exit: 169 if (file >= 0) 170 close (file); 171 172 FREE (input); 173 FREE (buffer); 174 175 return (errno); 176 } 177 178 close (file); 179 180 /* Set TO to larger than end of file if negative. */ 181 if (to < 0) |
178 to = file_size; | 182 to = chars_read; |
179 180 /* Start at beginning of file, work to end. */ 181 line_start = line_end = current_line = 0; 182 183 /* Skip lines until we are at FROM. */ | 183 184 /* Start at beginning of file, work to end. */ 185 line_start = line_end = current_line = 0; 186 187 /* Skip lines until we are at FROM. */ |
184 while (line_start < file_size && current_line < from) | 188 while (line_start < chars_read && current_line < from) |
185 { | 189 { |
186 for (line_end = line_start; line_end < file_size; line_end++) | 190 for (line_end = line_start; line_end < chars_read; line_end++) |
187 if (buffer[line_end] == '\n') 188 { 189 current_line++; 190 line_start = line_end + 1; 191 if (current_line == from) 192 break; 193 } 194 } 195 196 /* If there are lines left to gobble, then gobble them now. */ | 191 if (buffer[line_end] == '\n') 192 { 193 current_line++; 194 line_start = line_end + 1; 195 if (current_line == from) 196 break; 197 } 198 } 199 200 /* If there are lines left to gobble, then gobble them now. */ |
197 for (line_end = line_start; line_end < file_size; line_end++) | 201 for (line_end = line_start; line_end < chars_read; line_end++) |
198 if (buffer[line_end] == '\n') 199 { 200 buffer[line_end] = '\0'; 201 202 if (buffer[line_start]) 203 add_history (buffer + line_start); 204 205 current_line++; --- 25 unchanged lines hidden (view full) --- 231 232 buffer = (char *)NULL; 233 filename = history_filename (fname); 234 file = open (filename, O_RDONLY|O_BINARY, 0666); 235 236 if (file == -1 || fstat (file, &finfo) == -1) 237 goto truncate_exit; 238 | 202 if (buffer[line_end] == '\n') 203 { 204 buffer[line_end] = '\0'; 205 206 if (buffer[line_start]) 207 add_history (buffer + line_start); 208 209 current_line++; --- 25 unchanged lines hidden (view full) --- 235 236 buffer = (char *)NULL; 237 filename = history_filename (fname); 238 file = open (filename, O_RDONLY|O_BINARY, 0666); 239 240 if (file == -1 || fstat (file, &finfo) == -1) 241 goto truncate_exit; 242 |
243 /* Don't try to truncate non-regular files. */ 244 if (S_ISREG(finfo.st_mode) == 0) 245 goto truncate_exit; 246 |
|
239 file_size = (size_t)finfo.st_size; 240 241 /* check for overflow on very large files */ 242 if (file_size != finfo.st_size || file_size + 1 < file_size) 243 { 244 close (file); 245#if defined (EFBIG) 246 errno = EFBIG; --- 27 unchanged lines hidden (view full) --- 274 i++; 275 break; 276 } 277 278 /* Write only if there are more lines in the file than we want to 279 truncate to. */ 280 if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) 281 { | 247 file_size = (size_t)finfo.st_size; 248 249 /* check for overflow on very large files */ 250 if (file_size != finfo.st_size || file_size + 1 < file_size) 251 { 252 close (file); 253#if defined (EFBIG) 254 errno = EFBIG; --- 27 unchanged lines hidden (view full) --- 282 i++; 283 break; 284 } 285 286 /* Write only if there are more lines in the file than we want to 287 truncate to. */ 288 if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) 289 { |
282 write (file, buffer + i, file_size - i); | 290 write (file, buffer + i, chars_read - i); |
283 284#if defined (__BEOS__) 285 /* BeOS ignores O_TRUNC. */ | 291 292#if defined (__BEOS__) 293 /* BeOS ignores O_TRUNC. */ |
286 ftruncate (file, file_size - i); | 294 ftruncate (file, chars_read - i); |
287#endif 288 289 close (file); 290 } 291 292 truncate_exit: 293 294 FREE (buffer); --- 82 unchanged lines hidden --- | 295#endif 296 297 close (file); 298 } 299 300 truncate_exit: 301 302 FREE (buffer); --- 82 unchanged lines hidden --- |