Exemple #1
0
void ns_unix_error(int errcode, char *cmdname, value cmdarg)
{
  CAMLparam0();
  CAMLlocal4(res,name,err,arg);

  name = err = arg = Val_unit;

  Begin_roots3 (name, err, arg);
    arg = cmdarg == Nothing ? copy_string("") : cmdarg;
    name = copy_string(cmdname);
    err =
      cst_to_constr(errcode, ns_error_table, sizeof(ns_error_table)/sizeof(int));
    if (unix_error_exn == NULL) {
      unix_error_exn = caml_named_value("Ocamllib.Unix_error");
      if (unix_error_exn == NULL)
        invalid_argument("Exception Ocamllib.Unix_error not initialized, please link Ocamllib.cma");
    }
    res = alloc_small(4, 0);
    Field(res, 0) = *unix_error_exn;
    Field(res, 1) = err;
    Field(res, 2) = name;
    Field(res, 3) = arg;
  End_roots();
  mlraise(res);
  CAMLreturn0;
}
Exemple #2
0
value makeblock3(value tag, value accu,value arg1, value arg2)
{
  value res;

  Begin_roots3(accu,arg1,arg2);
  res = alloc(3, Int_val(tag));
  End_roots();
  initialize(&Field(res,0), accu);
  initialize(&Field(res,1), arg1);
  initialize(&Field(res,2), arg2);

  return res;
}
Exemple #3
0
static value alloc_group_entry(struct group *entry)
{
  value res;
  value name = Val_unit, pass = Val_unit, mem = Val_unit;

  Begin_roots3 (name, pass, mem);
    name = caml_copy_string(entry->gr_name);
    pass = caml_copy_string(entry->gr_passwd);
    mem = caml_copy_string_array((const char**)entry->gr_mem);
    res = caml_alloc_4(0, name, pass,
                       Val_int(entry->gr_gid), mem);
  End_roots();
  return res;
}
Exemple #4
0
/* Raises exceptions which take two arguments */
static void raise_with_two_args(value tag, value arg1, value arg2)
{
  value v_exc;

  /* Protects tag, arg1 and arg2 from being reclaimed by the garbage
     collector when the exception value is allocated */
  Begin_roots3(tag, arg1, arg2);
    v_exc = caml_alloc_small(3, 0);
    Field(v_exc, 0) = tag;
    Field(v_exc, 1) = arg1;
    Field(v_exc, 2) = arg2;
  End_roots();

  caml_raise(v_exc);
}
Exemple #5
0
static value alloc_group_entry(struct group *entry)
{
  value res;
  value name = Val_unit, pass = Val_unit, mem = Val_unit;

  Begin_roots3 (name, pass, mem);
    name = copy_string(entry->gr_name);
    pass = copy_string(entry->gr_passwd);
    mem = copy_string_array((const char**)entry->gr_mem);
    res = alloc_small(4, 0);
    Init_field(res, 0, name);
    Init_field(res, 1, pass);
    Init_field(res, 2, Val_int(entry->gr_gid));
    Init_field(res, 3, mem);
  End_roots();
  return res;
}
static value alloc_service_entry(struct servent *entry)
{
  value res;
  value name = Val_unit, aliases = Val_unit, proto = Val_unit;

  Begin_roots3 (name, aliases, proto);
    name = copy_string(entry->s_name);
    aliases = copy_string_array((const char**)entry->s_aliases);
    proto = copy_string(entry->s_proto);
    res = alloc_small(4, 0);
    Field(res,0) = name;
    Field(res,1) = aliases;
    Field(res,2) = Val_int(ntohs(entry->s_port));
    Field(res,3) = proto;
  End_roots();
  return res;
}
Exemple #7
0
static void camlzip_bzerror(char * fn, int err)
{
  char * msg;
  value s1 = Val_unit, s2 = Val_unit, bucket = Val_unit;

  if (camlzip_bzerror_exn == NULL) {
    camlzip_bzerror_exn = caml_named_value("Bzlib.Error");
    if (camlzip_bzerror_exn == NULL)
      invalid_argument("Exception Bzlib.Error not initialized");
  }
  Begin_roots3(s1, s2, bucket);
    s1 = copy_string(fn);
    switch (err) {
    case BZ_CONFIG_ERROR:
      s2 = Val_int(0);
      break;
    case BZ_SEQUENCE_ERROR:
      s2 = Val_int(1);
      break;
    case BZ_PARAM_ERROR:
      s2 = Val_int(2);
      break;
    case BZ_MEM_ERROR:
      s2 = Val_int(3);
      break;
    case BZ_DATA_ERROR:
      s2 = Val_int(4);
      break;
    case BZ_DATA_ERROR_MAGIC:
      s2 = Val_int(5);
      break;
    default:
      s2 = Val_int(6);
    }
    bucket = alloc_small(3, 0);
    Field(bucket, 0) = *camlzip_bzerror_exn;
    Field(bucket, 1) = s1;
    Field(bucket, 2) = s2;
  End_roots();
  mlraise(bucket);
}
Exemple #8
0
CAMLprim value unix_select_r(CAML_R, value readfds, value writefds, value exceptfds,
                             value timeout)
{
  fd_set read, write, except;
  int maxfd;
  double tm;
  struct timeval tv;
  struct timeval * tvp;
  int retcode;
  value res;

  Begin_roots3 (readfds, writefds, exceptfds);
    maxfd = -1;
    retcode  = fdlist_to_fdset(readfds, &read, &maxfd);
    retcode += fdlist_to_fdset(writefds, &write, &maxfd);
    retcode += fdlist_to_fdset(exceptfds, &except, &maxfd);
    /* PR#5563: if a bad fd was encountered, report EINVAL error */
    if (retcode != 0) unix_error_r(ctx, EINVAL, "select", Nothing);
    tm = Double_val(timeout);
    if (tm < 0.0)
      tvp = (struct timeval *) NULL;
    else {
      tv.tv_sec = (int) tm;
      tv.tv_usec = (int) (1e6 * (tm - tv.tv_sec));
      tvp = &tv;
    }
    caml_enter_blocking_section_r(ctx);
    retcode = select(maxfd + 1, &read, &write, &except, tvp);
    caml_leave_blocking_section_r(ctx);
    if (retcode == -1) uerror_r(ctx,"select", Nothing);
    readfds = fdset_to_fdlist_r(ctx, readfds, &read);
    writefds = fdset_to_fdlist_r(ctx, writefds, &write);
    exceptfds = fdset_to_fdlist_r(ctx, exceptfds, &except);
    res = caml_alloc_small_r(ctx, 3, 0);
    Field(res, 0) = readfds;
    Field(res, 1) = writefds;
    Field(res, 2) = exceptfds;
  End_roots();
  return res;
}
Exemple #9
0
static void store_in_job(value job_v)
{
  value adr = Val_unit;
  value addr_list = Val_unit;
  int i;

/*  printf("store_in_job %d\n", job_naddresses); */
  Begin_roots3 (job_v, addr_list, adr);
#ifdef h_addr
  addr_list = alloc_small(job_naddresses, 0);
  for(i=0; i<job_naddresses; i++){
    adr = alloc_one_addr(ip_job_result + i * entry_h_length);
    modify(&Field(addr_list,i), adr);
  }
#else
  adr = alloc_one_addr(ip_job_result);
  addr_list = alloc_small(1, 0);
  Field(addr_list, 0) = adr;
#endif  /* h_addr */
  modify(&Field(job_v,1), addr_list);
  End_roots();
}
Exemple #10
0
static void camlzip_error(char * fn, value vzs)
{
  char * msg;
  value s1 = Val_unit, s2 = Val_unit, bucket = Val_unit;

  msg = ZStream_val(vzs)->msg;
  if (msg == NULL) msg = "";
  if (camlzip_error_exn == NULL) {
    camlzip_error_exn = caml_named_value("Zlib.Error");
    if (camlzip_error_exn == NULL)
      caml_invalid_argument("Exception Zlib.Error not initialized");
  }
  Begin_roots3(s1, s2, bucket);
    s1 = caml_copy_string(fn);
    s2 = caml_copy_string(msg);
    bucket = caml_alloc_small(3, 0);
    Field(bucket, 0) = *camlzip_error_exn;
    Field(bucket, 1) = s1;
    Field(bucket, 2) = s2;
  End_roots();
  caml_raise(bucket);
}
Exemple #11
0
CAMLprim value unix_select(value readfds, value writefds, value exceptfds, 
                           value timeout)
{
  fd_set read, write, except;
  int maxfd;
  double tm;
  struct timeval tv;
  struct timeval * tvp;
  int retcode;
  value res;

  Begin_roots3 (readfds, writefds, exceptfds);
    maxfd = -1;
    fdlist_to_fdset(readfds, &read, &maxfd);
    fdlist_to_fdset(writefds, &write, &maxfd);
    fdlist_to_fdset(exceptfds, &except, &maxfd);
    tm = Double_val(timeout);
    if (tm < 0.0)
      tvp = (struct timeval *) NULL;
    else {
      tv.tv_sec = (int) tm;
      tv.tv_usec = (int) (1e6 * (tm - tv.tv_sec));
      tvp = &tv;
    }
    enter_blocking_section();
    retcode = select(maxfd + 1, &read, &write, &except, tvp);
    leave_blocking_section();
    if (retcode == -1) uerror("select", Nothing);
    readfds = fdset_to_fdlist(readfds, &read);
    writefds = fdset_to_fdlist(writefds, &write);
    exceptfds = fdset_to_fdlist(exceptfds, &except);
    res = alloc_small(3, 0);
    Field(res, 0) = readfds;
    Field(res, 1) = writefds;
    Field(res, 2) = exceptfds;
  End_roots();
  return res;
}
Exemple #12
0
void unix_error(int errcode, char *cmdname, value cmdarg)
{
  value res;
  value name = Val_unit, err = Val_unit, arg = Val_unit;
  int errconstr;

  Begin_roots3 (name, err, arg);
    arg = cmdarg == Nothing ? copy_string("") : cmdarg;
    name = copy_string(cmdname);
    err = unix_error_of_code (errcode);
    if (unix_error_exn == NULL) {
      unix_error_exn = caml_named_value("Unix.Unix_error");
      if (unix_error_exn == NULL)
        invalid_argument("Exception Unix.Unix_error not initialized, please link unix.cma");
    }
    res = alloc_small(4, 0);
    Field(res, 0) = *unix_error_exn;
    Field(res, 1) = err;
    Field(res, 2) = name;
    Field(res, 3) = arg;
  End_roots();
  mlraise(res);
}
Exemple #13
0
/* Executes a pattern match with runtime options, a regular expression, a
   string offset, a string length, a subject string, a number of subgroup
   offsets, an offset vector and an optional callout function */
