1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/* Copyright (c) 2001-2014 John E. Davis
* This file is part of the S-Lang library.
*
* You may distribute under the terms of either the GNU General Public
* License or the Perl Artistic License.
*/
#include <stdio.h>
#include <slang.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
SLANG_MODULE(fcntl);
static int check_and_set_errno (int e)
{
#ifdef EINTR
if (e == EINTR)
return 0;
#endif
(void) SLerrno_set_errno (e);
return -1;
}
static int do_fcntl_2 (int fd, int cmd)
{
int ret;
while ((-1 == (ret = fcntl (fd, cmd)))
&& (0 == check_and_set_errno (errno)))
;
return ret;
}
static int do_fcntl_3_int (int fd, int cmd, int flags)
{
int ret;
while ((-1 == (ret = fcntl (fd, cmd, flags)))
&& (0 == check_and_set_errno (errno)))
;
return ret;
}
static int pop_fd (int *fdp)
{
SLFile_FD_Type *f;
int status;
if (SLang_peek_at_stack () == SLANG_INT_TYPE)
return SLang_pop_int (fdp);
if (-1 == SLfile_pop_fd (&f))
return -1;
status = SLfile_get_fd (f, fdp);
SLfile_free_fd (f);
return status;
}
static int fcntl_getfd (void)
{
int fd;
if (-1 == pop_fd (&fd))
return -1;
return do_fcntl_2 (fd, F_GETFD);
}
static int fcntl_setfd (int *flags)
{
int fd;
if (-1 == pop_fd (&fd))
return -1;
return do_fcntl_3_int (fd, F_SETFD, *flags);
}
static int fcntl_getfl (void)
{
int fd;
if (-1 == pop_fd (&fd))
return -1;
return do_fcntl_2 (fd, F_GETFL);
}
static int fcntl_setfl (int *flags)
{
int fd;
if (-1 == pop_fd (&fd))
return -1;
return do_fcntl_3_int (fd, F_SETFL, *flags);
}
#define F SLANG_FILE_FD_TYPE
#define I SLANG_INT_TYPE
static SLang_Intrin_Fun_Type Fcntl_Intrinsics [] =
{
MAKE_INTRINSIC_0("fcntl_getfd", fcntl_getfd, I),
MAKE_INTRINSIC_1("fcntl_setfd", fcntl_setfd, I, I),
MAKE_INTRINSIC_0("fcntl_getfl", fcntl_getfl, I),
MAKE_INTRINSIC_1("fcntl_setfl", fcntl_setfl, I, I),
SLANG_END_INTRIN_FUN_TABLE
};
#undef I
#undef F
static SLang_IConstant_Type Fcntl_Consts [] =
{
MAKE_ICONSTANT("FD_CLOEXEC", FD_CLOEXEC),
#ifndef O_ACCMODE
# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
MAKE_ICONSTANT("O_ACCMODE", O_ACCMODE),
SLANG_END_ICONST_TABLE
};
int init_fcntl_module_ns (char *ns_name)
{
SLang_NameSpace_Type *ns;
ns = SLns_create_namespace (ns_name);
if (ns == NULL)
return -1;
if ((-1 == SLns_add_intrin_fun_table (ns, Fcntl_Intrinsics, "__FCNTL__"))
|| (-1 == SLns_add_iconstant_table (ns, Fcntl_Consts, NULL)))
return -1;
return 0;
}
/* This function is optional */
void deinit_fcntl_module (void)
{
}
|