aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/modules/fcntl-module.c
blob: 7b329ab823630acf0a9031a3afa939b0893c83a0 (plain)
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
/* Copyright (c) 2001 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 (SLFile_FD_Type *f, int cmd)
{
   int ret;
   int fd;

   if (-1 == SLfile_get_fd (f, &fd))
     return -1;
     
   while ((-1 == (ret = fcntl (fd, cmd)))
	  && (0 == check_and_set_errno (errno)))
     ;
   
   return ret;
}

static int do_fcntl_3_int (SLFile_FD_Type *f, int cmd, int flags)
{
   int ret;
   int fd;
   
      
   if (-1 == SLfile_get_fd (f, &fd))
     return -1;

   while ((-1 == (ret = fcntl (fd, cmd, flags)))
	  && (0 == check_and_set_errno (errno)))
     ;
   
   return ret;
}
   
static int fcntl_getfd (SLFile_FD_Type *f)
{
   return do_fcntl_2 (f, F_GETFD);
}

static int fcntl_setfd (SLFile_FD_Type *f, int *flags)
{
   return do_fcntl_3_int (f, F_SETFD, *flags);
}

static int fcntl_getfl (SLFile_FD_Type *f)
{   
   return do_fcntl_2 (f, F_GETFL);
}

static int fcntl_setfl (SLFile_FD_Type *f, int *flags)
{
   return do_fcntl_3_int (f, F_SETFL, *flags);
}

#define F SLANG_FILE_FD_TYPE
#define I SLANG_INT_TYPE
static SLang_Intrin_Fun_Type Fcntl_Intrinsics [] =
{
   MAKE_INTRINSIC_1("fcntl_getfd", fcntl_getfd, I, F),
   MAKE_INTRINSIC_2("fcntl_setfd", fcntl_setfd, I, F, I),
   MAKE_INTRINSIC_1("fcntl_getfl", fcntl_getfl, I, F),
   MAKE_INTRINSIC_2("fcntl_setfl", fcntl_setfl, I, F, I),

   SLANG_END_INTRIN_FUN_TABLE
};
#undef I
#undef F

static SLang_IConstant_Type Fcntl_Consts [] =
{
   MAKE_ICONSTANT("FD_CLOEXEC", FD_CLOEXEC),
   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)
{
}