CAMLprim value pcre_exec_stub(value v_opt, value v_rex, value v_ofs,
                              value v_subj, value v_subgroups2, value v_ovec,
                              value v_maybe_cof)
{
  const int ofs = Int_val(v_ofs), len = caml_string_length(v_subj);

  if (ofs > len || ofs < 0)
    caml_invalid_argument("Pcre.pcre_exec_stub: illegal offset");

  {
    const pcre *code = (pcre *) Field(v_rex, 1);  /* Compiled pattern */
    const pcre_extra *extra = (pcre_extra *) Field(v_rex, 2);  /* Extra info */
    const char *ocaml_subj = String_val(v_subj);  /* Subject string */
    const int opt = Int_val(v_opt);  /* Runtime options */
    int subgroups2 = Int_val(v_subgroups2);
    const int subgroups2_1 = subgroups2 - 1;
    const int subgroups3 = (subgroups2 >> 1) + subgroups2;

    /* Special case when no callout functions specified */
    if (v_maybe_cof == None) {
      int *ovec = (int *) &Field(v_ovec, 0);

      /* Performs the match */
      const int ret =
        pcre_exec(code, extra, ocaml_subj, len, ofs, opt, ovec, subgroups3);

      if (ret < 0) {
        switch(ret) {
          case PCRE_ERROR_NOMATCH : caml_raise_constant(*pcre_exc_Not_found);
          case PCRE_ERROR_PARTIAL : caml_raise_constant(*pcre_exc_Partial);
          case PCRE_ERROR_MATCHLIMIT :
            caml_raise_constant(*pcre_exc_MatchLimit);
          case PCRE_ERROR_BADPARTIAL :
            caml_raise_constant(*pcre_exc_BadPartial);
          case PCRE_ERROR_BADUTF8 : caml_raise_constant(*pcre_exc_BadUTF8);
          case PCRE_ERROR_BADUTF8_OFFSET :
            caml_raise_constant(*pcre_exc_BadUTF8Offset);
          default :
            caml_raise_with_string(*pcre_exc_InternalError, "pcre_exec_stub");
        }
      }

      else {
        const int *ovec_src = ovec + subgroups2_1;
        long int *ovec_dst = (long int *) ovec + subgroups2_1;

        /* Converts offsets from C-integers to OCaml-Integers
           This is a bit tricky, because there are 32- and 64-bit platforms
           around and OCaml chooses the larger possibility for representing
           integers when available (also in arrays) - not so the PCRE */
        while (subgroups2--) {
          *ovec_dst = Val_int(*ovec_src);
          --ovec_src; --ovec_dst;
        }
      }
    }

    /* There are callout functions */
    else {
      value v_cof = Field(v_maybe_cof, 0);
      value v_substrings;
      char *subj = caml_stat_alloc(sizeof(char) * len);
      int *ovec = caml_stat_alloc(sizeof(int) * subgroups3);
      int ret;
      struct cod cod = { (value *) NULL, (value *) NULL, (value) NULL };
      struct pcre_extra new_extra =
#ifdef PCRE_CONFIG_MATCH_LIMIT_RECURSION
        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL, 0 };
#else
        { PCRE_EXTRA_CALLOUT_DATA, NULL, 0, NULL, NULL };
#endif

      memcpy(subj, ocaml_subj, len);

      Begin_roots3(v_rex, v_cof, v_substrings);
        Begin_roots2(v_subj, v_ovec);
          v_substrings = caml_alloc_small(2, 0);
        End_roots();

        Field(v_substrings, 0) = v_subj;
        Field(v_substrings, 1) = v_ovec;

        cod.v_substrings_p = &v_substrings;
        cod.v_cof_p = &v_cof;
        new_extra.callout_data = &cod;

        if (extra == NULL) {
          ret = pcre_exec(code, &new_extra, subj, len, ofs, opt, ovec,
                          subgroups3);
        }
        else {
          new_extra.flags = PCRE_EXTRA_CALLOUT_DATA | extra->flags;
          new_extra.study_data = extra->study_data;
          new_extra.match_limit = extra->match_limit;
          new_extra.tables = extra->tables;
#ifdef PCRE_CONFIG_MATCH_LIMIT_RECURSION
          new_extra.match_limit_recursion = extra->match_limit_recursion;
#endif

          ret = pcre_exec(code, &new_extra, subj, len, ofs, opt, ovec,
                          subgroups3);
        }

        free(subj);
      End_roots();

      if (ret < 0) {
        free(ovec);
        switch(ret) {
          case PCRE_ERROR_NOMATCH : caml_raise_constant(*pcre_exc_Not_found);
          case PCRE_ERROR_PARTIAL : caml_raise_constant(*pcre_exc_Partial);
          case PCRE_ERROR_MATCHLIMIT :
            caml_raise_constant(*pcre_exc_MatchLimit);
          case PCRE_ERROR_BADPARTIAL :
            caml_raise_constant(*pcre_exc_BadPartial);
          case PCRE_ERROR_BADUTF8 : caml_raise_constant(*pcre_exc_BadUTF8);
          case PCRE_ERROR_BADUTF8_OFFSET :
            caml_raise_constant(*pcre_exc_BadUTF8Offset);
          case PCRE_ERROR_CALLOUT : caml_raise(cod.v_exn);
          default :
            caml_raise_with_string(*pcre_exc_InternalError, "pcre_exec_stub");
        }
      }

      else {
        int *ovec_src = ovec + subgroups2_1;
        long int *ovec_dst = &Field(v_ovec, 0) + subgroups2_1;

        while (subgroups2--) {
          *ovec_dst = Val_int(*ovec_src);
          --ovec_src; --ovec_dst;
        }

        free(ovec);
      }
    }
  }

  return Val_unit;
}

