コード例 #1
0
ファイル: sys_descrip.c プロジェクト: ryo/netbsd-src
/*
 * Duplicate a file descriptor.
 */
int
sys_dup(struct lwp *l, const struct sys_dup_args *uap, register_t *retval)
{
	/* {
		syscallarg(int)	fd;
	} */
	int error, newfd, oldfd;
	file_t *fp;

	oldfd = SCARG(uap, fd);

	if ((fp = fd_getfile(oldfd)) == NULL) {
		return EBADF;
	}
	error = fd_dup(fp, 0, &newfd, false);
	fd_putfile(oldfd);
	*retval = newfd;
	return error;
}
コード例 #2
0
ファイル: sys_descrip.c プロジェクト: ryo/netbsd-src
/*
 * The file control system call.
 */
int
sys_fcntl(struct lwp *l, const struct sys_fcntl_args *uap, register_t *retval)
{
	/* {
		syscallarg(int)		fd;
		syscallarg(int)		cmd;
		syscallarg(void *)	arg;
	} */
	int fd, i, tmp, error, cmd, newmin;
	filedesc_t *fdp;
	file_t *fp;
	struct flock fl;
	bool cloexec = false;

	fd = SCARG(uap, fd);
	cmd = SCARG(uap, cmd);
	fdp = l->l_fd;
	error = 0;

	switch (cmd) {
	case F_CLOSEM:
		if (fd < 0)
			return EBADF;
		while ((i = fdp->fd_lastfile) >= fd) {
			if (fd_getfile(i) == NULL) {
				/* Another thread has updated. */
				continue;
			}
			fd_close(i);
		}
		return 0;

	case F_MAXFD:
		*retval = fdp->fd_lastfile;
		return 0;

	case F_SETLKW:
	case F_SETLK:
	case F_GETLK:
		error = copyin(SCARG(uap, arg), &fl, sizeof(fl));
		if (error)
			return error;
		error = do_fcntl_lock(fd, cmd, &fl);
		if (cmd == F_GETLK && error == 0)
			error = copyout(&fl, SCARG(uap, arg), sizeof(fl));
		return error;

	default:
		/* Handled below */
		break;
	}

	if ((fp = fd_getfile(fd)) == NULL)
		return (EBADF);

	if ((cmd & F_FSCTL)) {
		error = fcntl_forfs(fd, fp, cmd, SCARG(uap, arg));
		fd_putfile(fd);
		return error;
	}

	switch (cmd) {
	case F_DUPFD_CLOEXEC:
		cloexec = true;
		/*FALLTHROUGH*/
	case F_DUPFD:
		newmin = (long)SCARG(uap, arg);
		if ((u_int)newmin >=
		    l->l_proc->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
		    (u_int)newmin >= maxfiles) {
			fd_putfile(fd);
			return EINVAL;
		}
		error = fd_dup(fp, newmin, &i, cloexec);
		*retval = i;
		break;

	case F_GETFD:
		*retval = fdp->fd_dt->dt_ff[fd]->ff_exclose;
		break;

	case F_SETFD:
		fd_set_exclose(l, fd,
		    ((long)SCARG(uap, arg) & FD_CLOEXEC) != 0);
		break;

	case F_GETNOSIGPIPE:
		*retval = (fp->f_flag & FNOSIGPIPE) != 0;
		break;

	case F_SETNOSIGPIPE:
		if (SCARG(uap, arg))
			atomic_or_uint(&fp->f_flag, FNOSIGPIPE);
		else
			atomic_and_uint(&fp->f_flag, ~FNOSIGPIPE);
		*retval = 0;
		break;

	case F_GETFL:
		*retval = OFLAGS(fp->f_flag);
		break;

	case F_SETFL:
		/* XXX not guaranteed to be atomic. */
		tmp = FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;
		error = (*fp->f_ops->fo_fcntl)(fp, F_SETFL, &tmp);
		if (error)
			break;
		i = tmp ^ fp->f_flag;
		if (i & FNONBLOCK) {
			int flgs = tmp & FNONBLOCK;
			error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, &flgs);
			if (error) {
				(*fp->f_ops->fo_fcntl)(fp, F_SETFL,
				    &fp->f_flag);
				break;
			}
		}
		if (i & FASYNC) {
			int flgs = tmp & FASYNC;
			error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, &flgs);
			if (error) {
				if (i & FNONBLOCK) {
					tmp = fp->f_flag & FNONBLOCK;
					(void)(*fp->f_ops->fo_ioctl)(fp,
						FIONBIO, &tmp);
				}
				(*fp->f_ops->fo_fcntl)(fp, F_SETFL,
				    &fp->f_flag);
				break;
			}
		}
		fp->f_flag = (fp->f_flag & ~FCNTLFLAGS) | tmp;
		break;

	case F_GETOWN:
		error = (*fp->f_ops->fo_ioctl)(fp, FIOGETOWN, &tmp);
		*retval = tmp;
		break;

	case F_SETOWN:
		tmp = (int)(uintptr_t) SCARG(uap, arg);
		error = (*fp->f_ops->fo_ioctl)(fp, FIOSETOWN, &tmp);
		break;

	default:
		error = EINVAL;
	}

	fd_putfile(fd);
	return (error);
}
コード例 #3
0
ファイル: pipe.c プロジェクト: ajinkya007/pike-1
/*! @decl void output(object obj, int|void start_pos)
 *!
 *!   Add an output file object.
 */
