]>
git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/mach/hurd/fcntl.c
1 /* Copyright (C) 1992-2019 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
23 #include <sys/file.h> /* XXX for LOCK_* */
26 /* Perform file control operations on FD. */
28 __libc_fcntl (int fd
, int cmd
, ...)
34 d
= _hurd_fd_get (fd
);
37 return __hurd_fail (EBADF
);
45 default: /* Bad command. */
50 /* First the descriptor-based commands, which do no RPCs. */
52 case F_DUPFD
: /* Duplicate the file descriptor. */
57 struct hurd_userlink ulink
, ctty_ulink
;
62 /* Extract the ports and flags from the file descriptor. */
63 __spin_lock (&d
->port
.lock
);
65 ctty
= _hurd_port_get (&d
->ctty
, &ctty_ulink
);
66 port
= _hurd_port_locked_get (&d
->port
, &ulink
); /* Unlocks D. */
68 if (cmd
== F_DUPFD_CLOEXEC
)
71 /* Duplication clears the FD_CLOEXEC flag. */
74 /* Get a new file descriptor. The third argument to __fcntl is the
75 minimum file descriptor number for it. */
76 new = _hurd_alloc_fd (&result
, va_arg (ap
, int));
78 /* _hurd_alloc_fd has set errno. */
82 /* Give the ports each a user ref for the new descriptor. */
83 __mach_port_mod_refs (__mach_task_self (), port
,
84 MACH_PORT_RIGHT_SEND
, 1);
85 if (ctty
!= MACH_PORT_NULL
)
86 __mach_port_mod_refs (__mach_task_self (), ctty
,
87 MACH_PORT_RIGHT_SEND
, 1);
89 /* Install the ports and flags in the new descriptor. */
90 if (ctty
!= MACH_PORT_NULL
)
91 _hurd_port_set (&new->ctty
, ctty
);
93 _hurd_port_locked_set (&new->port
, port
); /* Unlocks NEW. */
98 _hurd_port_free (&d
->port
, &ulink
, port
);
99 if (ctty
!= MACH_PORT_NULL
)
100 _hurd_port_free (&d
->ctty
, &ctty_ulink
, port
);
105 /* Set RESULT by evaluating EXPR with the descriptor locked.
106 Check for an empty descriptor and return EBADF. */
107 #define LOCKED(expr) \
108 HURD_CRITICAL_BEGIN; \
109 __spin_lock (&d->port.lock); \
110 if (d->port.port == MACH_PORT_NULL) \
111 result = __hurd_fail (EBADF); \
114 __spin_unlock (&d->port.lock); \
117 case F_GETFD
: /* Get descriptor flags. */
121 case F_SETFD
: /* Set descriptor flags. */
122 LOCKED ((d
->flags
= va_arg (ap
, int), 0));
126 /* Now the real io operations, done by RPCs to io servers. */
132 struct flock
*fl
= va_arg (ap
, struct flock
*);
144 return __f_setlk (fd
, fl
->l_type
, fl
->l_whence
,
145 fl
->l_start
, fl
->l_len
, wait
);
156 struct flock64
*fl
= va_arg (ap
, struct flock64
*);
168 return __f_setlk (fd
, fl
->l_type
, fl
->l_whence
,
169 fl
->l_start
, fl
->l_len
, wait
);
176 case F_GETFL
: /* Get per-open flags. */
177 if (err
= HURD_FD_PORT_USE (d
, __io_get_openmodes (port
, &result
)))
178 result
= __hurd_dfail (fd
, err
);
181 case F_SETFL
: /* Set per-open flags. */
182 err
= HURD_FD_PORT_USE (d
, __io_set_all_openmodes (port
,
184 result
= err
? __hurd_dfail (fd
, err
) : 0;
187 case F_GETOWN
: /* Get owner. */
188 if (err
= HURD_FD_PORT_USE (d
, __io_get_owner (port
, &result
)))
189 result
= __hurd_dfail (fd
, err
);
192 case F_SETOWN
: /* Set owner. */
193 err
= HURD_FD_PORT_USE (d
, __io_mod_owner (port
, va_arg (ap
, pid_t
)));
194 result
= err
? __hurd_dfail (fd
, err
) : 0;
202 libc_hidden_def (__libc_fcntl
)
203 weak_alias (__libc_fcntl
, __fcntl
)
204 libc_hidden_weak (__fcntl
)
205 weak_alias (__libc_fcntl
, fcntl
)
207 strong_alias (__libc_fcntl
, __libc_fcntl64
)
208 libc_hidden_def (__libc_fcntl64
)
209 weak_alias (__libc_fcntl64
, __fcntl64
)
210 libc_hidden_weak (__fcntl64
)
211 weak_alias (__fcntl64
, fcntl64
)