blob: 3cf984bc6c2aa3056cae7ca20d31884fd449563d [file] [log] [blame]
Dmitry V. Levin25120032015-10-01 12:24:01 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "defs.h"
32#include <fcntl.h>
33
34#include "xlat/fcntlcmds.h"
35#include "xlat/fdflags.h"
36#include "xlat/lockfcmds.h"
37#include "xlat/notifyflags.h"
38
39/*
40 * Assume that F_SETLK64, F_SETLKW64, and F_GETLK64 are either defined
41 * or not defined altogether.
42 */
43#if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK
44# define USE_PRINTFLOCK64 1
45#else
46# define USE_PRINTFLOCK64 0
47#endif
48
49#if USE_PRINTFLOCK64
50
51# ifndef HAVE_STRUCT_FLOCK64
52struct flock64 {
53 short int l_type, l_whence;
54 int64_t l_start, l_len;
55 int l_pid;
56};
57# endif
58
59static void
60printflock64(struct tcb *tcp, long addr, int getlk)
61{
62 struct flock64 fl;
63
64 if (umove_or_printaddr(tcp, addr, &fl))
65 return;
66 tprints("{type=");
67 printxval(lockfcmds, fl.l_type, "F_???");
68 tprints(", whence=");
69 printxval(whence_codes, fl.l_whence, "SEEK_???");
70 tprintf(", start=%lld, len=%lld", (long long) fl.l_start, (long long) fl.l_len);
71 if (getlk)
72 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
73 else
74 tprints("}");
75}
76#endif /* USE_PRINTFLOCK64 */
77
78static void
79printflock(struct tcb *tcp, long addr, int getlk)
80{
81 struct flock fl;
82
83#if SUPPORTED_PERSONALITIES > 1
84 if (
85# if SIZEOF_OFF_T > SIZEOF_LONG
86 current_personality != DEFAULT_PERSONALITY &&
87# endif
88 current_wordsize != sizeof(fl.l_start)) {
89 if (current_wordsize == 4) {
90 /* 32-bit x86 app on x86_64 and similar cases */
91 struct {
92 short int l_type;
93 short int l_whence;
94 int32_t l_start; /* off_t */
95 int32_t l_len; /* off_t */
96 int32_t l_pid; /* pid_t */
97 } fl32;
98 if (umove_or_printaddr(tcp, addr, &fl32))
99 return;
100 fl.l_type = fl32.l_type;
101 fl.l_whence = fl32.l_whence;
102 fl.l_start = fl32.l_start;
103 fl.l_len = fl32.l_len;
104 fl.l_pid = fl32.l_pid;
105 } else {
106 /* let people know we have a problem here */
107 tprintf("<decode error: unsupported wordsize %d>",
108 current_wordsize);
109 return;
110 }
111 } else
112#endif
113 if (umove_or_printaddr(tcp, addr, &fl))
114 return;
115 tprints("{type=");
116 printxval(lockfcmds, fl.l_type, "F_???");
117 tprints(", whence=");
118 printxval(whence_codes, fl.l_whence, "SEEK_???");
119#if SIZEOF_OFF_T > SIZEOF_LONG
120 tprintf(", start=%lld, len=%lld", fl.l_start, fl.l_len);
121#else
122 tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
123#endif
124 if (getlk)
125 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
126 else
127 tprints("}");
128}
129
130SYS_FUNC(fcntl)
131{
132 if (entering(tcp)) {
133 printfd(tcp, tcp->u_arg[0]);
134 tprints(", ");
135 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
136 switch (tcp->u_arg[1]) {
137 case F_SETFD:
138 tprints(", ");
139 printflags(fdflags, tcp->u_arg[2], "FD_???");
140 break;
141 case F_SETOWN: case F_DUPFD:
142#ifdef F_DUPFD_CLOEXEC
143 case F_DUPFD_CLOEXEC:
144#endif
145 tprintf(", %ld", tcp->u_arg[2]);
146 break;
147 case F_SETFL:
148 tprints(", ");
149 tprint_open_modes(tcp->u_arg[2]);
150 break;
151 case F_SETLK: case F_SETLKW:
152 tprints(", ");
153 printflock(tcp, tcp->u_arg[2], 0);
154 break;
155#if USE_PRINTFLOCK64
156 case F_SETLK64: case F_SETLKW64:
157 tprints(", ");
158 printflock64(tcp, tcp->u_arg[2], 0);
159 break;
160#endif /* USE_PRINTFLOCK64 */
161#ifdef F_NOTIFY
162 case F_NOTIFY:
163 tprints(", ");
164 printflags(notifyflags, tcp->u_arg[2], "DN_???");
165 break;
166#endif
167#ifdef F_SETLEASE
168 case F_SETLEASE:
169 tprints(", ");
170 printxval(lockfcmds, tcp->u_arg[2], "F_???");
171 break;
172#endif
Dmitry V. Levinc3410ba2015-10-09 01:55:46 +0000173 case F_GETOWN:
174 break;
175 default:
176 return 0;
Dmitry V. Levin25120032015-10-01 12:24:01 +0000177 }
Dmitry V. Levinc3410ba2015-10-09 01:55:46 +0000178 return RVAL_DECODED;
Dmitry V. Levin25120032015-10-01 12:24:01 +0000179 } else {
180 switch (tcp->u_arg[1]) {
Dmitry V. Levin25120032015-10-01 12:24:01 +0000181 case F_GETFD:
182 if (syserror(tcp) || tcp->u_rval == 0)
183 return 0;
184 tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval);
185 return RVAL_HEX|RVAL_STR;
186 case F_GETFL:
187 if (syserror(tcp))
188 return 0;
189 tcp->auxstr = sprint_open_modes(tcp->u_rval);
190 return RVAL_HEX|RVAL_STR;
191 case F_GETLK:
192 tprints(", ");
193 printflock(tcp, tcp->u_arg[2], 1);
194 break;
195#if USE_PRINTFLOCK64
196 case F_GETLK64:
197 tprints(", ");
198 printflock64(tcp, tcp->u_arg[2], 1);
199 break;
200#endif
201#ifdef F_GETLEASE
202 case F_GETLEASE:
203 if (syserror(tcp))
204 return 0;
205 tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
206 return RVAL_HEX|RVAL_STR;
207#endif
208 default:
209 tprintf(", %#lx", tcp->u_arg[2]);
210 break;
211 }
212 }
213 return 0;
214}