/* Byte-code hook for pcre_exec_stub
   Needed, because there are more than 5 arguments */
CAMLprim value pcre_exec_stub_bc(value *argv, int __unused argn)
{
  return pcre_exec_stub(argv[0], argv[1], argv[2], argv[3],
                        argv[4], argv[5], argv[6]);
}

/* Generates a new set of chartables for the current locale (see man
   page of PCRE */
CAMLprim value pcre_maketables_stub(value __unused v_unit)
{
  /* GC will do a full cycle every 100 table set allocations
     (one table set consumes 864 bytes -> maximum of 86400 bytes
     unreclaimed table sets) */
  const value v_res = caml_alloc_final(2, pcre_dealloc_tables, 864, 86400);
  Field(v_res, 1) = (value) pcre_maketables();
  return v_res;
}

/* Wraps around the isspace-function */
CAMLprim value pcre_isspace_stub(value v_c)
{
  return Val_bool(isspace(Int_val(v_c)));
}

/* Returns number of substring associated with a name */
CAMLprim value pcre_get_stringnumber_stub(value v_rex, value v_name)
{
  const int ret = pcre_get_stringnumber((pcre *) Field(v_rex, 1),
                                        String_val(v_name));
  if (ret == PCRE_ERROR_NOSUBSTRING)
    caml_invalid_argument("Named string not found");

  return Val_int(ret);
}

