1 1.1 mrg /* Implementation of the FGET, FGETC, FPUT, FPUTC, FLUSH 2 1.1 mrg FTELL, TTYNAM and ISATTY intrinsics. 3 1.1.1.3 mrg Copyright (C) 2005-2022 Free Software Foundation, Inc. 4 1.1 mrg 5 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran). 6 1.1 mrg 7 1.1 mrg Libgfortran is free software; you can redistribute it and/or 8 1.1 mrg modify it under the terms of the GNU General Public 9 1.1 mrg License as published by the Free Software Foundation; either 10 1.1 mrg version 3 of the License, or (at your option) any later version. 11 1.1 mrg 12 1.1 mrg Libgfortran is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 18 1.1 mrg permissions described in the GCC Runtime Library Exception, version 19 1.1 mrg 3.1, as published by the Free Software Foundation. 20 1.1 mrg 21 1.1 mrg You should have received a copy of the GNU General Public License and 22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 1.1 mrg <http://www.gnu.org/licenses/>. */ 25 1.1 mrg 26 1.1 mrg #include "io.h" 27 1.1 mrg #include "fbuf.h" 28 1.1 mrg #include "unix.h" 29 1.1 mrg #include <string.h> 30 1.1 mrg 31 1.1 mrg 32 1.1 mrg static const int five = 5; 33 1.1 mrg static const int six = 6; 34 1.1 mrg 35 1.1 mrg extern int PREFIX(fgetc) (const int *, char *, gfc_charlen_type); 36 1.1 mrg export_proto_np(PREFIX(fgetc)); 37 1.1 mrg 38 1.1 mrg int 39 1.1 mrg PREFIX(fgetc) (const int *unit, char *c, gfc_charlen_type c_len) 40 1.1 mrg { 41 1.1 mrg int ret; 42 1.1 mrg gfc_unit *u = find_unit (*unit); 43 1.1 mrg 44 1.1 mrg if (u == NULL) 45 1.1 mrg return -1; 46 1.1 mrg 47 1.1 mrg fbuf_reset (u); 48 1.1 mrg if (u->mode == WRITING) 49 1.1 mrg { 50 1.1 mrg sflush (u->s); 51 1.1 mrg u->mode = READING; 52 1.1 mrg } 53 1.1 mrg 54 1.1 mrg memset (c, ' ', c_len); 55 1.1 mrg ret = sread (u->s, c, 1); 56 1.1 mrg unlock_unit (u); 57 1.1 mrg 58 1.1 mrg if (ret < 0) 59 1.1 mrg return ret; 60 1.1 mrg 61 1.1 mrg if (ret != 1) 62 1.1 mrg return -1; 63 1.1 mrg else 64 1.1 mrg return 0; 65 1.1 mrg } 66 1.1 mrg 67 1.1 mrg 68 1.1 mrg #define FGETC_SUB(kind) \ 69 1.1 mrg extern void fgetc_i ## kind ## _sub \ 70 1.1 mrg (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \ 71 1.1 mrg export_proto(fgetc_i ## kind ## _sub); \ 72 1.1 mrg void fgetc_i ## kind ## _sub \ 73 1.1 mrg (const int *unit, char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \ 74 1.1 mrg { if (st != NULL) \ 75 1.1 mrg *st = PREFIX(fgetc) (unit, c, c_len); \ 76 1.1 mrg else \ 77 1.1 mrg PREFIX(fgetc) (unit, c, c_len); } 78 1.1 mrg 79 1.1 mrg FGETC_SUB(1) 80 1.1 mrg FGETC_SUB(2) 81 1.1 mrg FGETC_SUB(4) 82 1.1 mrg FGETC_SUB(8) 83 1.1 mrg 84 1.1 mrg 85 1.1 mrg extern int PREFIX(fget) (char *, gfc_charlen_type); 86 1.1 mrg export_proto_np(PREFIX(fget)); 87 1.1 mrg 88 1.1 mrg int 89 1.1 mrg PREFIX(fget) (char *c, gfc_charlen_type c_len) 90 1.1 mrg { 91 1.1 mrg return PREFIX(fgetc) (&five, c, c_len); 92 1.1 mrg } 93 1.1 mrg 94 1.1 mrg 95 1.1 mrg #define FGET_SUB(kind) \ 96 1.1 mrg extern void fget_i ## kind ## _sub \ 97 1.1 mrg (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \ 98 1.1 mrg export_proto(fget_i ## kind ## _sub); \ 99 1.1 mrg void fget_i ## kind ## _sub \ 100 1.1 mrg (char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \ 101 1.1 mrg { if (st != NULL) \ 102 1.1 mrg *st = PREFIX(fgetc) (&five, c, c_len); \ 103 1.1 mrg else \ 104 1.1 mrg PREFIX(fgetc) (&five, c, c_len); } 105 1.1 mrg 106 1.1 mrg FGET_SUB(1) 107 1.1 mrg FGET_SUB(2) 108 1.1 mrg FGET_SUB(4) 109 1.1 mrg FGET_SUB(8) 110 1.1 mrg 111 1.1 mrg 112 1.1 mrg 113 1.1 mrg extern int PREFIX(fputc) (const int *, char *, gfc_charlen_type); 114 1.1 mrg export_proto_np(PREFIX(fputc)); 115 1.1 mrg 116 1.1 mrg int 117 1.1 mrg PREFIX(fputc) (const int *unit, char *c, 118 1.1 mrg gfc_charlen_type c_len __attribute__((unused))) 119 1.1 mrg { 120 1.1 mrg ssize_t s; 121 1.1 mrg gfc_unit *u = find_unit (*unit); 122 1.1 mrg 123 1.1 mrg if (u == NULL) 124 1.1 mrg return -1; 125 1.1 mrg 126 1.1 mrg fbuf_reset (u); 127 1.1 mrg if (u->mode == READING) 128 1.1 mrg { 129 1.1 mrg sflush (u->s); 130 1.1 mrg u->mode = WRITING; 131 1.1 mrg } 132 1.1 mrg 133 1.1 mrg s = swrite (u->s, c, 1); 134 1.1 mrg unlock_unit (u); 135 1.1 mrg if (s < 0) 136 1.1 mrg return -1; 137 1.1 mrg return 0; 138 1.1 mrg } 139 1.1 mrg 140 1.1 mrg 141 1.1 mrg #define FPUTC_SUB(kind) \ 142 1.1 mrg extern void fputc_i ## kind ## _sub \ 143 1.1 mrg (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \ 144 1.1 mrg export_proto(fputc_i ## kind ## _sub); \ 145 1.1 mrg void fputc_i ## kind ## _sub \ 146 1.1 mrg (const int *unit, char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \ 147 1.1 mrg { if (st != NULL) \ 148 1.1 mrg *st = PREFIX(fputc) (unit, c, c_len); \ 149 1.1 mrg else \ 150 1.1 mrg PREFIX(fputc) (unit, c, c_len); } 151 1.1 mrg 152 1.1 mrg FPUTC_SUB(1) 153 1.1 mrg FPUTC_SUB(2) 154 1.1 mrg FPUTC_SUB(4) 155 1.1 mrg FPUTC_SUB(8) 156 1.1 mrg 157 1.1 mrg 158 1.1 mrg extern int PREFIX(fput) (char *, gfc_charlen_type); 159 1.1 mrg export_proto_np(PREFIX(fput)); 160 1.1 mrg 161 1.1 mrg int 162 1.1 mrg PREFIX(fput) (char *c, gfc_charlen_type c_len) 163 1.1 mrg { 164 1.1 mrg return PREFIX(fputc) (&six, c, c_len); 165 1.1 mrg } 166 1.1 mrg 167 1.1 mrg 168 1.1 mrg #define FPUT_SUB(kind) \ 169 1.1 mrg extern void fput_i ## kind ## _sub \ 170 1.1 mrg (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \ 171 1.1 mrg export_proto(fput_i ## kind ## _sub); \ 172 1.1 mrg void fput_i ## kind ## _sub \ 173 1.1 mrg (char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \ 174 1.1 mrg { if (st != NULL) \ 175 1.1 mrg *st = PREFIX(fputc) (&six, c, c_len); \ 176 1.1 mrg else \ 177 1.1 mrg PREFIX(fputc) (&six, c, c_len); } 178 1.1 mrg 179 1.1 mrg FPUT_SUB(1) 180 1.1 mrg FPUT_SUB(2) 181 1.1 mrg FPUT_SUB(4) 182 1.1 mrg FPUT_SUB(8) 183 1.1 mrg 184 1.1 mrg 185 1.1 mrg /* SUBROUTINE FLUSH(UNIT) 186 1.1 mrg INTEGER, INTENT(IN), OPTIONAL :: UNIT */ 187 1.1 mrg 188 1.1 mrg extern void flush_i4 (GFC_INTEGER_4 *); 189 1.1 mrg export_proto(flush_i4); 190 1.1 mrg 191 1.1 mrg void 192 1.1 mrg flush_i4 (GFC_INTEGER_4 *unit) 193 1.1 mrg { 194 1.1 mrg gfc_unit *us; 195 1.1 mrg 196 1.1 mrg /* flush all streams */ 197 1.1 mrg if (unit == NULL) 198 1.1 mrg flush_all_units (); 199 1.1 mrg else 200 1.1 mrg { 201 1.1 mrg us = find_unit (*unit); 202 1.1 mrg if (us != NULL) 203 1.1 mrg { 204 1.1 mrg sflush (us->s); 205 1.1 mrg unlock_unit (us); 206 1.1 mrg } 207 1.1 mrg } 208 1.1 mrg } 209 1.1 mrg 210 1.1 mrg 211 1.1 mrg extern void flush_i8 (GFC_INTEGER_8 *); 212 1.1 mrg export_proto(flush_i8); 213 1.1 mrg 214 1.1 mrg void 215 1.1 mrg flush_i8 (GFC_INTEGER_8 *unit) 216 1.1 mrg { 217 1.1 mrg gfc_unit *us; 218 1.1 mrg 219 1.1 mrg /* flush all streams */ 220 1.1 mrg if (unit == NULL) 221 1.1 mrg flush_all_units (); 222 1.1 mrg else 223 1.1 mrg { 224 1.1 mrg us = find_unit (*unit); 225 1.1 mrg if (us != NULL) 226 1.1 mrg { 227 1.1 mrg sflush (us->s); 228 1.1 mrg unlock_unit (us); 229 1.1 mrg } 230 1.1 mrg } 231 1.1 mrg } 232 1.1 mrg 233 1.1 mrg /* FSEEK intrinsic */ 234 1.1 mrg 235 1.1 mrg extern void fseek_sub (int *, GFC_IO_INT *, int *, int *); 236 1.1 mrg export_proto(fseek_sub); 237 1.1 mrg 238 1.1 mrg void 239 1.1 mrg fseek_sub (int *unit, GFC_IO_INT *offset, int *whence, int *status) 240 1.1 mrg { 241 1.1 mrg gfc_unit *u = find_unit (*unit); 242 1.1 mrg ssize_t result = -1; 243 1.1 mrg 244 1.1 mrg if (u != NULL) 245 1.1 mrg { 246 1.1 mrg result = sseek(u->s, *offset, *whence); 247 1.1 mrg 248 1.1 mrg unlock_unit (u); 249 1.1 mrg } 250 1.1 mrg 251 1.1 mrg if (status) 252 1.1 mrg *status = (result < 0 ? -1 : 0); 253 1.1 mrg } 254 1.1 mrg 255 1.1 mrg 256 1.1 mrg 257 1.1 mrg /* FTELL intrinsic */ 258 1.1 mrg 259 1.1 mrg static gfc_offset 260 1.1 mrg gf_ftell (int unit) 261 1.1 mrg { 262 1.1 mrg gfc_unit *u = find_unit (unit); 263 1.1 mrg if (u == NULL) 264 1.1 mrg return -1; 265 1.1 mrg int pos = fbuf_reset (u); 266 1.1 mrg if (pos != 0) 267 1.1 mrg sseek (u->s, pos, SEEK_CUR); 268 1.1 mrg gfc_offset ret = stell (u->s); 269 1.1 mrg unlock_unit (u); 270 1.1 mrg return ret; 271 1.1 mrg } 272 1.1 mrg 273 1.1 mrg 274 1.1 mrg extern GFC_IO_INT PREFIX(ftell) (int *); 275 1.1 mrg export_proto_np(PREFIX(ftell)); 276 1.1 mrg 277 1.1 mrg GFC_IO_INT 278 1.1 mrg PREFIX(ftell) (int *unit) 279 1.1 mrg { 280 1.1 mrg return gf_ftell (*unit); 281 1.1 mrg } 282 1.1 mrg 283 1.1 mrg 284 1.1 mrg #define FTELL_SUB(kind) \ 285 1.1 mrg extern void ftell_i ## kind ## _sub (int *, GFC_INTEGER_ ## kind *); \ 286 1.1 mrg export_proto(ftell_i ## kind ## _sub); \ 287 1.1 mrg void \ 288 1.1 mrg ftell_i ## kind ## _sub (int *unit, GFC_INTEGER_ ## kind *offset) \ 289 1.1 mrg { \ 290 1.1 mrg *offset = gf_ftell (*unit); \ 291 1.1 mrg } 292 1.1 mrg 293 1.1 mrg FTELL_SUB(1) 294 1.1 mrg FTELL_SUB(2) 295 1.1 mrg FTELL_SUB(4) 296 1.1 mrg FTELL_SUB(8) 297 1.1 mrg 298 1.1 mrg 299 1.1 mrg 300 1.1 mrg /* LOGICAL FUNCTION ISATTY(UNIT) 301 1.1 mrg INTEGER, INTENT(IN) :: UNIT */ 302 1.1 mrg 303 1.1 mrg extern GFC_LOGICAL_4 isatty_l4 (int *); 304 1.1 mrg export_proto(isatty_l4); 305 1.1 mrg 306 1.1 mrg GFC_LOGICAL_4 307 1.1 mrg isatty_l4 (int *unit) 308 1.1 mrg { 309 1.1 mrg gfc_unit *u; 310 1.1 mrg GFC_LOGICAL_4 ret = 0; 311 1.1 mrg 312 1.1 mrg u = find_unit (*unit); 313 1.1 mrg if (u != NULL) 314 1.1 mrg { 315 1.1 mrg ret = (GFC_LOGICAL_4) stream_isatty (u->s); 316 1.1 mrg unlock_unit (u); 317 1.1 mrg } 318 1.1 mrg return ret; 319 1.1 mrg } 320 1.1 mrg 321 1.1 mrg 322 1.1 mrg extern GFC_LOGICAL_8 isatty_l8 (int *); 323 1.1 mrg export_proto(isatty_l8); 324 1.1 mrg 325 1.1 mrg GFC_LOGICAL_8 326 1.1 mrg isatty_l8 (int *unit) 327 1.1 mrg { 328 1.1 mrg gfc_unit *u; 329 1.1 mrg GFC_LOGICAL_8 ret = 0; 330 1.1 mrg 331 1.1 mrg u = find_unit (*unit); 332 1.1 mrg if (u != NULL) 333 1.1 mrg { 334 1.1 mrg ret = (GFC_LOGICAL_8) stream_isatty (u->s); 335 1.1 mrg unlock_unit (u); 336 1.1 mrg } 337 1.1 mrg return ret; 338 1.1 mrg } 339 1.1 mrg 340 1.1 mrg 341 1.1 mrg /* SUBROUTINE TTYNAM(UNIT,NAME) 342 1.1 mrg INTEGER,SCALAR,INTENT(IN) :: UNIT 343 1.1 mrg CHARACTER,SCALAR,INTENT(OUT) :: NAME */ 344 1.1 mrg 345 1.1 mrg extern void ttynam_sub (int *, char *, gfc_charlen_type); 346 1.1 mrg export_proto(ttynam_sub); 347 1.1 mrg 348 1.1 mrg void 349 1.1 mrg ttynam_sub (int *unit, char *name, gfc_charlen_type name_len) 350 1.1 mrg { 351 1.1 mrg gfc_unit *u; 352 1.1 mrg int nlen; 353 1.1 mrg int err = 1; 354 1.1 mrg 355 1.1 mrg u = find_unit (*unit); 356 1.1 mrg if (u != NULL) 357 1.1 mrg { 358 1.1 mrg err = stream_ttyname (u->s, name, name_len); 359 1.1 mrg if (err == 0) 360 1.1 mrg { 361 1.1 mrg nlen = strlen (name); 362 1.1 mrg memset (&name[nlen], ' ', name_len - nlen); 363 1.1 mrg } 364 1.1 mrg 365 1.1 mrg unlock_unit (u); 366 1.1 mrg } 367 1.1 mrg if (err != 0) 368 1.1 mrg memset (name, ' ', name_len); 369 1.1 mrg } 370 1.1 mrg 371 1.1 mrg 372 1.1 mrg extern void ttynam (char **, gfc_charlen_type *, int); 373 1.1 mrg export_proto(ttynam); 374 1.1 mrg 375 1.1 mrg void 376 1.1 mrg ttynam (char **name, gfc_charlen_type *name_len, int unit) 377 1.1 mrg { 378 1.1 mrg gfc_unit *u; 379 1.1 mrg 380 1.1 mrg u = find_unit (unit); 381 1.1 mrg if (u != NULL) 382 1.1 mrg { 383 1.1 mrg *name = xmalloc (TTY_NAME_MAX); 384 1.1 mrg int err = stream_ttyname (u->s, *name, TTY_NAME_MAX); 385 1.1 mrg if (err == 0) 386 1.1 mrg { 387 1.1 mrg *name_len = strlen (*name); 388 1.1 mrg unlock_unit (u); 389 1.1 mrg return; 390 1.1 mrg } 391 1.1 mrg free (*name); 392 1.1 mrg unlock_unit (u); 393 1.1 mrg } 394 1.1 mrg 395 1.1 mrg *name_len = 0; 396 1.1 mrg *name = NULL; 397 1.1 mrg } 398