summaryrefslogtreecommitdiff
path: root/legacy/evil/src/lib/evil_fcntl.c
blob: f180417418899456d2d027583c0f86957a5f62bf (plain) (blame)
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
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */

#include <stdio.h>

#ifdef _MSC_VER
# include <io.h>   /* for _get_osfhandle _lseek and _locking */
#endif

#include <sys/locking.h>

#include <winsock2.h> /* for ioctlsocket */

#include "Evil.h"


#ifdef __MINGW32CE__
# define _get_osfhandle(FILEDES) ((HANDLE)FILEDES)
#endif /* __MINGW32CE__ */


/*
 * port of fcntl function
 *
 */

int fcntl(int fd, int cmd, ...)
{
   va_list va;
   HANDLE  h;
   int     res = -1;

   va_start (va, cmd);

   h = (HANDLE)_get_osfhandle(fd);
   if (h == INVALID_HANDLE_VALUE)
     return -1;

   if (cmd == F_GETFD)
     {
#ifndef __MINGW32CE__
        DWORD flag;

	if (!GetHandleInformation(h, &flag))
	  return -1;

	res = 0;
#endif /* ! __MINGW32CE__ */
     }

   if (cmd == F_SETFD)
     {
        long flag;

        flag = va_arg(va, long);
        if (flag == FD_CLOEXEC)
          {
#ifndef __MINGW32CE__
             if (SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0))
               res = 0;
#endif /* ! __MINGW32CE__ */
          }
     }
   else if (cmd == F_SETFL)
     {
        long flag;

        flag = va_arg(va, long);
        if (flag == O_NONBLOCK)
          {
             u_long arg = 1;
             int    type;
             int    len;
             int    ret;

             len = (int)sizeof(int);
             ret = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, (char *)&type, &len);
             if (!ret && (type == SOCK_STREAM))
               {
                  if (!ioctlsocket((SOCKET)fd, FIONBIO, &arg) == SOCKET_ERROR)
                    res = 0;
               }
          }
     }
#ifndef __MINGW32CE__
   else if ((cmd == F_SETLK) || (cmd == F_SETLKW))
     {
        struct flock *fl;
        off_t        length = 0;
        long         pos;

        fl = va_arg(va, struct flock *);

        if (fl->l_len == 0)
          {
             length = _lseek(fd, 0L, SEEK_END);
             if (length != -1L)
               res = 0;
          }
        fl->l_len = length - fl->l_start - 1;

        pos = _lseek(fd, fl->l_start, fl->l_whence);
        if (pos != -1L)
          res = 0;

        printf ("Evil 1 %d %d %d\n", fl->l_type, F_RDLCK, F_WRLCK);
        if ((fl->l_type == F_RDLCK) || (fl->l_type == F_WRLCK))
          {
        printf ("Evil 2\n");
             if (cmd == F_SETLK)
               res = _locking(fd, _LK_NBLCK, fl->l_len); /* if cannot be locked, we return immediatly */
             else /* F_SETLKW */
               res = _locking(fd, _LK_LOCK, fl->l_len); /* otherwise, we try several times */
          }

        printf ("Evil 3\n");
        if (fl->l_type == F_UNLCK)
          res = _locking(fd, _LK_UNLCK, fl->l_len);
     }

#endif /* ! __MINGW32CE__ */

   va_end(va);

   return res;
}