Exemple #1
0
value caml_inotify_add_watch(value fd, value path, value selector_flags) {
  CAMLparam3(fd, path, selector_flags);

  int selector = caml_convert_flag_list(selector_flags, inotify_flag_table);

  int watch = inotify_add_watch(Int_val(fd), String_val(path), selector);
  if (watch == -1) uerror("inotify_add_watch", path);

  CAMLreturn(Val_int(watch));
}
Exemple #2
0
CAMLprim value caml_extunix_linkat(value v_olddirfd, value v_oldname, value v_newdirfd, value v_newname, value v_flags)
{
  CAMLparam5(v_olddirfd, v_oldname, v_newdirfd, v_newname, v_flags);
  int ret = 0;
  int flags = caml_convert_flag_list(v_flags, at_flags_table);
  flags &= AT_SYMLINK_FOLLOW;  /* only allowed flag here */
  ret = linkat(Int_val(v_olddirfd), String_val(v_oldname), Int_val(v_newdirfd), String_val(v_newname), flags);
  if (ret != 0) uerror("linkat", v_oldname);
  CAMLreturn(Val_unit);
}
Exemple #3
0
value stub_inotify_add_watch(value fd, value path, value mask)
{
	CAMLparam3(fd, path, mask);
	int cv_mask, wd;

	cv_mask = caml_convert_flag_list(mask, inotify_flag_table);
	wd = inotify_add_watch(Int_val(fd), String_val(path), cv_mask);
	if (wd < 0)
		caml_failwith("inotify_add_watch");
	CAMLreturn(Val_int(wd));
}
Exemple #4
0
CAMLprim value unix_waitpid(value flags, value pid_req)
{
  int pid, status, cv_flags;

  cv_flags = caml_convert_flag_list(flags, wait_flag_table);
  caml_enter_blocking_section();
  pid = waitpid(Int_val(pid_req), &status, cv_flags);
  caml_leave_blocking_section();
  if (pid == -1) uerror("waitpid", Nothing);
  return alloc_process_status(pid, status);
}
CAMLprim value unix_posix_openpt(value flags)
{
  CAMLparam1(flags);
  int fd, cv_flags;

  cv_flags = caml_convert_flag_list(flags, posix_openpt_flag_table);
  caml_enter_blocking_section();
  fd = posix_openpt(cv_flags);
  caml_leave_blocking_section();

  if (fd == -1) uerror("posix_openpt", Nothing);

  CAMLreturn (Val_int(fd));
}
Exemple #6
0
CAMLprim value caml_extunix_unlinkat(value v_dirfd, value v_name, value v_flags)
{
  CAMLparam3(v_dirfd, v_name, v_flags);
  char* p = caml_stat_alloc(caml_string_length(v_name) + 1);
  int ret = 0;
  int flags = caml_convert_flag_list(v_flags, at_flags_table);
  flags &= AT_REMOVEDIR;  /* only allowed flag here */

  strcpy(p, String_val(v_name));
  caml_enter_blocking_section();
  ret = unlinkat(Int_val(v_dirfd), p, flags);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret != 0) uerror("unlinkat", v_name);
  CAMLreturn(Val_unit);
}
Exemple #7
0
CAMLprim value caml_extunix_fstatat(value v_dirfd, value v_name, value v_flags)
{
  CAMLparam3(v_dirfd, v_name, v_flags);
  int ret;
  struct stat buf;
  char* p = caml_stat_alloc(caml_string_length(v_name) + 1);
  int flags = caml_convert_flag_list(v_flags, at_flags_table);
  flags &= (AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT); /* only allowed flags here */

  strcpy(p, String_val(v_name));
  caml_enter_blocking_section();
  ret = fstatat(Int_val(v_dirfd), p, &buf, flags);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (ret != 0) uerror("fstatat", v_name);
  if (buf.st_size > Max_long && (buf.st_mode & S_IFMT) == S_IFREG)
    unix_error(EOVERFLOW, "fstatat", v_name);
  CAMLreturn(stat_aux(/*0,*/ &buf));
}
Exemple #8
0
CAMLprim value caml_sys_open(value path, value vflags, value vperm)
{
  CAMLparam3(path, vflags, vperm);
  int fd, flags, perm;
  char * p;

  p = caml_stat_alloc(caml_string_length(path) + 1);
  strcpy(p, String_val(path));
  flags = caml_convert_flag_list(vflags, sys_open_flags);
  perm = Int_val(vperm);
  /* open on a named FIFO can block (PR#1533) */
  caml_enter_blocking_section();
  fd = open(p, flags, perm);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (fd == -1) caml_sys_error(path);
#if defined(F_SETFD) && defined(FD_CLOEXEC)
  fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
  CAMLreturn(Val_long(fd));
}
Exemple #9
0
CAMLprim value stub_xc_domain_save(value handle, value fd, value domid,
                                   value max_iters, value max_factors,
                                   value flags, value hvm)
{
    CAMLparam5(handle, fd, domid, max_iters, max_factors);
    CAMLxparam2(flags, hvm);
    struct save_callbacks callbacks;

    uint32_t c_flags;
    uint32_t c_domid;
    int r;
    unsigned long generation_id_addr;

    c_flags = caml_convert_flag_list(flags, suspend_flag_list);
    c_domid = _D(domid);

    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.data = (void*) c_domid;
    callbacks.suspend = dispatch_suspend;
    callbacks.switch_qemu_logdirty = switch_qemu_logdirty;

    caml_enter_blocking_section();
    generation_id_addr = xenstore_get(c_domid, GENERATION_ID_ADDRESS);
    r = xc_domain_save(_H(handle), Int_val(fd), c_domid,
                       Int_val(max_iters), Int_val(max_factors),
                       c_flags, &callbacks, Bool_val(hvm)
#ifdef XENGUEST_4_2
                       ,generation_id_addr
#endif
        );
    caml_leave_blocking_section();
    if (r)
        failwith_oss_xc(_H(handle), "xc_domain_save");

    CAMLreturn(Val_unit);
}
Exemple #10
0
CAMLprim value
caml_backpack_mq_open(value val_name, value val_flags, value val_mode, value val_attr)
{
	CAMLparam4(val_name, val_flags, val_mode, val_attr);
	CAMLlocal1(val_res);
	int flags = caml_convert_flag_list(val_flags, mqueue_flags);
	struct mq_attr attr, *pattr;
	mqd_t mq;

	if (Is_long(val_attr))
		pattr = NULL;
	else {
		attr.mq_maxmsg  = Long_val(Field(Field(val_attr, 0), 0));
		attr.mq_msgsize = Long_val(Field(Field(val_attr, 0), 1));
		pattr           = &attr;
	}

	if ((mq = mq_open(String_val(val_name), flags, Int_val(val_mode), pattr)) == -1)
		uerror("mq_open", val_name);

	val_res = Val_int(mq);

	CAMLreturn(val_res);
}
value netsys_copy_value(value flags, value orig)
{
    int code;
    int cflags;
    intnat start_offset, bytelen;
    mlsize_t wosize;
    char *dest, *dest_end, *extra_block, *extra_block_end;
    int color;
    struct named_custom_ops bigarray_ops;
    struct named_custom_ops int32_ops;
    struct named_custom_ops int64_ops;
    struct named_custom_ops nativeint_ops;
    CAMLparam2(orig,flags);
    CAMLlocal1(block);

    /* First test on trivial cases: */
    if (Is_long(orig) || Wosize_val(orig) == 0) {
	CAMLreturn(orig);
    };

    code = prep_stat_tab();
    if (code != 0) goto exit;

    code = prep_stat_queue();
    if (code != 0) goto exit;

    cflags = caml_convert_flag_list(flags, init_value_flags);

    /* fprintf (stderr, "counting\n"); */

    /* Count only! */
    code = netsys_init_value_1(stat_tab, stat_queue, NULL, NULL, orig, 
			       (cflags & 1) ? 1 : 0,  /* enable_bigarrays */
			       (cflags & 2) ? 1 : 0,  /* enable_customs */
			       1, /* enable_atoms */
			       1, /* simulate */
			       NULL, NULL, 0, &start_offset, &bytelen);
    if (code != 0) goto exit;

    /* fprintf (stderr, "done counting bytelen=%ld\n", bytelen); */

    /* set up the custom ops. We always set this, because we assume that
       the values in [orig] are not trustworthy
    */
    bigarray_ops.name = "_bigarray";
    bigarray_ops.ops = 
	Custom_ops_val(alloc_bigarray_dims(CAML_BA_UINT8 | BIGARRAY_C_LAYOUT, 
					   1, NULL, 1));
    bigarray_ops.next = &int32_ops;

    int32_ops.name = "_i";
    int32_ops.ops = Custom_ops_val(caml_copy_int32(0));
    int32_ops.next = &int64_ops;

    int64_ops.name = "_j";
    int64_ops.ops = Custom_ops_val(caml_copy_int64(0));
    int64_ops.next = &nativeint_ops;

    nativeint_ops.name = "_n";
    nativeint_ops.ops = Custom_ops_val(caml_copy_nativeint(0));
    nativeint_ops.next = NULL;

    /* alloc */

    extra_block = NULL;
    extra_block_end = NULL;

    /* shamelessly copied from intern.c */
    wosize = Wosize_bhsize(bytelen);
    /* fprintf (stderr, "wosize=%ld\n", wosize); */
    if (wosize > Max_wosize) {
	/* Round desired size up to next page */
	asize_t request = ((bytelen + Page_size - 1) >> Page_log) << Page_log;
	extra_block = caml_alloc_for_heap(request);
	if (extra_block == NULL) caml_raise_out_of_memory();
	extra_block_end = extra_block + request;
	color = caml_allocation_color(extra_block);
	dest = extra_block;
	dest_end = dest + bytelen;
	block = Val_hp(extra_block);
    } else {
value netsys_init_value(value memv, 
			value offv, 
			value orig,  
			value flags,
			value targetaddrv,
			value target_custom_ops
			)
{
    int code;
    value r;
    intnat start_offset, bytelen;
    int  cflags;
    void *targetaddr;
    char *mem_data;
    char *mem_end;
    intnat off;
    struct named_custom_ops *ops, *old_ops, *next_ops;
    
    code = prep_stat_tab();
    if (code != 0) goto exit;

    code = prep_stat_queue();
    if (code != 0) goto exit;

    off = Long_val(offv);
    if (off % sizeof(void *) != 0) { code=(-2); goto exit; }

    cflags = caml_convert_flag_list(flags, init_value_flags);
    targetaddr = (void *) (Nativeint_val(targetaddrv) + off);

    ops = NULL;
    while (Is_block(target_custom_ops)) {
	value pair;
	old_ops = ops;
	pair = Field(target_custom_ops,0);
	ops = (struct named_custom_ops*) 
	          stat_alloc(sizeof(struct named_custom_ops));
	ops->name = stat_alloc(caml_string_length(Field(pair,0))+1);
	strcmp(ops->name, String_val(Field(pair,0)));
	ops->ops = (void *) Nativeint_val(Field(pair,1));
	ops->next = old_ops;
	target_custom_ops = Field(target_custom_ops,1);
    };

    mem_data = ((char *) Bigarray_val(memv)->data) + off;
    mem_end = mem_data + Bigarray_val(memv)->dim[0];

    /* note: the color of the new values does not matter because bigarrays
       are ignored by the GC. So we pass 0 (white).
    */
    
    code = netsys_init_value_1(stat_tab, stat_queue, mem_data, mem_end, orig, 
			       (cflags & 1) ? 2 : 0, 
			       (cflags & 2) ? 1 : 0, 
			       (cflags & 4) ? 2 : 0,
			       cflags & 8,
			       targetaddr, ops, 0,
			       &start_offset, &bytelen);
    if (code != 0) goto exit;

    unprep_stat_tab();
    unprep_stat_queue();

    while (ops != NULL) {
	next_ops = ops->next;
	stat_free(ops->name);
	stat_free(ops);
	ops = next_ops;
    };
    
    r = caml_alloc_small(2,0);
    Field(r,0) = Val_long(start_offset + off);
    Field(r,1) = Val_long(bytelen);

    return r;

 exit:
    unprep_stat_queue();
    unprep_stat_tab();

    switch(code) {
    case (-1):
	unix_error(errno, "netsys_init_value", Nothing);
    case (-2):
	failwith("Netsys_mem.init_value: Library error");
    case (-4):
	caml_raise_constant(*caml_named_value("Netsys_mem.Out_of_space"));
    default:
	failwith("Netsys_mem.init_value: Unknown error");
    }
}
Exemple #13
0
CAMLprim value caml_extunix_recvmsg2(value vfd, value vbuf, value ofs, value vlen,
  value vflags)
{
  CAMLparam4(vfd, vbuf, ofs, vlen);
  CAMLlocal5(vres, vlist, v, vx, vsaddr);
  union {
    struct cmsghdr hdr;
    char buf[CMSG_SPACE(sizeof(int)) /* File descriptor passing */
#ifdef EXTUNIX_HAVE_IP_RECVIF
        + CMSG_SPACE(sizeof(struct sockaddr_dl)) /* IP_RECVIF */
#endif
#ifdef EXTUNIX_HAVE_IP_RECVDSTADDR
        + CMSG_SPACE(sizeof(struct in_addr))     /* IP_RECVDSTADDR */
#endif
    ];
  } cmsgbuf;
  struct iovec             iov;
  struct msghdr            msg;
  struct cmsghdr          *cmsg;
  ssize_t                  n;
  size_t                   len;
  char                     iobuf[UNIX_BUFFER_SIZE];
  struct sockaddr_storage  ss;
  int                      sendflags;
#ifdef EXTUNIX_HAVE_IP_RECVIF
  struct sockaddr_dl      *dst = NULL;
#endif

  len = Long_val(vlen);

  memset(&iov, 0, sizeof(iov));
  memset(&msg, 0, sizeof(msg));

  if (len > UNIX_BUFFER_SIZE)
    len = UNIX_BUFFER_SIZE;

  iov.iov_base = iobuf;
  iov.iov_len = len;
  msg.msg_name = &ss;
  msg.msg_namelen = sizeof(ss);
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = &cmsgbuf.buf;
  msg.msg_controllen = sizeof(cmsgbuf.buf);
  sendflags = caml_convert_flag_list(vflags, msg_flag_table);

  caml_enter_blocking_section();
  n = recvmsg(Int_val(vfd), &msg, sendflags);
  caml_leave_blocking_section();

  vres = caml_alloc_small(4, 0);

  if (n == -1) {
    uerror("recvmsg", Nothing);
    CAMLreturn (vres);
  }

  vsaddr = my_alloc_sockaddr(&ss);

  memmove(&Byte(vbuf, Long_val(ofs)), iobuf, n);

  vlist = Val_int(0);

  /* Build the variant list vlist */
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
       cmsg = CMSG_NXTHDR(&msg, cmsg)) {
    if (cmsg->cmsg_level == SOL_SOCKET &&
        cmsg->cmsg_type == SCM_RIGHTS) {
      /* CMSG_DATA is aligned, so the following is cool */
      v = caml_alloc_small(2, TAG_FILEDESCRIPTOR);
      Field(v, 0) = Val_int(*(int *)CMSG_DATA(cmsg));
      Field(v, 1) = vlist;
      vlist = v;
      continue;
    }

#ifdef EXTUNIX_HAVE_IP_RECVIF
    if (cmsg->cmsg_level == IPPROTO_IP &&
        cmsg->cmsg_type == IP_RECVIF) {
      dst = (struct sockaddr_dl *)CMSG_DATA(cmsg);
      v = caml_alloc_small(2, 0);
      vx = caml_alloc_small(1, TAG_IP_RECVIF);
      Field(vx, 0) = Val_int(dst->sdl_index);
      Field(v, 0) = vx;
      Field(v, 1) = vlist;
      vlist = v;
      continue;
    }
#endif
#ifdef EXTUNIX_HAVE_IP_RECVDSTADDR
    if (cmsg->cmsg_level == IPPROTO_IP &&
        cmsg->cmsg_type == IP_RECVDSTADDR) {
      struct in_addr ipdst;
      ipdst = *(struct in_addr *)CMSG_DATA(cmsg);
      v = caml_alloc_small(2, 0);
      vx = caml_alloc_small(1, TAG_IP_RECVDSTADDR);
      Field(vx, 0) = caml_alloc_string(4);
      memcpy(String_val(Field(vx, 0)), &ipdst, 4);
      Field(v, 0) = vx;
      Field(v, 1) = vlist;
      vlist = v;
      continue;
    }
#endif
  }

  /* Now build the result */
  Field(vres, 0) = Val_long(n);
  Field(vres, 1) = vsaddr;
  Field(vres, 2) = vlist;
  Field(vres, 3) = int_to_recvflags(msg.msg_flags);

  CAMLreturn(vres);
}