static int stdin_open(gx_io_device * iodev, const char *access, stream ** ps, gs_memory_t * mem) { i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */ stream *s; if (!streq1(access, 'r')) return_error(e_invalidfileaccess); if (file_is_invalid(s, &ref_stdin)) { /****** stdin SHOULD NOT LINE-BUFFER ******/ gs_memory_t *mem = imemory_system; byte *buf; s = file_alloc_stream(mem, "stdin_open(stream)"); /* We want stdin to read only one character at a time, */ /* but it must have a substantial buffer, in case it is used */ /* by a stream that requires more than one input byte */ /* to make progress. */ buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE, "stdin_open(buffer)"); if (s == 0 || buf == 0) return_error(e_VMerror); sread_file(s, gs_stdin, buf, STDIN_BUF_SIZE); s->procs.process = s_stdin_read_process; s->save_close = s_std_null; s->procs.close = file_close_file; make_file(&ref_stdin, a_readonly | avm_system, s->read_id, s); *ps = s; return 1; } *ps = s; return 0; }
/* * Set up a file stream on an OS file. The caller has allocated the * stream and buffer. */ void file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer, uint buffer_size) { switch (fmode[0]) { case 'a': sappend_file(s, file, buffer, buffer_size); break; case 'r': /* Defeat buffering for terminals. */ { struct stat rstat; fstat(fileno(file), &rstat); sread_file(s, file, buffer, (S_ISCHR(rstat.st_mode) ? 1 : buffer_size)); } break; case 'w': swrite_file(s, file, buffer, buffer_size); } if (fmode[1] == '+') s->file_modes |= s_mode_read | s_mode_write; s->save_close = s->procs.close; s->procs.close = file_close_file; }
/* Switch a file stream to reading or writing. */ static int s_fileno_switch(stream * s, bool writing) { uint modes = s->file_modes; int fd = sfileno(s); long pos; if (writing) { if (!(s->file_modes & s_mode_write)) return ERRC; pos = stell(s); if_debug2('s', "[s]switch 0x%lx to write at %ld\n", (ulong) s, pos); lseek(fd, pos, SEEK_SET); /* pacify OS */ if (modes & s_mode_append) { sappend_file(s, s->file, s->cbuf, s->cbsize); /* sets position */ } else { swrite_file(s, s->file, s->cbuf, s->cbsize); s->position = pos; } s->modes = modes; } else { if (!(s->file_modes & s_mode_read)) return ERRC; pos = stell(s); if_debug2('s', "[s]switch 0x%lx to read at %ld\n", (ulong) s, pos); if (sflush(s) < 0) return ERRC; lseek(fd, 0L, SEEK_CUR); /* pacify OS */ sread_file(s, s->file, s->cbuf, s->cbsize); s->modes |= modes & s_mode_append; /* don't lose append info */ s->position = pos; } s->file_modes = modes; return 0; }