2008-01-29 00:34:34 -05:00
|
|
|
/*
|
|
|
|
* Ikarus Scheme -- A compiler for R6RS Scheme.
|
|
|
|
* Copyright (C) 2006,2007,2008 Abdulaziz Ghuloum
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 3 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2007-12-09 07:20:49 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/types.h>
|
2007-12-10 15:02:25 -05:00
|
|
|
#include <sys/stat.h>
|
2007-12-09 07:20:49 -05:00
|
|
|
#include <sys/uio.h>
|
|
|
|
#include <unistd.h>
|
2007-12-26 17:35:58 -05:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netdb.h>
|
2008-03-22 19:29:41 -04:00
|
|
|
#include <string.h>
|
2008-03-24 13:18:39 -04:00
|
|
|
#include <netinet/in.h>
|
2009-04-09 05:29:50 -04:00
|
|
|
#include <dirent.h>
|
2007-12-09 07:20:49 -05:00
|
|
|
#include "ikarus-data.h"
|
|
|
|
|
2008-05-31 13:43:55 -04:00
|
|
|
extern ikptr ik_errno_to_code();
|
2007-12-09 07:20:49 -05:00
|
|
|
|
2007-12-23 13:37:48 -05:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_close_fd(ikptr fd /*, ikpcb* pcb */){
|
2007-12-09 07:20:49 -05:00
|
|
|
int err = close(unfix(fd));
|
|
|
|
if(err == -1){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2007-12-09 07:20:49 -05:00
|
|
|
} else {
|
|
|
|
return false_object;;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-09 03:00:44 -05:00
|
|
|
ikptr
|
|
|
|
ikrt_set_position(ikptr fd, ikptr pos /*, ikpcb* pcb */){
|
|
|
|
off_t offset = extract_num_longlong(pos);
|
|
|
|
off_t err = lseek(unfix(fd), offset, SEEK_SET);
|
|
|
|
if(err == -1){
|
|
|
|
return ik_errno_to_code();
|
|
|
|
} else {
|
|
|
|
return false_object;;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-23 13:37:48 -05:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_open_input_fd(ikptr fn /*, ikpcb* pcb */){
|
2008-01-01 21:08:07 -05:00
|
|
|
int fh = open((char*)(long)(fn+off_bytevector_data), O_RDONLY, 0);
|
2008-05-31 13:43:55 -04:00
|
|
|
if(fh >= 0){
|
2007-12-09 07:20:49 -05:00
|
|
|
return fix(fh);
|
|
|
|
} else {
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2007-12-09 07:20:49 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-23 13:37:48 -05:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_open_output_fd(ikptr fn, ikptr ikopts /*, ikpcb* pcb */){
|
2007-12-10 07:28:03 -05:00
|
|
|
int opts = unfix(ikopts);
|
|
|
|
int mode = 0;
|
|
|
|
switch (opts){
|
|
|
|
/* mode 0: error if exists, create if does not exist */
|
|
|
|
case 0: mode = O_WRONLY | O_CREAT | O_EXCL; break;
|
|
|
|
/* mode 1: truncate if exists, error if not exists */
|
|
|
|
case 1: mode = O_WRONLY | O_TRUNC; break;
|
|
|
|
/* mode 2: truncate if exists, create if not exist */
|
|
|
|
case 2: mode = O_WRONLY | O_TRUNC | O_CREAT ; break;
|
|
|
|
/* mode 3: truncate if exists, error if not exists */
|
|
|
|
case 3: mode = O_WRONLY | O_TRUNC ; break;
|
|
|
|
case 4: mode = O_WRONLY | O_CREAT | O_EXCL ; break;
|
|
|
|
case 5: mode = O_WRONLY | O_CREAT ; break;
|
|
|
|
case 6: mode = O_WRONLY | O_CREAT ; break;
|
|
|
|
case 7: mode = O_WRONLY ; break;
|
|
|
|
}
|
2008-01-01 21:08:07 -05:00
|
|
|
int fh = open((char*)(long)(fn+off_bytevector_data),
|
2007-12-10 07:28:03 -05:00
|
|
|
mode,
|
|
|
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
2008-05-31 13:43:55 -04:00
|
|
|
if(fh >= 0){
|
2007-12-10 07:28:03 -05:00
|
|
|
return fix(fh);
|
|
|
|
} else {
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2007-12-10 07:28:03 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-23 13:37:48 -05:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_read_fd(ikptr fd, ikptr bv, ikptr off, ikptr cnt /*, ikpcb* pcb */){
|
2008-03-22 19:29:41 -04:00
|
|
|
#if 0
|
|
|
|
fprintf(stderr, "READ: %d\n", unfix(fd));
|
|
|
|
#endif
|
2007-12-09 07:20:49 -05:00
|
|
|
ssize_t bytes =
|
|
|
|
read(unfix(fd),
|
2008-01-01 21:08:07 -05:00
|
|
|
(char*)(long)(bv+off_bytevector_data+unfix(off)),
|
2007-12-09 07:20:49 -05:00
|
|
|
unfix(cnt));
|
2008-03-22 19:29:41 -04:00
|
|
|
#if 0
|
|
|
|
fprintf(stderr, "BYTES: %d\n", bytes);
|
|
|
|
#endif
|
2007-12-09 07:20:49 -05:00
|
|
|
if(bytes >= 0){
|
|
|
|
return fix(bytes);
|
|
|
|
} else {
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2007-12-09 07:20:49 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-23 13:37:48 -05:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_write_fd(ikptr fd, ikptr bv, ikptr off, ikptr cnt /*, ikpcb* pcb */){
|
2008-04-12 15:06:55 -04:00
|
|
|
#if 0
|
|
|
|
if (0) {
|
|
|
|
fprintf(stderr, "WRITE %d, %p %d %d %d\n",
|
|
|
|
unfix(fd),
|
|
|
|
bv,
|
|
|
|
unfix(ref(bv, off_bytevector_length)),
|
|
|
|
unfix(off),
|
|
|
|
unfix(cnt));
|
|
|
|
int i;
|
|
|
|
for(i=0; i<100; i++){
|
|
|
|
fprintf(stderr, "bv[%d]=0x%02x ", i,
|
|
|
|
((char*)(bv+off_bytevector_data))[i]);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
#endif
|
2007-12-10 07:28:03 -05:00
|
|
|
ssize_t bytes =
|
|
|
|
write(unfix(fd),
|
2008-01-01 21:08:07 -05:00
|
|
|
(char*)(long)(bv+off_bytevector_data+unfix(off)),
|
2007-12-10 07:28:03 -05:00
|
|
|
unfix(cnt));
|
|
|
|
if(bytes >= 0){
|
|
|
|
return fix(bytes);
|
|
|
|
} else {
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2007-12-10 07:28:03 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-26 17:35:58 -05:00
|
|
|
|
|
|
|
|
2008-03-22 19:29:41 -04:00
|
|
|
static ikptr
|
|
|
|
do_connect(ikptr host, ikptr srvc, int socket_type){
|
2007-12-26 17:35:58 -05:00
|
|
|
struct addrinfo* info;
|
2008-01-01 21:08:07 -05:00
|
|
|
int err = getaddrinfo((char*)(long)(host+off_bytevector_data),
|
|
|
|
(char*)(long)(srvc+off_bytevector_data),
|
2007-12-26 17:35:58 -05:00
|
|
|
0,
|
|
|
|
&info);
|
|
|
|
if(err){
|
2008-05-31 13:43:55 -04:00
|
|
|
switch(err){
|
|
|
|
case EAI_SYSTEM: return ik_errno_to_code();
|
|
|
|
default: return false_object;
|
|
|
|
}
|
2007-12-26 17:35:58 -05:00
|
|
|
}
|
|
|
|
struct addrinfo* i = info;
|
2008-05-31 13:43:55 -04:00
|
|
|
ikptr sock = false_object;
|
2007-12-26 17:35:58 -05:00
|
|
|
while(i){
|
2008-03-22 19:29:41 -04:00
|
|
|
if(i->ai_socktype != socket_type){
|
2007-12-26 17:35:58 -05:00
|
|
|
i = i->ai_next;
|
|
|
|
} else {
|
|
|
|
int s = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
|
|
|
|
if(s < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
sock = ik_errno_to_code();
|
2007-12-26 17:35:58 -05:00
|
|
|
i = i->ai_next;
|
|
|
|
} else {
|
|
|
|
int err = connect(s, i->ai_addr, i->ai_addrlen);
|
|
|
|
if(err < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
sock = ik_errno_to_code();
|
2007-12-26 17:35:58 -05:00
|
|
|
i = i->ai_next;
|
|
|
|
} else {
|
2008-03-24 00:01:22 -04:00
|
|
|
sock = fix(s);
|
2007-12-26 17:35:58 -05:00
|
|
|
i = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freeaddrinfo(info);
|
2008-03-24 00:01:22 -04:00
|
|
|
return sock;
|
2007-12-26 17:35:58 -05:00
|
|
|
}
|
|
|
|
|
2007-12-27 22:08:27 -05:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_tcp_connect(ikptr host, ikptr srvc /*, ikpcb* pcb */){
|
2008-03-22 19:29:41 -04:00
|
|
|
return do_connect(host, srvc, SOCK_STREAM);
|
|
|
|
}
|
|
|
|
|
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_udp_connect(ikptr host, ikptr srvc /*, ikpcb* pcb */){
|
2008-03-22 19:29:41 -04:00
|
|
|
return do_connect(host, srvc, SOCK_DGRAM);
|
|
|
|
}
|
|
|
|
|
2008-03-23 00:41:49 -04:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_make_fd_nonblocking(ikptr fdptr /*, ikpcb* pcb */){
|
2007-12-27 22:08:27 -05:00
|
|
|
int fd = unfix(fdptr);
|
2008-03-23 00:41:49 -04:00
|
|
|
int err = fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
|
|
if(err == -1){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2007-12-27 22:08:27 -05:00
|
|
|
}
|
2008-03-23 00:41:49 -04:00
|
|
|
return 0;
|
2007-12-27 22:08:27 -05:00
|
|
|
}
|
2007-12-26 17:35:58 -05:00
|
|
|
|
2008-03-23 02:14:00 -04:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_select(ikptr fds, ikptr rfds, ikptr wfds, ikptr xfds /*, ikpcb* pcb */){
|
2008-03-23 02:14:00 -04:00
|
|
|
int rv = select(unfix(fds),
|
|
|
|
(fd_set*)(rfds + off_bytevector_data),
|
|
|
|
(fd_set*)(wfds + off_bytevector_data),
|
|
|
|
(fd_set*)(xfds + off_bytevector_data),
|
|
|
|
NULL);
|
|
|
|
if(rv < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 02:14:00 -04:00
|
|
|
}
|
|
|
|
return fix(rv);
|
|
|
|
}
|
2008-03-22 19:29:41 -04:00
|
|
|
|
2008-03-23 03:44:20 -04:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_listen(ikptr port /*, ikpcb* pcb */){
|
2008-03-23 03:44:20 -04:00
|
|
|
|
|
|
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
if(sock < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 03:44:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
struct sockaddr_in servaddr;
|
|
|
|
memset(&servaddr, 0, sizeof(struct sockaddr_in));
|
|
|
|
servaddr.sin_family = AF_INET;
|
|
|
|
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
servaddr.sin_port = htons(unfix(port));
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
int reuse = 1;
|
|
|
|
err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
|
|
|
|
if(err < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 03:44:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
|
|
|
if(err < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 03:44:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
err = listen(sock, 1024);
|
|
|
|
if(err < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 03:44:20 -04:00
|
|
|
}
|
|
|
|
return fix(sock);
|
|
|
|
}
|
|
|
|
|
2008-04-11 07:01:27 -04:00
|
|
|
#if 0
|
|
|
|
not used
|
|
|
|
ikptr
|
|
|
|
ikrt_getsockname(ikptr s, ikpcb* pcb){
|
|
|
|
socklen_t size = sizeof(struct sockaddr);
|
|
|
|
ikptr bv = ik_safe_alloc(pcb, align(disp_bytevector_data+size))
|
|
|
|
+ bytevector_tag;
|
|
|
|
int r = getsockname(unfix(s),
|
|
|
|
(struct sockaddr*)(bv+off_bytevector_data),
|
|
|
|
&size);
|
|
|
|
if(r == 0){
|
|
|
|
ref(bv, off_bytevector_length) = fix(size);
|
|
|
|
return bv;
|
|
|
|
} else {
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-04-11 07:01:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-03-23 03:44:20 -04:00
|
|
|
ikptr
|
2008-06-04 03:54:53 -04:00
|
|
|
ikrt_accept(ikptr s, ikptr bv /*, ikpcb* pcb */){
|
2008-04-11 07:01:27 -04:00
|
|
|
socklen_t addrlen = unfix(ref(bv, off_bytevector_length));
|
|
|
|
int sock = accept(unfix(s),
|
|
|
|
(struct sockaddr*) (bv+off_bytevector_data),
|
|
|
|
&addrlen);
|
2008-03-23 03:44:20 -04:00
|
|
|
if(sock < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 03:44:20 -04:00
|
|
|
}
|
2008-04-11 07:01:27 -04:00
|
|
|
ref(bv, off_bytevector_length) = fix(addrlen);
|
2008-03-23 03:44:20 -04:00
|
|
|
return fix(sock);
|
|
|
|
}
|
|
|
|
|
|
|
|
ikptr
|
2008-06-13 08:43:17 -04:00
|
|
|
ikrt_shutdown(ikptr s /*, ikpcb* pcb*/){
|
2008-03-24 13:25:59 -04:00
|
|
|
#ifdef __CYGWIN__
|
|
|
|
int err = close(unfix(s));
|
|
|
|
#else
|
2008-03-23 03:44:20 -04:00
|
|
|
int err = shutdown(unfix(s), SHUT_RDWR);
|
2008-03-24 13:25:59 -04:00
|
|
|
#endif
|
2008-03-23 03:44:20 -04:00
|
|
|
if(err < 0){
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-03-23 03:44:20 -04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-16 03:59:30 -05:00
|
|
|
static ikptr
|
|
|
|
timespec_bytevector(struct timespec* s, ikpcb* pcb) {
|
|
|
|
int len = sizeof(struct timespec);
|
|
|
|
ikptr r = ik_safe_alloc(pcb, align(disp_bytevector_data+len+3));
|
|
|
|
ref(r, 0) = fix(len+2);
|
|
|
|
*((char*)(r+disp_bytevector_data+0)) = sizeof(s->tv_sec);
|
|
|
|
*((char*)(r+disp_bytevector_data+1)) = sizeof(s->tv_nsec);
|
|
|
|
memcpy((char*)(r+disp_bytevector_data+2), s, len);
|
|
|
|
*((char*)(r+disp_bytevector_data+len+2)) = 0;
|
|
|
|
return r + bytevector_tag;
|
|
|
|
}
|
|
|
|
|
2008-11-16 04:22:23 -05:00
|
|
|
|
2008-11-16 03:59:30 -05:00
|
|
|
ikptr
|
|
|
|
ikrt_file_ctime2(ikptr filename, ikpcb* pcb){
|
|
|
|
struct stat s;
|
|
|
|
int err = stat((char*)(filename + off_bytevector_data), &s);
|
|
|
|
if(err) {
|
|
|
|
return ik_errno_to_code();
|
|
|
|
}
|
2008-11-16 04:22:23 -05:00
|
|
|
#if HAVE_STAT_ST_CTIMESPEC
|
2008-11-16 03:59:30 -05:00
|
|
|
return timespec_bytevector(&s.st_ctimespec, pcb);
|
2008-11-16 04:22:23 -05:00
|
|
|
#elif HAVE_STAT_ST_CTIM
|
|
|
|
return timespec_bytevector(&s.st_ctim, pcb);
|
|
|
|
#else
|
|
|
|
struct timespec ts;
|
|
|
|
ts.tv_sec = s.st_ctime;
|
|
|
|
ts.tv_nsec = 0;
|
2008-11-16 04:37:17 -05:00
|
|
|
return timespec_bytevector(&ts, pcb);
|
2008-11-16 04:22:23 -05:00
|
|
|
#endif
|
2008-11-16 03:59:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
ikptr
|
|
|
|
ikrt_file_mtime2(ikptr filename, ikpcb* pcb){
|
|
|
|
struct stat s;
|
|
|
|
int err = stat((char*)(filename + off_bytevector_data), &s);
|
|
|
|
if(err) {
|
|
|
|
return ik_errno_to_code();
|
|
|
|
}
|
2008-11-16 04:22:23 -05:00
|
|
|
#if HAVE_STAT_ST_MTIMESPEC
|
2008-11-16 03:59:30 -05:00
|
|
|
return timespec_bytevector(&s.st_mtimespec, pcb);
|
2008-11-16 04:22:23 -05:00
|
|
|
#elif HAVE_STAT_ST_MTIM
|
|
|
|
return timespec_bytevector(&s.st_mtim, pcb);
|
|
|
|
#else
|
|
|
|
struct timespec ts;
|
|
|
|
ts.tv_sec = s.st_mtime;
|
|
|
|
ts.tv_nsec = 0;
|
2008-11-16 04:37:17 -05:00
|
|
|
return timespec_bytevector(&ts, pcb);
|
2008-11-16 04:22:23 -05:00
|
|
|
#endif
|
2008-11-16 03:59:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-02-18 21:58:11 -05:00
|
|
|
ikptr
|
|
|
|
ikrt_file_ctime(ikptr filename, ikptr res){
|
|
|
|
struct stat s;
|
|
|
|
int err = stat((char*)(filename + off_bytevector_data), &s);
|
|
|
|
if(err) {
|
2008-05-31 13:43:55 -04:00
|
|
|
return ik_errno_to_code();
|
2008-02-18 21:58:11 -05:00
|
|
|
}
|
2008-02-19 03:28:40 -05:00
|
|
|
|
|
|
|
ref(res, off_car) = fix(s.st_ctime);
|
|
|
|
ref(res, off_cdr) = 0;
|
2008-02-18 21:58:11 -05:00
|
|
|
return fix(0);
|
|
|
|
}
|
|
|
|
|
2008-11-01 07:28:08 -04:00
|
|
|
ikptr
|
|
|
|
ikrt_file_mtime(ikptr filename, ikptr res){
|
|
|
|
struct stat s;
|
|
|
|
int err = stat((char*)(filename + off_bytevector_data), &s);
|
|
|
|
if(err) {
|
|
|
|
return ik_errno_to_code();
|
|
|
|
}
|
|
|
|
|
|
|
|
ref(res, off_car) = fix(s.st_mtime);
|
|
|
|
ref(res, off_cdr) = 0;
|
|
|
|
return fix(0);
|
|
|
|
}
|
|
|
|
|
2008-04-11 07:01:27 -04:00
|
|
|
|
2009-04-09 05:29:50 -04:00
|
|
|
ikptr
|
|
|
|
ikrt_opendir(ikptr dirname, ikpcb* pcb){
|
|
|
|
DIR* d = opendir((char*)(dirname+off_bytevector_data));
|
|
|
|
if(d == NULL){
|
|
|
|
return ik_errno_to_code();
|
|
|
|
}
|
|
|
|
return(make_pointer((long)d, pcb));
|
|
|
|
}
|
2008-04-11 07:01:27 -04:00
|
|
|
|
2009-04-09 05:29:50 -04:00
|
|
|
ikptr
|
|
|
|
ikrt_readdir(ikptr ptr, ikpcb* pcb){
|
|
|
|
DIR* d = (DIR*) ref(ptr, off_pointer_data);
|
2009-04-09 16:55:44 -04:00
|
|
|
errno = 0;
|
2009-04-09 05:29:50 -04:00
|
|
|
struct dirent* ent = readdir(d);
|
|
|
|
if (ent == NULL){
|
2009-04-09 16:55:44 -04:00
|
|
|
return (errno ? ik_errno_to_code() : false_object);
|
2009-04-09 05:29:50 -04:00
|
|
|
}
|
2009-04-09 16:55:44 -04:00
|
|
|
int len = strlen(ent->d_name);
|
2009-04-09 05:29:50 -04:00
|
|
|
ikptr bv = ik_safe_alloc(pcb, align(disp_bytevector_data+len+1))
|
|
|
|
+ bytevector_tag;
|
|
|
|
ref(bv, -bytevector_tag) = fix(len);
|
|
|
|
memcpy((char*)(bv+off_bytevector_data), ent->d_name, len+1);
|
|
|
|
return bv;
|
|
|
|
}
|
2008-04-11 07:01:27 -04:00
|
|
|
|
2009-04-09 05:29:50 -04:00
|
|
|
ikptr
|
|
|
|
ikrt_closedir(ikptr ptr, ikpcb* pcb){
|
|
|
|
DIR* d = (DIR*) ref(ptr, off_pointer_data);
|
|
|
|
int rv = closedir(d);
|
|
|
|
if (rv == -1){
|
|
|
|
return ik_errno_to_code();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|