e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
1b10db2002-10-08Martin Nilsson 
6219e12002-05-29Per Hedbor #include "global.h" #include "bignum.h" #include "object.h" #include "interpret.h"
74bd242002-07-03Per Hedbor #include "threads.h"
6219e12002-05-29Per Hedbor  #include "fdlib.h" #include "fd_control.h" #include <sys/stat.h> #include "shuffler.h" #define CHUNK 8192 /* Source: Normal file * Argument: Stdio.File instance pointing to a normal file */ struct fd_source { struct source s; struct object *obj; char buffer[CHUNK]; int fd;
ed547c2004-08-27Marcus Agehall  off_t len;
6219e12002-05-29Per Hedbor };
d3aa5b2010-08-14Jonas Wallden static struct data get_data( struct source *src, off_t len )
6219e12002-05-29Per Hedbor {
feb6822009-08-13Henrik Grubbström (Grubba)  struct fd_source *s = (struct fd_source *)src;
6219e12002-05-29Per Hedbor  struct data res; int rr; len = CHUNK; /* It's safe to ignore the 'len' argument */ res.do_free = 0; res.off = 0; res.data = s->buffer;
ed547c2004-08-27Marcus Agehall  if( len > s->len )
6219e12002-05-29Per Hedbor  {
ed547c2004-08-27Marcus Agehall  len = s->len;
6219e12002-05-29Per Hedbor  s->s.eof = 1; }
74bd242002-07-03Per Hedbor  THREADS_ALLOW();
6219e12002-05-29Per Hedbor  rr = fd_read( s->fd, res.data, len );
74bd242002-07-03Per Hedbor  THREADS_DISALLOW(); /* printf("B[normal file]: get_data( %d / %d ) --> %d\n", len, */ /* s->len, rr); */
6219e12002-05-29Per Hedbor  res.len = rr;
74bd242002-07-03Per Hedbor 
2d76f22005-05-20Martin Stjernholm  if( rr<0 || rr < len )
6219e12002-05-29Per Hedbor  s->s.eof = 1; return res; }
feb6822009-08-13Henrik Grubbström (Grubba) static void free_source( struct source *src )
6219e12002-05-29Per Hedbor {
feb6822009-08-13Henrik Grubbström (Grubba)  free_object(((struct fd_source *)src)->obj);
6219e12002-05-29Per Hedbor }
f0aa6f2013-06-09Martin Nilsson static int is_stdio_file(struct object *o) { struct program *p = o->prog; INT32 i = p->num_inherits; while( i-- ) { if( p->inherits[i].prog->id == PROG_STDIO_FD_ID || p->inherits[i].prog->id == PROG_STDIO_FD_REF_ID ) return 1; } return 0; }
6219e12002-05-29Per Hedbor struct source *source_normal_file_make( struct svalue *s, INT64 start, INT64 len ) { struct fd_source *res;
40962a2003-03-27Martin Stjernholm  PIKE_STAT_T st;
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(*s) != PIKE_T_OBJECT)
76f5062002-05-30Henrik Grubbström (Grubba)  return 0;
f0aa6f2013-06-09Martin Nilsson  if(!is_stdio_file(s->u.object))
6219e12002-05-29Per Hedbor  return 0;
7a3c512004-04-04Martin Nilsson  if (find_identifier("query_fd", s->u.object->prog) < 0) return 0;
9c14f32014-04-27Martin Nilsson  res = calloc( 1, sizeof( struct fd_source ) ); if( !res ) return NULL;
6219e12002-05-29Per Hedbor  apply( s->u.object, "query_fd", 0 ); res->fd = Pike_sp[-1].u.integer; pop_stack();
74bd242002-07-03Per Hedbor  res->s.get_data = get_data; res->s.free_source = free_source; res->obj = s->u.object;
50ea682003-03-14Henrik Grubbström (Grubba)  add_ref(res->obj);
6219e12002-05-29Per Hedbor  if( fd_fstat( res->fd, &st ) < 0 )
74bd242002-07-03Per Hedbor  {
6219e12002-05-29Per Hedbor  goto fail;
74bd242002-07-03Per Hedbor  }
6219e12002-05-29Per Hedbor  if( !S_ISREG(st.st_mode) )
74bd242002-07-03Per Hedbor  {
6219e12002-05-29Per Hedbor  goto fail;
13670c2015-05-25Martin Nilsson  }
74bd242002-07-03Per Hedbor  if( len > 0 )
6219e12002-05-29Per Hedbor  { if( len > st.st_size-start )
74bd242002-07-03Per Hedbor  {
6219e12002-05-29Per Hedbor  goto fail;
74bd242002-07-03Per Hedbor  }
6219e12002-05-29Per Hedbor  else res->len = len; } else res->len = st.st_size-start; if( fd_lseek( res->fd, (off_t)start, SEEK_SET ) < 0 )
74bd242002-07-03Per Hedbor  {
6219e12002-05-29Per Hedbor  goto fail;
74bd242002-07-03Per Hedbor  }
6219e12002-05-29Per Hedbor  return (struct source *)res; fail:
74bd242002-07-03Per Hedbor  free_source((void *)res);
6219e12002-05-29Per Hedbor  free(res); return 0; } void source_normal_file_exit( ) { } void source_normal_file_init( ) { }