/* Returns array of names of named substrings in a regexp */
CAMLprim value pcre_names_stub(value v_rex)
{
  CAMLparam0();
  CAMLlocal1(v_res);
  int name_count;
  int entry_size;
  const char *tbl_ptr;
  int i;

  int ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMECOUNT, &name_count);
  if (ret != 0)
    caml_raise_with_string(*pcre_exc_InternalError, "pcre_names_stub");

  ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMEENTRYSIZE, &entry_size);
  if (ret != 0)
    caml_raise_with_string(*pcre_exc_InternalError, "pcre_names_stub");

  ret = pcre_fullinfo_stub(v_rex, PCRE_INFO_NAMETABLE, &tbl_ptr);
  if (ret != 0)
    caml_raise_with_string(*pcre_exc_InternalError, "pcre_names_stub");

  v_res = caml_alloc(name_count, 0);

  for (i = 0; i < name_count; ++i) {
    value v_name = caml_copy_string(tbl_ptr + 2);
    Store_field(v_res, i, v_name);
    tbl_ptr += entry_size;
  }

  CAMLreturn(v_res);
}
Exemple #14
0
static void
uwt_udp_recv_own_cb(uv_udp_t* handle,
                    ssize_t nread,
                    const uv_buf_t* buf,
                    const struct sockaddr* addr,
                    unsigned int flags)
{
  HANDLE_CB_INIT_WITH_CLEAN(uh, handle);
  value exn = Val_unit;
#ifndef UWT_NO_COPY_READ
  bool buf_not_cleaned = true;
  const int read_ba = uh->use_read_ba;
#else
  (void) buf;
#endif
  if ( uh->close_called == 0 && (nread != 0 || addr != NULL) ){
    /* nread == 0 && addr == NULL only means we need to clear
       the buffer */
    assert ( uh->cb_read != CB_INVALID );
    value param;
    if ( nread < 0 ){
      param = caml_alloc_small(1,Error_tag);
      Field(param,0) = Val_uwt_error(nread);
    }
    else {
      value triple = Val_unit;
      value sockaddr = Val_unit;
      param = Val_unit;
      Begin_roots3(triple,sockaddr,param);
      value is_partial;
      if ( addr != NULL ){
        param = uwt__alloc_sockaddr(addr);
        if ( param != Val_unit ){
          sockaddr = caml_alloc_small(1,Some_tag);
          Field(sockaddr,0) = param;
        }
      }
      if ( flags & UV_UDP_PARTIAL ){
        is_partial = Val_long(1);
      }
      else {
        is_partial = Val_long(0);
      }
#ifndef UWT_NO_COPY_READ
      if ( nread != 0 && read_ba == 0 ){
        value o = Field(GET_CB_VAL(uh->cb_read),0);
        memcpy(String_val(o) + uh->x.obuf_offset, buf->base, nread);
      }
#endif
      triple = caml_alloc_small(3,0);
      Field(triple,0) = Val_long(nread);
      Field(triple,1) = is_partial;
      Field(triple,2) = sockaddr;
      param = caml_alloc_small(1,Ok_tag);
      Field(param,0) = triple;
      End_roots();
    }
#ifndef UWT_NO_COPY_READ
    if ( buf->base && read_ba == 0 ){
      buf_not_cleaned = false;
      uwt__free_uv_buf_t_const(buf);
    }
#endif
    uh->can_reuse_cb_read = 1;
    uh->read_waiting = 0;
    uh->in_use_cnt--;
    exn = Field(GET_CB_VAL(uh->cb_read),1);
    uwt__gr_unregister(&uh->cb_read);
    exn = caml_callback2_exn(*uwt__global_wakeup,exn,param);
    if ( uh->close_called == 0 && uh->can_reuse_cb_read == 1 ){
      uv_udp_recv_stop(handle);
      uh->can_reuse_cb_read = 0;
    }
  }
#ifndef UWT_NO_COPY_READ
  if ( read_ba == 0 && buf_not_cleaned && buf->base ){
    uwt__free_uv_buf_t_const(buf);
  }
#endif
  HANDLE_CB_RET(exn);
}