File: fcntl-module.c

package info (click to toggle)
slang2 2.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 10,588 kB
  • ctags: 10,558
  • sloc: ansic: 95,506; sh: 3,277; makefile: 945; pascal: 143
file content (147 lines) | stat: -rw-r--r-- 2,679 bytes parent folder | download
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)
{
}