static void pipe_output(INT32 args)
{
  struct object *obj;
  struct output *o;
  int fd;
  struct stat s;
  struct buffer *b;

  if (args<1 || 
      sp[-args].type != T_OBJECT ||
      !sp[-args].u.object ||
      !sp[-args].u.object->prog)
    Pike_error("Bad/missing argument 1 to pipe->output().\n");

  if (args==2 &&
      sp[1-args].type != T_INT)
    Pike_error("Bad argument 2 to pipe->output().\n");
       
  if (THIS->fd==-1)		/* no buffer */
  {
    /* test if usable as buffer */ 
    apply(sp[-args].u.object,"query_fd",0);

    if ((sp[-1].type==T_INT)
	&& (fd=sp[-1].u.integer)>=0
	&& (fstat(fd,&s)==0)
	&& S_ISREG(s.st_mode)
	&& (THIS->fd=fd_dup(fd))!=-1 )
    {
      /* keep the file pointer of the duped fd */
      THIS->pos=fd_lseek(fd, 0L, SEEK_CUR);

      THIS->living_outputs++;

      while (THIS->firstbuffer)
      {
	b=THIS->firstbuffer;
	THIS->firstbuffer=b->next;
	fd_lseek(THIS->fd, THIS->pos, SEEK_SET);
	fd_write(THIS->fd,b->s->str,b->s->len);
	sbuffers-=b->s->len;
	nbuffers--;
	free_string(b->s);
	free((char *)b);
      }
      THIS->lastbuffer=NULL;

      /* keep the file pointer of the duped fd
	 THIS->pos=0; */
      push_int(0);
      apply(sp[-args-2].u.object,"set_id", 1);
      pop_n_elems(args+2);	/* ... and from apply x 2  */
      return;
    }
    pop_stack();		/* from apply */
  } 

  THIS->living_outputs++;
  /* add_ref(THISOBJ); */	/* Weird */

  /* Allocate a new struct output */
  obj=clone_object(output_program,0);
  o=(struct output *)(obj->storage);
  o->next=THIS->firstoutput;
  THIS->firstoutput=obj;
  noutputs++;
  o->obj=NULL;

  add_ref(o->obj=sp[-args].u.object);

  o->write_offset=find_identifier("write",o->obj->prog);
  o->set_nonblocking_offset=find_identifier("set_nonblocking",o->obj->prog);
  o->set_blocking_offset=find_identifier("set_blocking",o->obj->prog);

  if (o->write_offset<0 || o->set_nonblocking_offset<0 ||
      o->set_blocking_offset<0) 
  {
    free_object(o->obj);
    Pike_error("illegal file object%s%s%s\n",
	  ((o->write_offset<0)?"; no write":""),
	  ((o->set_nonblocking_offset<0)?"; no set_nonblocking":""),
	  ((o->set_blocking_offset<0)?"; no set_blocking":""));
  }

  o->mode=O_RUN;
  /* keep the file pointer of the duped fd
     o->pos=0; */
  /* allow start position as 2nd argument for additional outputs
  o->pos=THIS->pos; */

  if(args>=2)
    o->pos=sp[1-args].u.integer;
  else
    o->pos=THIS->pos;

  push_object(obj); /* Ok, David, this is probably correct, but I dare you to explain why :) */
  apply(o->obj,"set_id",1);
  pop_stack();

  push_int(0);
  push_callback(offset_output_write_callback);
  push_callback(offset_output_close_callback);
  apply_low(o->obj,o->set_nonblocking_offset,3);
  pop_stack();
   
  pop_n_elems(args-1);
}
コード例 #4
0
ファイル: log.c プロジェクト: ajinkya007/pike-1
void f_aap_log_as_commonlog_to_file(INT32 args)
{
  struct log_entry *le;
  struct log *l = LTHIS->log;
  int n = 0;
  int mfd, ot=0;
  struct object *f;
  struct tm tm;
  FILE *foo;
  static const char *month[] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Oct", "Sep", "Nov", "Dec",
  };

  get_all_args("log_as_commonlog_to_file", args, "%o", &f);
  f->refs++;

  pop_n_elems(args);
  apply(f, "query_fd", 0);
  mfd = fd_dup(sp[-1].u.integer);
  if(mfd < 1)Pike_error("Bad fileobject to ->log_as_commonlog_to_file\n");
  pop_stack();

  foo = fdopen( mfd, "w" );
  if(!foo)
    Pike_error("Bad fileobject to ->log_as_commonlog_to_file\n");

  THREADS_ALLOW();

  mt_lock( &l->log_lock );
  le = l->log_head; 
  l->log_head = l->log_tail = 0;
  mt_unlock( &l->log_lock );

  while(le)
  {
    int i;
    struct tm *tm_p;
    struct log_entry *l = le->next;
    /* remotehost rfc931 authuser [date] "request" status bytes */
    if(le->t != ot)
    {
      time_t t = (time_t)le->t;
#ifdef HAVE_GMTIME_R
      gmtime_r( &t, &tm );
#else
#ifdef HAVE_GMTIME
      tm_p = gmtime( &t ); /* This will break if two threads run
			    gmtime() at once. */

#else
#ifdef HAVE_LOCALTIME
      tm_p = localtime( &t ); /* This will break if two threads run
			       localtime() at once. */
#endif
#endif
      if (tm_p) tm = *tm_p;
#endif
      ot = le->t;
    }

    /* date format:  [03/Feb/1998:23:08:20 +0000]  */

    /* GET [URL] HTTP/1.0 */
    for(i=13; i<le->raw.len; i++)
      if(le->raw.str[i] == '\r')
      {
	le->raw.str[i] = 0;
	break;
      }

#ifdef HAVE_INET_NTOP
    if(SOCKADDR_FAMILY(le->from) != AF_INET) {
      char buffer[64];
      fprintf(foo,
      "%s - %s [%02d/%s/%d:%02d:%02d:%02d +0000] \"%s\" %d %ld\n",
	      inet_ntop(SOCKADDR_FAMILY(le->from), SOCKADDR_IN_ADDR(le->from),
			buffer, sizeof(buffer)), /* hostname */
	      "-",                          /* remote-user */
	      tm.tm_mday, month[tm.tm_mon], tm.tm_year+1900,
	      tm.tm_hour, tm.tm_min, tm.tm_sec, /* date */
	      le->raw.str, /* request line */
	      le->reply, /* reply code */
	      DO_NOT_WARN((long)le->sent_bytes)); /* bytes transfered */
    } else
#endif /* HAVE_INET_NTOP */
    fprintf(foo,
    "%d.%d.%d.%d - %s [%02d/%s/%d:%02d:%02d:%02d +0000] \"%s\" %d %ld\n",
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 0 ],
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 1 ],
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 2 ],
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 3 ], /* hostname */
	    "-",                          /* remote-user */
	    tm.tm_mday, month[tm.tm_mon], tm.tm_year+1900,
	    tm.tm_hour, tm.tm_min, tm.tm_sec, /* date */
	    le->raw.str, /* request line */
	    le->reply, /* reply code */
	    DO_NOT_WARN((long)le->sent_bytes)); /* bytes transfered */
    free_log_entry( le );
    n++;
    le = l;
  }
  fclose(foo);
  fd_close(mfd);
  THREADS_DISALLOW();
  push_int(n);
}