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