]>
sourceware.org Git - glibc.git/blob - sysdeps/mach/hurd/fcntl.c
1 /* Copyright (C) 1992,93,94,95,96,97,99,2000 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
24 #include <sys/file.h> /* XXX for LOCK_* */
27 /* Perform file control operations on FD. */
29 __libc_fcntl (int fd
, int cmd
, ...)
35 d
= _hurd_fd_get (fd
);
38 return __hurd_fail (EBADF
);
46 default: /* Bad command. */
51 /* First the descriptor-based commands, which do no RPCs. */
53 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 /* Get a new file descriptor. The third argument to __fcntl is the
69 minimum file descriptor number for it. */
70 new = _hurd_alloc_fd (&result
, va_arg (ap
, int));
72 /* _hurd_alloc_fd has set errno. */
76 /* Give the ports each a user ref for the new descriptor. */
77 __mach_port_mod_refs (__mach_task_self (), port
,
78 MACH_PORT_RIGHT_SEND
, 1);
79 if (ctty
!= MACH_PORT_NULL
)
80 __mach_port_mod_refs (__mach_task_self (), ctty
,
81 MACH_PORT_RIGHT_SEND
, 1);
83 /* Install the ports and flags in the new descriptor. */
84 if (ctty
!= MACH_PORT_NULL
)
85 _hurd_port_set (&new->ctty
, ctty
);
86 /* Duplication clears the FD_CLOEXEC flag. */
87 new->flags
= flags
& ~FD_CLOEXEC
;
88 _hurd_port_locked_set (&new->port
, port
); /* Unlocks NEW. */
93 _hurd_port_free (&d
->port
, &ulink
, port
);
94 if (ctty
!= MACH_PORT_NULL
)
95 _hurd_port_free (&d
->ctty
, &ctty_ulink
, port
);
100 /* Set RESULT by evaluating EXPR with the descriptor locked.
101 Check for an empty descriptor and return EBADF. */
102 #define LOCKED(expr) \
103 HURD_CRITICAL_BEGIN; \
104 __spin_lock (&d->port.lock); \
105 if (d->port.port == MACH_PORT_NULL) \
106 result = __hurd_fail (EBADF); \
109 __spin_unlock (&d->port.lock); \
112 case F_GETFD
: /* Get descriptor flags. */
116 case F_SETFD
: /* Set descriptor flags. */
117 LOCKED ((d
->flags
= va_arg (ap
, int), 0));
121 /* Now the real io operations, done by RPCs to io servers. */
128 We need new RPCs to support POSIX.1 fcntl file locking!!
129 For the time being we support the whole-file case only,
130 with all kinds of WRONG WRONG WRONG semantics,
131 by using flock. This is definitely the Wrong Thing,
132 but it might be better than nothing (?). */
133 struct flock
*fl
= va_arg (ap
, struct flock
*);
149 case F_RDLCK
: cmd
|= LOCK_SH
; break;
150 case F_WRLCK
: cmd
|= LOCK_EX
; break;
151 case F_UNLCK
: cmd
|= LOCK_UN
; break;
156 switch (fl
->l_whence
)
159 if (fl
->l_start
== 0 && fl
->l_len
== 0)
171 return __flock (fd
, cmd
);
174 case F_GETFL
: /* Get per-open flags. */
175 if (err
= HURD_FD_PORT_USE (d
, __io_get_openmodes (port
, &result
)))
176 result
= __hurd_dfail (fd
, err
);
179 case F_SETFL
: /* Set per-open flags. */
180 err
= HURD_FD_PORT_USE (d
, __io_set_all_openmodes (port
,
182 result
= err
? __hurd_dfail (fd
, err
) : 0;
185 case F_GETOWN
: /* Get owner. */
186 if (err
= HURD_FD_PORT_USE (d
, __io_get_owner (port
, &result
)))
187 result
= __hurd_dfail (fd
, err
);
190 case F_SETOWN
: /* Set owner. */
191 err
= HURD_FD_PORT_USE (d
, __io_mod_owner (port
, va_arg (ap
, pid_t
)));
192 result
= err
? __hurd_dfail (fd
, err
) : 0;
201 weak_alias (__libc_fcntl
, __fcntl
)
202 weak_alias (__libc_fcntl
, fcntl
)
This page took 0.046308 seconds and 5 git commands to generate.