Codebase list pseudo / upstream/1.9.0+git20190515+996bead
New upstream version 1.9.0+git20190515+996bead Andrej Shadura 4 years ago
268 changed file(s) with 2102 addition(s) and 855 deletion(s). Raw diff Collapse all Expand all
456456
457457 END OF TERMS AND CONDITIONS
458458
459 How to Apply These Terms to Your New Libraries
460
461 If you develop a new library, and you want it to be of the greatest
462 possible use to the public, we recommend making it free software that
463 everyone can redistribute and change. You can do so by permitting
464 redistribution under these terms (or, alternatively, under the terms of the
465 ordinary General Public License).
466
467 To apply these terms, attach the following notices to the library. It is
468 safest to attach them to the start of each source file to most effectively
469 convey the exclusion of warranty; and each file should have at least the
470 "copyright" line and a pointer to where the full notice is found.
471
472 <one line to give the library's name and a brief idea of what it does.>
473 Copyright (C) <year> <name of author>
474
475 This library is free software; you can redistribute it and/or
476 modify it under the terms of the GNU Lesser General Public
477 License as published by the Free Software Foundation; either
478 version 2.1 of the License, or (at your option) any later version.
479
480 This library is distributed in the hope that it will be useful,
481 but WITHOUT ANY WARRANTY; without even the implied warranty of
482 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
483 Lesser General Public License for more details.
484
485 You should have received a copy of the GNU Lesser General Public
486 License along with this library; if not, write to the Free Software
487 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
488
489 Also add information on how to contact you by electronic and paper mail.
490
491 You should also get your employer (if you work as a programmer) or your
492 school, if any, to sign a "copyright disclaimer" for the library, if
493 necessary. Here is a sample; alter the names:
494
495 Yoyodyne, Inc., hereby disclaims all copyright interest in the
496 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
497
498 <signature of Ty Coon>, 1 April 1990
499 Ty Coon, President of Vice
500
501 That's all there is to it!
502
503
459 Note:
460 Individual files contain the following tag instead of the full license text.
461
462 SPDX-License-Identifier: LGPL-2.1-only
463
464 This enables machine processing of license information based on the SPDX
465 License Identifiers that are here available: http://spdx.org/licenses/
0 2019-05-15:
1 * (RP) Add SDPX license headers to source files.
2
3 2019-04-10:
4 * (seebs) Experimental workaround for special non-blocking open
5 case.
6 * (seebs) fix warnings in renameat2.
7
8 2019-04-09:
9 * (seebs) Partial fix for db corruption issue.
10 * (seebs) Make a glibc renameat2 wrapper that just fails because
11 implementing renameat2 semantics is Surprisingly Hard.
12
13 2018-12-15:
14 * (seebs) Import IPC patch from Rasmus Villemoes.
15 * (seebs) Import (another) IPC patch from Rasmus Villemoes.
16
17 2018-11-29:
18 * (seebs) add missing <stdint.h> to pseudo_db.c. Thanks to
19 Bernhard Hartleb <bernhard.hartleb@gmail.com> for pointing
20 this out.
21
22 2018-09-20:
23 * (seebs) coerce inodes to signed int64_t range when shoving
24 them into sqlite.
25 * (seebs) add another /*fallthrough*/ comment to make gcc7 happy.
26 * (seebs) also make sure inodes are handled as 64-bit, not
27 32-bit, which probably matters more. Thanks to <Jack.Fewx@dell.com>
28 for catching this.
29
30 2018-04-13:
31 * (seebs) Reduce spamminess of path mismatches.
32 Don't log path mismatches with multiple links unless you've
33 requested path+verbose debugging. Also allow pseudo_debug
34 to take a 0 to indicate "always debug", because we want that
35 message unconditionally, and I don't want near-identical
36 calls to diag() and debug().
37 * (seebs) Fix a lurking stray slash that could happen while
38 resolving absolute symlinks.
39 * (seebs) fix mishandled flags for symlink following.
40
41 2018-04-02:
42 * (seebs) Change default copyright notice in guts to
43 say "Peter Seebach" rather than "Wind River" as I haven't
44 worked there in over a year.
45
46 2018-03-31:
47 * (seebs) keep pseudo_fix_path from changing errno, because
48 *some* people think they should check errno to find out
49 whether an error occurred, even if no call has returned
50 a status indicating an error, and this is completely wrong
51 but we can't fix them all.
52 * (seebs) check for wrapper initialization in syscall wrapper,
53 because what if it was the *first* call someone made. (Thanks
54 to Joshua Watt <jpewhacker@gmail.com> for diagnosing this
55 before I got a chance.)
56
57 2018-03-30:
58 * (seebs) fix path stuff more thoroughly.
59 * (seebs) Merge suggested README change from Richard Tollerton
60 <rich.tollerton@ni.com> pointing to oe-core list.
61 * (seebs) Merge suggested setuid/etc bit change from
62 Richard Tollerton, and associated test case.
63
64 2018-03-29:
65 * (seebs) wrap syscall, and if SYS_renameat2 exists, try to
66 reject it with ENOSYS, because coreutils started using a
67 new syscall. An actual renameat2 wrapper will be a major
68 effort ("changing the pseudo_ipc data structure") and is
69 pointless when glibc hasn't got a wrapper so we have no
70 viable test cases.
71
72 2018-03-06:
73 * (seebs) Update path handling a bit to correctly fail if a path
74 tries to have a slash after a plain file name, even in cases
75 like "foo/.", which were previously ignored (or in the case of
76 "..", resolved as though it had been a directory).
77
78 2018-03-01:
79 * (seebs) If you get a CREAT for an existing file, and it matches
80 both path and inode, don't delete the entry because the inode
81 matched and then not create it because the path used to match
82 before you delete it.
83
84 2018-02-26:
85 * (seebs) implement mkstemps, mkostemp, and mkostemps. Actually,
86 move implementation all to mkostemps, then implement the others
87 in terms of it.
88
89 2018-02-19:
90 * (seebs) fix using index of request rather than request's value
91
92 2018-02-16:
93 * (seebs) allow closing client #0.
94
95 2018-02-15:
96 * (seebs) O_TMPFILE is actually some other flag AND O_DIRECTORYy,
97 so a test for (flags & O_TMPFILE) does not actually test that
98 O_TMPFILE is set.
99
100 2018-01-20:
101 * (seebs) merge patch from <joshua.g.lock@linux.intel.com> to fix
102 open/openat flags.
103
104 2018-01-16:
105 * (seebs) rework the LINKAT case significantly but now
106 it's actually probably right.
107 * (<zboszor@pr.hu>) handle extremely long group names
108 in getgrnam and similar functions.
109 * (seebs) drop the diagnostic for a missing "real" function
110 as it turns out to be counterproductive at best.
111 * (seebs) merge epoll support from <alexander.kanavin@linux.intel.com>
112 * (seebs) add wrapper for statvfs (based on patch from
113 <dan.dedrick@gmail.com>)
114 * (seebs) Call this 1.9.0.
115 * (seebs) Experimental-ish: Require a response even for FASTOP
116 just to confirm delivery of message/server availability.
117
118 2017-12-22:
119 * (seebs) handle the pathological case of LINKAT with
120 AT_SYMLINK_FOLLOW on /proc/self/fd/N.
121
122 2017-12-18:
123 * (seebs) Add a list of clients as a handler for SIGUSR2. (Useful
124 for debugging, maybe.)
125
126 2017-04-13:
127 * (seebs) don't unset LD_PRELOAD or the like, because if you
128 do that, bash can segfault because it "knows" how many
129 fields are in environ.
130
131 2017-02-24:
132 * (seebs) import posix_acl_default fix from Anton Gerasimov
133 <anton@advancedtelematic.com>
134 2017-02-03:
135 * (gportay) contributed fix to Makefile (fix binaries rebuild).
136
137 2017-02-01:
138 * (seebs) handle xattr deletion slightly more carefully.
139 * (seebs) tag this as 1.8.2
140
141 2016-12-12:
142 * (seebs) contributed fix to makewrappers (fix space/tab issues)
143 * (seebs) contributed fixes for Python 3 print support
144 * (seebs) contributed fixes for Python 3 support
145 * All of these from: Gaël PORTAY <gael.portay@savoirfairelinux.com>
146 * (seebs) import fix from Rabin Vincent for test case
147 * (seebs) import fix from Rabin Vincent for pthread mutexes
148 * (seebs) import fix from George McCollister for capset.
149 * (seebs) import fix from Igor Gnatenko for man page sections.
150
151 2016-11-23:
152 * (seebs) actually wait on server shutdown for pseudo -S [cmd]
153
154 2016-11-04:
155 * (seebs) clarify usage message on missing --prefix
156
157 2016-10-31:
158 * (seebs) drop silly if
159
160 2016-10-29:
161 * (seebs) handle x32
162
0163 2016-10-13:
1164 * (seebs) handle commas in CFLAGS
2165
22 #
33 # Copyright (c) 2008-2015 Wind River Systems, Inc.
44 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the Lesser GNU General Public License version 2.1 as
7 # published by the Free Software Foundation.
8 #
9 # This program 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.
12 # See the Lesser GNU General Public License for more details.
13 #
14 # You should have received a copy of the Lesser GNU General Public License
15 # version 2.1 along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 # SPDX-License-Identifier: LGPL-2.1-only
176 #
187
198 # configuration flags
2413 SQLITE_LIB=@SQLITE_LIB@
2514 SQLITE_MEMORY=@SQLITE_MEMORY@
2615 FORCE_ASYNC=@FORCE_ASYNC@
16 EPOLL=@EPOLL@
2717 XATTR=@XATTR@
2818 XATTRDB=@XATTRDB@
2919 PROFILING=@PROFILING@
4333 ARCH_FLAGS=@ARCH_FLAGS@
4434 MARK64=@MARK64@
4535 RPATH=@RPATH@
46 VERSION=1.8.1
36 VERSION=1.9.0
4737
4838 LIB=@LIB@
4939 BIN=bin
5343
5444 CFLAGS_BASE=-pipe -std=gnu99 -Wall -W -Wextra
5545 CFLAGS_CODE=-fPIC -D_LARGEFILE64_SOURCE -D_ATFILE_SOURCE $(ARCH_FLAGS)
56 CFLAGS_DEFS=-DPSEUDO_PREFIX='"$(PREFIX)"' -DPSEUDO_SUFFIX='"$(SUFFIX)"' -DPSEUDO_BINDIR='"$(BIN)"' -DPSEUDO_LIBDIR='"$(LIB)"' -DPSEUDO_LOCALSTATEDIR='"$(LOCALSTATE)"' -DPSEUDO_VERSION='"$(VERSION)"' $(SQLITE_MEMORY) $(FORCE_ASYNC) -DPSEUDO_PASSWD_FALLBACK='$(PASSWD_FALLBACK)' $(OPTDEFS)
46 CFLAGS_DEFS=-DPSEUDO_PREFIX='"$(PREFIX)"' -DPSEUDO_SUFFIX='"$(SUFFIX)"' -DPSEUDO_BINDIR='"$(BIN)"' -DPSEUDO_LIBDIR='"$(LIB)"' -DPSEUDO_LOCALSTATEDIR='"$(LOCALSTATE)"' -DPSEUDO_VERSION='"$(VERSION)"' $(SQLITE_MEMORY) $(FORCE_ASYNC) -DPSEUDO_PASSWD_FALLBACK='$(PASSWD_FALLBACK)' $(OPTDEFS) $(EPOLL)
5747 CFLAGS_DEBUG=-O2 -g
5848 @DEFAULT_SQLITE@CFLAGS_SQL=-L$(SQLITE)/$(SQLITE_LIB) -I$(SQLITE)/include $(RPATH)
5949 CFLAGS_PSEUDO=$(CFLAGS_BASE) $(CFLAGS_CODE) $(CFLAGS_DEFS) \
8373
8474 all: $(LIBPSEUDO) $(PSEUDO) $(PSEUDODB) $(PSEUDOLOG) $(PSEUDO_PROFILE)
8575
86 test: all $(BIN) $(LIB) $(LOCALSTATE)
76 test: all | $(BIN) $(LIB) $(LOCALSTATE)
8777 @./run_tests.sh -v
8878
8979 install-lib: $(LIBPSEUDO)
10595
10696 pseudo: $(PSEUDO)
10797
108 $(PSEUDO): $(BIN) pseudo.o $(SHOBJS) $(DBOBJS) pseudo_client.o pseudo_server.o pseudo_ipc.o
98 $(PSEUDO): pseudo.o $(SHOBJS) $(DBOBJS) pseudo_client.o pseudo_server.o pseudo_ipc.o | $(BIN)
10999 $(CC) $(CFLAGS) $(CFLAGS_PSEUDO) -o $(PSEUDO) \
110100 pseudo.o pseudo_server.o pseudo_client.o pseudo_ipc.o \
111101 $(DBOBJS) $(SHOBJS) $(LDFLAGS) $(DB_LDFLAGS) $(CLIENT_LDFLAGS)
112102
113103 pseudolog: $(PSEUDOLOG)
114104
115 $(PSEUDOLOG): $(BIN) pseudolog.o $(SHOBJS) $(DBOBJS) pseudo_client.o pseudo_ipc.o
105 $(PSEUDOLOG): pseudolog.o $(SHOBJS) $(DBOBJS) pseudo_client.o pseudo_ipc.o | $(BIN)
116106 $(CC) $(CFLAGS) $(CFLAGS_PSEUDO) -o $(PSEUDOLOG) pseudolog.o pseudo_client.o pseudo_ipc.o \
117107 $(DBOBJS) $(SHOBJS) $(LDFLAGS) $(DB_LDFLAGS) $(CLIENT_LDFLAGS)
118108
119109 pseudodb: $(PSEUDODB)
120110
121 $(PSEUDODB): $(BIN) pseudodb.o $(SHOBJS) $(DBOBJS) pseudo_ipc.o
111 $(PSEUDODB): pseudodb.o $(SHOBJS) $(DBOBJS) pseudo_ipc.o | $(BIN)
122112 $(CC) $(CFLAGS) $(CFLAGS_PSEUDO) -o $(PSEUDODB) pseudodb.o \
123113 $(DBOBJS) $(SHOBJS) pseudo_ipc.o $(LDFLAGS) $(DB_LDFLAGS) $(CLIENT_LDFLAGS)
124114
125115 libpseudo: $(LIBPSEUDO)
126116
127 $(LIBPSEUDO): $(LIB) $(WRAPOBJS) pseudo_client.o pseudo_ipc.o $(SHOBJS)
117 $(LIBPSEUDO): $(WRAPOBJS) pseudo_client.o pseudo_ipc.o $(SHOBJS) | $(LIB)
128118 $(CC) $(CFLAGS) $(CFLAGS_PSEUDO) -shared -o $(LIBPSEUDO) \
129119 pseudo_client.o pseudo_ipc.o \
130120 $(WRAPOBJS) $(SHOBJS) $(LDFLAGS) $(CLIENT_LDFLAGS)
167157 offsets64:
168158 $(CC) -m64 -o offsets64 offsets.c
169159
170 $(PSEUDO_PROFILE): $(BIN) pseudo_profile
160 $(PSEUDO_PROFILE): pseudo_profile | $(BIN)
171161 cp pseudo_profile $(BIN)
172162
173163 pseudo_profile: Makefile pseudo_profile.c tables wrappers
8484 deal of fun, and I'm pretty happy that we're finally ready to make it
8585 available for other people to look at.
8686
87
88 CONTACT:
89
90 Discussions and patches should be directed at the openembedded-core mailing
91 list at openembedded-core at lists.openembedded.org. More information at
92 https://www.openembedded.org/wiki/Mailing_lists. Bugs should be filed with
93 the Yocto project at https://bugzilla.yoctoproject.org/.
33 #
44 # Copyright (c) 2008-2014 Wind River Systems, Inc.
55 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the Lesser GNU General Public License version 2.1 as
8 # published by the Free Software Foundation.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 # See the Lesser GNU General Public License for more details.
14 #
15 # You should have received a copy of the Lesser GNU General Public License
16 # version 2.1 along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 # SPDX-License-Identifier: LGPL-2.1-only
187 #
198 # not a real configure script...
209 opt_prefix=
2413 opt_bits=
2514 opt_sqlite=/usr
2615 opt_rpath=
16 opt_epoll=
2717 opt_memory=
2818 opt_async=
2919 opt_xattr=
3626
3727 usage()
3828 {
29 [ -n "$*" ] && echo >&2 "$*"
3930 echo >&2 "usage:"
4031 echo >&2 " configure --prefix=..."
4132 echo >&2 " [--libdir=...]"
4233 echo >&2 " [--suffix=...]"
4334 echo >&2 " [--enable-memory-db]"
35 echo >&2 " [--enable-epoll]"
4436 echo >&2 " [--enable-xattr]"
4537 echo >&2 " [--enable-xattrdb]"
4638 echo >&2 " [--enable-profiling]"
114106 --enable-profiling=yes | --enable-profiling)
115107 opt_profiling=true
116108 ;;
109 --enable-epoll=no)
110 opt_epoll=false
111 ;;
112 --enable-epoll=yes | --enable-epoll)
113 opt_epoll=true
114 ;;
117115 --enable-xattr=no)
118116 opt_xattr=false
119117 ;;
214212 fi
215213
216214 if [ -z "$opt_prefix" ]; then
217 usage
215 usage "Error: You must specify a prefix path for installation (--prefix=)."
218216 fi
219217
220218 if [ -z "$opt_libdir" ]; then
251249
252250 if [ -z "$opt_async" ]; then
253251 opt_async=false
252 fi
253
254 if [ -z "$opt_epoll" ]; then
255 opt_epoll=false
254256 fi
255257
256258 if $opt_async; then
281283 fi
282284 fi
283285
286 if $opt_epoll; then
287 EPOLL="-DPSEUDO_EPOLL"
288 else
289 EPOLL=""
290 fi
291
284292 if $opt_xattr || $opt_xattrdb; then
285293 if ! $xattr_runs; then
286294 echo >&2 "WARNING: getfattr doesn't work, but xattr-related features requestd."
320328
321329 sed -e '
322330 s,@PREFIX@,'"$opt_prefix"',g
331 s,@EPOLL@,'"$EPOLL"',g
323332 s,@XATTR@,'"$opt_xattr"',g
324333 s,@XATTRDB@,'"$opt_xattrdb"',g
325334 s,@PROFILING@,'"$opt_profiling"',g
1717 pseudo_loaded, "server couldn't get out of pseudo environment"
1818 pseudo_prefix, "couldn't get valid pseudo prefix"
1919 pseudo_invocation, "invalid server command arguments"
20 epoll_create, "epoll_create() failed"
21 epoll_ctl, "epoll_ctl() failed"
22
00 /*
11 * Copyright (c) 2008-2014 Wind River Systems, Inc.
22 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the Lesser GNU General Public License version 2.1 as
5 * published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 * See the Lesser GNU General Public License for more details.
11 *
12 * You should have received a copy of the Lesser GNU General Public License
13 * version 2.1 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3 * SPDX-License-Identifier: LGPL-2.1-only
154 *
165 */
11 #
22 # Copyright (c) 2008-2010, 2013 Wind River Systems, Inc.
33 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the Lesser GNU General Public License version 2.1 as
6 # published by the Free Software Foundation.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # See the Lesser GNU General Public License for more details.
12 #
13 # You should have received a copy of the Lesser GNU General Public License
14 # version 2.1 along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4 # SPDX-License-Identifier: LGPL-2.1-only
165 #
176 """convert tables.in files to enums, tables, and support code.
187
5039 import glob
5140 import sys
5241 import string
42 import os
5343 from templatefile import TemplateFile
5444
5545 class DataType:
5747
5848 def __init__(self, path):
5949 """read the first line of path, then make tuples of the rest"""
60 source = file(path)
61 definition = source.readline().rstrip()
62 self.name, qualifiers = string.split(definition, ': ', 2)
63 if '; ' in qualifiers:
64 self.prefix, columns = string.split(qualifiers, '; ')
65 else:
66 self.prefix = qualifiers
67 columns = []
68 self.flags = False
69 if len(columns):
70 self.columns = []
71 columns = string.split(columns, ', ')
72 for col in columns:
73 indexed = False
74 if col.startswith("FLAGS"):
75 print "Flags: set for %s" % self.name
76 self.flags = True
50 with open(path,'r') as source:
51 definition = source.readline().rstrip()
52 self.name, qualifiers = definition.split(': ', 2)
53 if '; ' in qualifiers:
54 self.prefix, columns = qualifiers.split('; ')
55 else:
56 self.prefix = qualifiers
57 columns = []
58 self.flags = False
59 if len(columns):
60 self.columns = []
61 columns = columns.split(', ')
62 for col in columns:
63 indexed = False
64 if col.startswith("FLAGS"):
65 print("Flags: set for %s" % self.name)
66 self.flags = True
67 continue
68 if col.startswith("INDEXED "):
69 col = col[8:]
70 indexed = True
71 if "=" in col:
72 name, default = col.split(' = ')
73 else:
74 name, default = col, ""
75 if " " in name:
76 words = name.split(' ')
77 name = words[-1]
78 del words[-1]
79 type = ' '.join(words)
80 else:
81 type = "char *"
82 self.columns.append({"indexed":indexed, "type":type, "name":name, "value":default})
83 else:
84 self.columns = []
85 self.data = []
86 self.comments = []
87 index = 1
88 for line in source.readlines():
89 item = {}
90 if line.startswith('#'):
91 self.comments.append(line.rstrip().replace('#', ''))
7792 continue
78 if col.startswith("INDEXED "):
79 col = col[8:]
80 indexed = True
81 if "=" in col:
82 name, default = string.split(col, ' = ')
83 else:
84 name, default = col, ""
85 if " " in name:
86 words = string.split(name, ' ')
87 name = words[-1]
88 del words[-1]
89 type = ' '.join(words)
90 else:
91 type = "char *"
92 self.columns.append({"indexed":indexed, "type":type, "name":name, "value":default})
93 else:
94 self.columns = []
95 self.data = []
96 self.comments = []
97 index = 1
98 for line in source.readlines():
99 item = {}
100 if line.startswith('#'):
101 self.comments.append(line.rstrip().replace('#', ''))
102 continue
103 # first entry on the line is the "real" name/id, following hunks
104 # are additional columns
105 cols = string.split(line.rstrip(), ', ')
106 item["name"] = cols.pop(0)
107 item["upper"] = item["name"].replace('-', '_').upper()
108 column_list = []
109 for col in self.columns:
110 if len(cols) > 0:
111 value = cols.pop(0)
112 if col["indexed"]:
113 if not "max" in col:
114 col["max"] = value
115 if value > col["max"]:
116 col["max"] = value
117 if not "min" in col:
118 col["min"] = value
119 if value < col["min"]:
120 col["min"] = value
121 column_list.append({"name":col["name"], "value":value})
122 else:
123 column_list.append({"name":col["name"], "value":col["value"]})
124 item["cols"] = column_list
125 item["index"] = index
126 index = index + 1
127 self.data.append(item)
93 # first entry on the line is the "real" name/id, following hunks
94 # are additional columns
95 cols = line.rstrip().split(', ')
96 item["name"] = cols.pop(0)
97 item["upper"] = item["name"].replace('-', '_').upper()
98 column_list = []
99 for col in self.columns:
100 if len(cols) > 0:
101 value = cols.pop(0)
102 if col["indexed"]:
103 if not "max" in col:
104 col["max"] = value
105 if value > col["max"]:
106 col["max"] = value
107 if not "min" in col:
108 col["min"] = value
109 if value < col["min"]:
110 col["min"] = value
111 column_list.append({"name":col["name"], "value":value})
112 else:
113 column_list.append({"name":col["name"], "value":col["value"]})
114 item["cols"] = column_list
115 item["index"] = index
116 index = index + 1
117 self.data.append(item)
128118
129119 def __getitem__(self, key):
130120 """Make this object look like a dict for Templates to use"""
247237 template_file.emit('header')
248238 templates.append(template_file)
249239 except IOError:
250 print "Invalid or malformed template %s. Aborting." % path
240 print("Invalid or malformed template %s. Aborting." % path)
251241 exit(1)
252242
253243 for filename in sys.argv[1:]:
255245 sys.stdout.write("%s: " % filename)
256246 datatype = DataType(filename)
257247 datatypes.append(datatype)
258 print datatype.__repr__()
259 print ""
260
261 print "Writing datatypes...",
248 print(datatype.__repr__())
249 print("")
250
251 print("Writing datatypes...")
262252 for datatype in datatypes:
263253 # populate various tables and files with each datatype
264254 for template_file in templates:
265255 template_file.emit('body', datatype)
266 print "done. Cleaning up."
256 print("done. Cleaning up.")
267257
268258 for template_file in templates:
269259 # clean up files
11 #
22 # Copyright (c) 2008-2011,2013 Wind River Systems, Inc.
33 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the Lesser GNU General Public License version 2.1 as
6 # published by the Free Software Foundation.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # See the Lesser GNU General Public License for more details.
12 #
13 # You should have received a copy of the Lesser GNU General Public License
14 # version 2.1 along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4 # SPDX-License-Identifier: LGPL-2.1-only
165 #
176 """convert wrapfuncs.in to wrapper function stubs and tables"""
187
274263 self.specific_dirfds[arg.name[:-5]] = True
275264 self.dirfd = 'dirfd'
276265 elif arg.name == 'flags':
277 self.flags = 'flags'
266 self.flags = '(flags & AT_SYMLINK_NOFOLLOW)'
278267 elif arg.name.endswith('path'):
279268 self.paths_to_munge.append(arg.name)
280269
323312
324313 def maybe_async_skip(self):
325314 if self.async_skip:
326 return """/* This function is not called if pseudo is configured --enable-force-async */
315 return """/* This function is not called if pseudo is configured --enable-force-async */
327316 #ifdef PSEUDO_FORCE_ASYNC
328317 if (!pseudo_allow_fsync) {
329318 PROFILE_DONE;
332321 #endif
333322 """ % self.async_skip
334323 else:
335 return ""
324 return ""
336325
337326 def comment(self):
338327 """declare self (in a comment)"""
392381
393382 def rc_format(self):
394383 """the format string to use for the return value"""
395 return typedata.get(self.type, { 'format': '[%s]', 'value': '"' + self.type + '"' })['format']
384 return typedata.get(self.type, { 'format': '[%s]', 'value': '"' + self.type + '"' })['format']
396385
397386 def rc_value(self):
398387 """the value to pass for the format string for the return value"""
399 return typedata.get(self.type, { 'format': '[%s]', 'value': '"' + self.type + '"' })['value']
388 return typedata.get(self.type, { 'format': '[%s]', 'value': '"' + self.type + '"' })['value']
400389
401390 def rc_decl(self):
402391 """declare rc (if needed)"""
452441 """
453442
454443 def __init__(self, port, sources):
444 if type(port) is not str:
445 port = str(port, encoding="ascii")
455446 self.name = port
456447 self.subports = []
457448 self.preports = []
458 print port
449 print(port)
459450
460451 if os.path.exists(self.portfile("pseudo_wrappers.c")):
461452 self.wrappers = self.portfile("pseudo_wrappers.c")
482473 if retcode:
483474 raise Exception("preports script failed for port %s" % self.name)
484475
485 for preport in string.split(portlist):
476 for preport in portlist.split():
486477 next = Port(preport, sources)
487478 self.preports.append(next)
488479
493484 if retcode:
494485 raise Exception("subports script failed for port %s" % self.name)
495486
496 for subport in string.split(portlist):
487 for subport in portlist.split():
497488 next = Port(subport, sources)
498489 self.subports.append(next)
499490
503494 prefuncs = pre.functions()
504495 for name in prefuncs.keys():
505496 if name in mergedfuncs:
506 print "Warning: %s from %s overriding %s" % (name, pre.name, mergedfuncs[name].port)
497 print("Warning: %s from %s overriding %s" % (name, pre.name, mergedfuncs[name].port))
507498 mergedfuncs[name] = prefuncs[name]
508499 for name in self.funcs.keys():
509500 if name in mergedfuncs:
510 print "Warning: %s from %s overriding %s" % (name, self.name, mergedfuncs[name].port)
501 print("Warning: %s from %s overriding %s" % (name, self.name, mergedfuncs[name].port))
511502 mergedfuncs[name] = self.funcs[name]
512503 for sub in self.subports:
513504 subfuncs = sub.functions()
514505 for name in subfuncs.keys():
515506 if name in mergedfuncs:
516 print "Warning: %s from %s overriding %s" % (name, sub.name, mergedfuncs[name].port)
507 print("Warning: %s from %s overriding %s" % (name, sub.name, mergedfuncs[name].port))
517508 mergedfuncs[name] = subfuncs[name]
518509 return mergedfuncs
519510
520511 def define(self):
521 return '#define PSEUDO_PORT_%s 1' % string.upper(self.name).replace('/', '_')
512 return '#define PSEUDO_PORT_%s 1' % self.name.upper().replace('/', '_')
522513
523514 def portdeps(self):
524 deps = []
525 if self.wrappers:
526 deps.append(self.wrappers)
527 if self.portdef_file:
528 deps.append(self.portdef_file)
515 deps = []
516 if self.wrappers:
517 deps.append(self.wrappers)
518 if self.portdef_file:
519 deps.append(self.portdef_file)
529520 if deps:
530521 return 'pseudo_wrappers.o: %s' % ' '.join(deps)
531522 else:
575566 func.directory = directory
576567 funcs[func.name] = func
577568 sys.stdout.write(".")
578 except Exception, e:
579 print "Parsing failed:", e
569 except Exception(e):
570 print("Parsing failed:", e)
580571 exit(1)
581572 funclist.close()
582 print ""
573 print("")
583574 return funcs
584575
585576 def main(argv):
589580
590581 for arg in argv:
591582 name, value = arg.split('=')
592 os.environ["port_" + name] = value
583 os.environ["port_" + name] = value
593584
594585 # error checking helpfully provided by the exception handler
595586 copyright_file = open('guts/COPYRIGHT')
598589
599590 for path in glob.glob('templates/*'):
600591 try:
601 print "Considering template: " + path
592 print("Considering template: " + path)
602593 source = TemplateFile(path)
603 if source.name.endswith('.c') or source.name.endswith('.h'):
594 if source.name.endswith('.c') or source.name.endswith('.h'):
604595 source.emit('copyright')
605596 source.emit('header')
606597 sources.append(source)
607598 except IOError:
608 print "Invalid or malformed template %s. Aborting." % path
599 print("Invalid or malformed template %s. Aborting." % path)
609600 exit(1)
610601
611602 try:
612603 port = Port('common', sources)
613604
614605 except KeyError:
615 print "Unknown uname -s result: '%s'." % uname_s
616 print "Known system types are:"
617 print "%-20s %-10s %s" % ("uname -s", "port name", "description")
606 print("Unknown uname -s result: '%s'." % uname_s)
607 print("Known system types are:")
608 print("%-20s %-10s %s" % ("uname -s", "port name", "description"))
618609 for key in host_ports:
619 print "%-20s %-10s %s" % (key, host_ports[key],
620 host_descrs[host_ports[key]])
610 print("%-20s %-10s %s" % (key, host_ports[key],
611 host_descrs[host_ports[key]]))
621612
622613 # the per-function stuff
623 print "Writing functions...",
614 print("Writing functions...")
624615 all_funcs = port.functions()
625616 for name in sorted(all_funcs.keys()):
626617 # populate various tables and files with each function
627618 for source in sources:
628619 source.emit('body', all_funcs[name])
629 print "done. Cleaning up."
620 print("done. Cleaning up.")
630621
631622 for source in sources:
632623 # clean up files
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #ifndef _LARGEFILE64_SOURCE
00 #!/bin/sh
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
4
15 # do a quick performance test of pseudo
26 opt_f=false
37 flag_f=
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int execl(const char *file, const char *arg, va_list ap)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int execle(const char *file, const char *arg, va_list ap)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int execlp(const char *file, const char *arg, va_list ap)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_execv(const char *file, char *const *argv) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_execve(const char *file, char *const *argv, char *const *envp) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_execvp(const char *file, char *const *argv) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fork(void) {
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
4
05 /* these aren't used, but the wrapper table isn't happy unless they
16 * exist
27 */
00 #!/bin/sh
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
4
15 case $(uname -s) in
26 Linux) echo "linux";;
37 Darwin) echo "darwin";;
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems, Inc.
22 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the Lesser GNU General Public License version 2.1 as
5 * published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 * See the Lesser GNU General Public License for more details.
11 *
12 * You should have received a copy of the Lesser GNU General Public License
13 * version 2.1 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3 * SPDX-License-Identifier: LGPL-2.1-only
154 *
165 */
00 /*
11 * Copyright (c) 2011, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fcntl(int fd, int cmd, ... { struct flock *lock })
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fgetgrent_r(FILE *fp, struct group*gbuf, char *buf, size_t buflen, struct group **gbufp)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size, u_int32_t position, int options)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t flistxattr(int filedes, char *list, size_t size, int options)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fremovexattr(int filedes, const char *name, int options)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fsetxattr(int filedes, const char *name, const void *value, size_t size, u_int32_t position, int options)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fstat(int fd, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgrouplist(const char *name, int basegid, int *groups, int *ngroups) {
810
911 int found = 0;
1012 int found_group = 0;
11 char buf[PSEUDO_PWD_MAX];
12 struct group grp, *gbuf = &grp;
13 size_t buflen = PSEUDO_PWD_MAX;
14 char *buf = NULL;
15 struct group grp;
1316
14 setgrent();
15 while ((rc = wrap_getgrent_r(gbuf, buf, PSEUDO_PWD_MAX, &gbuf)) == 0) {
16 int i = 0;
17 for (i = 0; gbuf->gr_mem[i]; ++i) {
18 if (!strcmp(gbuf->gr_mem[i], name)) {
19 if (found < *ngroups)
20 groups[found] = gbuf->gr_gid;
21 ++found;
22 if ((int) gbuf->gr_gid == basegid)
23 found_group = 1;
17 rc = ERANGE;
18
19 do {
20 struct group *gbuf = &grp;
21 char *new_buf = buf;
22
23 if (rc == ERANGE)
24 new_buf = realloc(buf, buflen);
25
26 if (!new_buf) {
27 rc = ENOMEM;
28 break;
29 }
30
31 buf = new_buf;
32
33 found = 0;
34 found_group = 0;
35 setgrent();
36 while ((rc = wrap_getgrent_r(gbuf, buf, buflen, &gbuf)) == 0) {
37 int i = 0;
38 for (i = 0; gbuf->gr_mem[i]; ++i) {
39 if (!strcmp(gbuf->gr_mem[i], name)) {
40 if (found < *ngroups)
41 groups[found] = gbuf->gr_gid;
42 ++found;
43 if ((int) gbuf->gr_gid == basegid)
44 found_group = 1;
45 }
2446 }
2547 }
26 }
27 endgrent();
48 endgrent();
49
50 if (rc == ERANGE)
51 buflen = buflen << 1;
52 } while (rc == ERANGE);
53 free(buf);
2854 if (!found_group) {
2955 if (found < *ngroups)
3056 groups[found] = basegid;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgroups(int size, gid_t *list) {
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t getxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t listxattr(const char *path, char *list, size_t size, int options)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lstat(const char *path, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011-2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int open(const char *path, int flags, ... { int mode })
57 * int rc = -1;
1113
1214 /* mask out mode bits appropriately */
1315 mode = mode & ~pseudo_umask;
14 #ifdef PSEUDO_FORCE_ASYNCH
16 #ifdef PSEUDO_FORCE_ASYNC
1517 flags &= ~O_SYNC;
1618 #endif
1719
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int removexattr(const char *path, const char *name, int options)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_scandir(const char *path, struct dirent ***namelist, int (*filter)(struct dirent *), int (*compar)(const void *, const void *)) {
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int setxattr(const char *path, const char *name, const void *value, size_t size, u_int32_t position, int options)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int stat(const char *path, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int sync_file_range(int fd, off_t offset, off_t nbytes, unsigned int flags)
57 * int rc = -1;
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 #define PRELINK_LIBRARIES "DYLD_INSERT_LIBRARIES"
15 #define PRELINK_PATH "DYLD_LIBRARY_PATH"
26 #define PSEUDO_STATBUF_64 0
22 *
33 * Copyright (c) 2008-2011 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 /* we need XATTR_NOFOLLOW in scope */
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems, Inc.
22 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the Lesser GNU General Public License version 2.1 as
5 * published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 * See the Lesser GNU General Public License for more details.
11 *
12 * You should have received a copy of the Lesser GNU General Public License
13 * version 2.1 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3 * SPDX-License-Identifier: LGPL-2.1-only
154 *
165 */
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int
57 * wrap___fxstat(int ver, int fd, struct stat *buf) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int
57 * wrap___fxstat64(int ver, int fd, struct stat64 *buf) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___fxstatat64(int ver, int dirfd, const char *path, struct stat64 *buf, int flags) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___lxstat(int ver, const char *path, struct stat *buf) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___lxstat64(int ver, const char *path, struct stat64 *buf) {
00 /*
11 * Copyright (c) 2008-2010,2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___openat64_2(int dirfd, const char *path, int flags) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___openat_2(int dirfd, const char *path, int flags) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___xmknod(int ver, const char *path, mode_t mode, dev_t *dev) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___xmknodat(int ver, int dirfd, const char *path, mode_t mode, dev_t *dev) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___xstat(int ver, const char *path, struct stat *buf) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap___xstat64(int ver, const char *path, struct stat64 *buf) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_canonicalize_file_name(const char *filename) {
0 /*
1 * Copyright (c) 2016 Wind River Systems; see
2 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 * int capset(cap_user_header_t hdrp, const cap_user_data_t datap)
7 * int rc = -1;
8 */
9
10 rc = real_capset(hdrp, datap);
11
12 /* return rc;
13 * }
14 */
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_creat64(const char *path, ...mode_t mode) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_eaccess(const char *path, int mode) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_euidaccess(const char *path, int mode) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fcntl(int fd, int cmd, ...struct flock *lock) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static FILE *
57 * wrap_fopen64(const char *path, const char *mode) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static FILE *
57 * wrap_freopen64(const char *path, const char *mode, FILE *stream) {
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fstat(int fd, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fstat64(int fd, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_ftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int), int nopenfd) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_get_current_dir_name(void) {
00 /*
11 * Copyright (c) 2010-2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) {
810
911 int found = 0;
1012 int found_group = 0;
11 char buf[PSEUDO_PWD_MAX];
12 struct group grp, *gbuf = &grp;
13 size_t buflen = PSEUDO_PWD_MAX;
14 char *buf = NULL;
15 struct group grp;
1316
14 setgrent();
15 while ((rc = wrap_getgrent_r(gbuf, buf, PSEUDO_PWD_MAX, &gbuf)) == 0) {
16 int i = 0;
17 for (i = 0; gbuf->gr_mem[i]; ++i) {
18 if (!strcmp(gbuf->gr_mem[i], user)) {
19 if (found < *ngroups)
20 groups[found] = gbuf->gr_gid;
21 ++found;
22 if (gbuf->gr_gid == group)
23 found_group = 1;
17 rc = ERANGE;
18
19 do {
20 struct group *gbuf = &grp;
21 char *new_buf = buf;
22
23 if (rc == ERANGE)
24 new_buf = realloc(buf, buflen);
25
26 if (!new_buf) {
27 rc = ENOMEM;
28 break;
29 }
30
31 buf = new_buf;
32
33 found = 0;
34 found_group = 0;
35 setgrent();
36 while ((rc = wrap_getgrent_r(gbuf, buf, buflen, &gbuf)) == 0) {
37 int i = 0;
38 for (i = 0; gbuf->gr_mem[i]; ++i) {
39 if (!strcmp(gbuf->gr_mem[i], user)) {
40 if (found < *ngroups)
41 groups[found] = gbuf->gr_gid;
42 ++found;
43 if (gbuf->gr_gid == group)
44 found_group = 1;
45 }
2446 }
2547 }
26 }
27 endgrent();
48 endgrent();
49
50 if (rc == ERANGE)
51 buflen = buflen << 1;
52 } while (rc == ERANGE);
53 free(buf);
2854 if (!found_group) {
2955 if (found < *ngroups)
3056 groups[found] = group;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgroups(int size, gid_t *list) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getpw(uid_t uid, char *buf) {
00 /*
11 * Copyright (c) 2010-2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_glob64(const char *pattern, int flags, int (*errfunc)(const char *, int), glob64_t *pglob) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_lchown(const char *path, uid_t owner, gid_t group) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_lckpwdf(void) {
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lstat(const char *path, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lstat64(const char *path, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2016 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int mknod(const char *path, mode_t mode, dev_t dev)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2016 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_mkstemp64(char *template) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_nftw64(const char *path, int (*fn)(const char *, const struct stat64 *, int, struct FTW *), int nopenfd, int flag) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_open(const char *path, int flags, ...mode_t mode) {
00 /*
11 * Copyright (c) 2008-2010,2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_open64(const char *path, int flags, ...mode_t mode) {
00 /*
11 * Copyright (c) 2008-2010, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_openat(int dirfd, const char *path, int flags, ...mode_t mode) {
68 * int rc = -1;
79 */
810 struct stat64 buf;
11 int overly_magic_nonblocking = 0;
912 int existed = 1;
1013 int save_errno;
14 sigset_t local_saved_sigmask;
1115
1216 /* mask out mode bits appropriately */
1317 mode = mode & ~pseudo_umask;
1923 }
2024 #endif
2125
22 #ifdef PSEUDO_FORCE_ASYNCH
26 #ifdef PSEUDO_FORCE_ASYNC
2327 /* Yes, I'm aware that every Linux system I've seen has
2428 * DSYNC and RSYNC being the same value as SYNC.
2529 */
3741 );
3842 #endif
3943
44 #ifdef O_TMPFILE
45 /* don't handle O_CREAT the same way if O_TMPFILE exists
46 * and is set.
47 */
48 if ((flags & O_TMPFILE) == O_TMPFILE) {
49 existed = 0;
50 } else
51 #endif
4052 /* if a creation has been requested, check whether file exists */
53 /* note "else" in #ifdef O_TMPFILE above */
4154 if (flags & O_CREAT) {
4255 save_errno = errno;
4356 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
5164 errno = save_errno;
5265 }
5366
67 /* if a pipe is opened without O_NONBLOCK, for only reading or
68 * only writing, it can block forever. We need to do extra magic
69 * in that case...
70 */
71 if (!(flags & O_NONBLOCK) && ((flags & (O_WRONLY | O_RDONLY | O_RDWR)) != O_RDWR)) {
72 save_errno = errno;
73 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
74 rc = real___xstat64(_STAT_VER, path, &buf);
75 #else
76 rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0);
77 #endif
78 if (rc != -1 && S_ISFIFO(buf.st_mode)) {
79 overly_magic_nonblocking = 1;
80 }
81 }
82
83 /* this is a horrible special case and i do not know whether it will work */
84 if (overly_magic_nonblocking) {
85 pseudo_droplock();
86 sigprocmask(SIG_SETMASK, &pseudo_saved_sigmask, &local_saved_sigmask);
87 }
5488 /* because we are not actually root, secretly mask in 0600 to the
5589 * underlying mode. The ", 0" is because the only time mode matters
5690 * is if a file is going to be created, in which case it's
6195 #else
6296 rc = real_openat(dirfd, path, flags, PSEUDO_FS_MODE(mode, 0));
6397 #endif
64 save_errno = errno;
98 if (overly_magic_nonblocking) {
99 save_errno = errno;
100 sigprocmask(SIG_SETMASK, &local_saved_sigmask, NULL);
101 /* well this is a problem. we can't NOT proceed; we may have
102 * already opened the file! we can't even return up the call
103 * stack to stuff that's going to try to drop the lock.
104 */
105 if (pseudo_getlock()) {
106 pseudo_diag("PANIC: after opening a readonly/writeonly FIFO (path '%s', fd %d, errno %d, saved errno %d), could not regain lock. unrecoverable. sorry. bye.\n",
107 path, rc, errno, save_errno);
108 abort();
109 }
110 errno = save_errno;
111 }
65112
66113 if (rc != -1) {
114 save_errno = errno;
67115 int stat_rc;
116 #ifdef O_TMPFILE
117 /* in O_TMPFILE case, nothing gets put in the
118 * database, because there's no directory entries for
119 * the file yet.
120 */
121 if ((flags & O_TMPFILE) == O_TMPFILE) {
122 real_fchmod(rc, PSEUDO_FS_MODE(mode, 0));
123 errno = save_errno;
124 return rc;
125 }
126 #endif
68127 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
69128 stat_rc = real___xstat64(_STAT_VER, path, &buf);
70129 #else
75134 buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode);
76135 if (!existed) {
77136 real_fchmod(rc, PSEUDO_FS_MODE(mode, 0));
137 // file has no path, but has been created
78138 pseudo_client_op(OP_CREAT, 0, -1, dirfd, path, &buf);
79139 }
80 pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, &buf);
140 pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, dirfd, path, &buf);
81141 } else {
82142 pseudo_debug(PDBGF_FILE, "openat (fd %d, path %d/%s, flags %d) succeeded, but stat failed (%s).\n",
83143 rc, dirfd, path, flags, strerror(errno));
00 /*
11 * Copyright (c) 2008-2010,2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_openat64(int dirfd, const char *path, int flags, ...mode_t mode) {
0 /*
1 * Copyright (c) 2019 Peter Seebach/Seebs <seebs@seebs.net>; see
2 * guts/COPYRIGHT for information.
3 *
4 * [Note: copyright added by code generator, may be
5 * incorrect. Remove this if you fix it.]
6 *
7 * SPDX-License-Identifier: LGPL-2.1-only
8 *
9 * int renameat2(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags)
10 * int rc = -1;
11 */
12
13 (void) olddirfd;
14 (void) oldpath;
15 (void) newdirfd;
16 (void) newpath;
17 (void) flags;
18 /* for now, let's try just failing out hard, and hope things retry with a
19 * different syscall.
20 */
21 errno = ENOSYS;
22 rc = -1;
23
24 /* return rc;
25 * }
26 */
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_scandir(const char *path, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const void *, const void *)) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_scandir64(const char *path, struct dirent64 ***namelist, int (*filter)(const struct dirent64 *), int (*compar)(const void *, const void *)) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setfsgid(gid_t fsgid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setfsuid(uid_t fsuid) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setgroups(size_t size, const gid_t *list) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setresgid(gid_t rgid, gid_t egid, gid_t sgid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) {
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int stat(const char *path, struct stat *buf)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int stat64(const char *path, struct stat *buf)
57 * int rc = -1;
0 /*
1 * Copyright (c) 2018 Wind River Systems; see
2 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 * long syscall(long nr)
7 * long rc = -1;
8 */
9
10 /* we should never get here, syscall is hand-wrapped */
11 rc = -1;
12 errno = ENOTSUPP;
13
14 /* return rc;
15 * }
16 */
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_truncate64(const char *path, off64_t length) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_ulckpwdf(void) {
00 /*
11 * Copyright (c) 2008-2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * clone(...) {
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
4
05 static int
16 wrap_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, va_list
27 ap) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t flistxattr(int filedes, char *list, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fremovexattr(int filedes, const char *name)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t lgetxattr(const char *pathname, const char *name, void *value, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t listxattr(const char *pathname, char *list, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t llistxattr(const char *pathname, char *list, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lremovexattr(const char *pathname, const char *name)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lsetxattr(const char *pathname, const char *name, const void *value, size_t size, int flags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int removexattr(const char *pathname, const char *name)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2008-2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * clone(...) {
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 static int
15 wrap_clone(int (*fn)(void *), void *child_stack, int flags, void *arg) {
26 /* unused */
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 #define PRELINK_LIBRARIES "LD_PRELOAD"
15 #define PRELINK_PATH "LD_LIBRARY_PATH"
26 #define PSEUDO_STATBUF_64 1
1923 */
2024 #define GLIBC_COMPAT_SYMBOL(sym, ver) __asm(".symver " #sym "," #sym "@GLIBC_" #ver)
2125
22 #ifdef __amd64__
26 #if defined(__amd64__) && !defined(__ILP32__)
2327 GLIBC_COMPAT_SYMBOL(memcpy,2.2.5);
2428 #elif defined(__i386__)
2529 GLIBC_COMPAT_SYMBOL(memcpy,2.0);
2630 #endif
31
32 #include <linux/capability.h>
33 #include <sys/syscall.h>
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 /* the unix port wants to know that real_stat() and
15 * friends exist. So they do. And because the Linux
26 * port really uses stat64 for those...
4145 pseudo_mknodat(int dirfd, const char *path, mode_t mode, dev_t dev) {
4246 return real___xmknodat(_MKNOD_VER, dirfd, path, mode, &dev);
4347 }
48
49 int pseudo_capset(cap_user_header_t hdrp, const cap_user_data_t datap) {
50 (void)hdrp;
51 (void)datap;
52
53 return 0;
54 }
55
56 long
57 syscall(long number, ...) {
58 long rc = -1;
59
60 if (!pseudo_check_wrappers() || !real_syscall) {
61 /* rc was initialized to the "failure" value */
62 pseudo_enosys("syscall");
63 return rc;
64 }
65
66 #ifdef SYS_renameat2
67 /* concerns exist about trying to parse arguments because syscall(2)
68 * specifies strange ABI behaviors. If we can get better clarity on
69 * that, it could make sense to redirect to wrap_renameat2().
70 */
71 if (number == SYS_renameat2) {
72 errno = ENOSYS;
73 return -1;
74 }
75 #else
76 (void) number;
77 #endif
78
79 /* gcc magic to attempt to just pass these args to syscall. we have to
80 * guess about the number of args; the docs discuss calling conventions
81 * up to 7, so let's try that?
82 */
83 void *res = __builtin_apply((void (*)()) real_syscall, __builtin_apply_args(), sizeof(long) * 7);
84 __builtin_return(res);
85 }
86
87 /* unused.
88 */
89 static long wrap_syscall(long nr, va_list ap) {
90 (void) nr;
91 (void) ap;
92 return -1;
93 }
0 /*
1 * Copyright (c) 2018 Wind River Systems; see
2 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 * int statvfs(const char *path, struct statvfs *buf)
7 * int rc = -1;
8 */
9
10 rc = real_statvfs(path, buf);
11
12 /* return rc;
13 * }
14 */
0 int statvfs(const char *path, struct statvfs *buf);
4040 echo "linux/noxattr"
4141 fi
4242 rm -f dummy.c dummy.o
43
44 cat > dummy.c <<EOF
45 #include <sys/statvfs.h>
46 int i;
47 EOF
48 if ! ${CC} -c -o dummy.o dummy.c >/dev/null 2>&1; then
49 echo >&2 "Warning: Can't compile trivial program using <sys/statvfs.h>".
50 echo >&2 " xattr support will require that header."
51 else
52 echo "linux/statvfs"
53 fi
54 rm -f dummy.c dummy.o
55
44 int __fxstat(int ver, int fd, struct stat *buf);
55 int lchown(const char *path, uid_t owner, gid_t group); /* flags=AT_SYMLINK_NOFOLLOW */
66 int __fxstatat(int ver, int dirfd, const char *path, struct stat *buf, int flags);
7 int openat(int dirfd, const char *path, int flags, ...{mode_t mode});
8 int __openat_2(int dirfd, const char *path, int flags);
7 int openat(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=0 */
8 int __openat_2(int dirfd, const char *path, int flags); /* flags=0 */
99 int mknod(const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknod */
1010 int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* real_func=pseudo_mknodat */
1111 int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev); /* flags=AT_SYMLINK_NOFOLLOW */
5252 int getpw(uid_t uid, char *buf);
5353 int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);
5454 int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp);
55 int capset(cap_user_header_t hdrp, const cap_user_data_t datap); /* real_func=pseudo_capset */
56 long syscall(long nr, ...); /* hand_wrapped=1 */
57 int renameat2(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags); /* flags=AT_SYMLINK_NOFOLLOW */
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t flistxattr(int filedes, char *list, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fremovexattr(int filedes, const char *name)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fsetxattr(int filedes, const char *name, const void *value, size_t size, int xflags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t getxattr(const char *path, const char *name, void *value, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t listxattr(const char *path, char *list, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * ssize_t llistxattr(const char *path, char *list, size_t size)
57 * ssize_t rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lremovexattr(const char *path, const char *name)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lsetxattr(const char *path, const char *name, const void *value, size_t size, int xflags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int removexattr(const char *path, const char *name)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int setxattr(const char *path, const char *name, const void *value, size_t size, int xflags)
57 * int rc = -1;
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 #include <attr/xattr.h>
15 #include <stdint.h>
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 /* shared functionality for the xattr code */
15 /* Each of these functions is expecting to get an optional name, and
26 * a populated statbuf to use for sending messages to the server.
6165 posix_permissions(const acl_header *header, int entries, int *extra, int *mode) {
6266 int acl_seen = 0;
6367 if (le32(header->version) != 2) {
64 pseudo_diag("Fatal: ACL support no available for header version %d.\n",
68 pseudo_diag("Fatal: ACL support not available for header version %d.\n",
6569 le32(header->version));
66 return 1;
70 return -1;
6771 }
6872 *mode = 0;
6973 *extra = 0;
96100 return 0;
97101 }
98102
103 static int get_special_bits(const char *path, int fd) {
104 int rc;
105 struct stat64 buf;
106 if (path) {
107 rc = lstat64(path, &buf);
108 } else {
109 rc = fstat64(fd, &buf);
110 }
111 if (rc == -1) {
112 return rc;
113 }
114
115 return buf.st_mode & (S_ISUID | S_ISGID | S_ISVTX);
116 }
117
99118 #define RC_AND_BUF \
100119 int rc; \
101120 PSEUDO_STATBUF buf; \
139158 pseudo_debug(PDBGF_XATTR, "setxattr(%s [fd %d], %s => '%.*s')\n",
140159 path ? path : "<no path>", fd, name, (int) size, (char *) value);
141160
161 /* Filter out erroneous sizes for POSIX ACL
162 * see posix_acl_xattr_count in include/linux/posix_acl_xattr.h of Linux source code */
163 /* I don't think there's any posix_acl_* values that aren't in this format */
164 if (!strncmp(name, "system.posix_acl_", 17)) {
165 // ACL is corrupt, issue an error
166 if(size < sizeof(acl_header) || (size - sizeof(acl_header)) % sizeof(acl_entry) != 0) {
167 pseudo_debug(PDBGF_XATTR, "invalid data size for %s: %d\n",
168 name, (int) size);
169 errno = EINVAL;
170 return -1;
171 }
172
173 // ACL is empty, do nothing
174 if((size - sizeof(acl_header)) / sizeof(acl_entry) == 0) {
175 /* on some systems, "cp -a" will attempt to clone the
176 * posix_acl_default entry for a directory (which would specify
177 * default ACLs for new files in that directory), but if the
178 * original was empty, we get a header but no entries. With
179 * real xattr, that ends up being silently discarded, apparently,
180 * so we discard it too.
181 */
182 pseudo_debug(PDBGF_XATTR, "0-length ACL entry %s.\n", name);
183 return 0;
184 }
185 }
142186 /* this may be a plain chmod */
143187 if (!strcmp(name, "system.posix_acl_access")) {
144188 int extra;
145189 int mode;
146190 int entries = (size - sizeof(acl_header)) / sizeof(acl_entry);
147 if (!posix_permissions(value, entries, &extra, &mode)) {
191 int res = posix_permissions(value, entries, &extra, &mode);
192 if (res == 0) {
193 /* POSIX ACLs don't actually include
194 * setuid/setgid/sticky bit. We need to add those back
195 * in ourselves. */
196 mode |= get_special_bits(path, fd);
148197 pseudo_debug(PDBGF_XATTR, "posix_acl_access translated to mode %04o. Remaining attribute(s): %d.\n",
149198 mode, extra);
150199 buf.st_mode = mode;
163212 if (!extra) {
164213 return 0;
165214 }
166 }
167 }
215 } else if (res == -1) {
216 errno = EOPNOTSUPP;
217 return -1;
218 }
219 }
220
168221 if (!strcmp(name, "user.pseudo_data")) {
169222 pseudo_debug(PDBGF_XATTR | PDBGF_XATTRDB, "user.pseudo_data xattribute does not get to go in database.\n");
170223 return -1;
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems, Inc.
22 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the Lesser GNU General Public License version 2.1 as
5 * published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 * See the Lesser GNU General Public License for more details.
11 *
12 * You should have received a copy of the Lesser GNU General Public License
13 * version 2.1 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3 * SPDX-License-Identifier: LGPL-2.1-only
154 *
165 */
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static void
57 * wrap_endgrent(void) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static void
57 * wrap_endpwent(void) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static gid_t
57 * wrap_getegid(void) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static uid_t
57 * wrap_geteuid(void) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static gid_t
57 * wrap_getgid(void) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static struct group *
57 * wrap_getgrent(void) {
68 * struct group * rc = NULL;
79 */
810 static struct group grp;
9 static char grbuf[PSEUDO_PWD_MAX];
10 int r_rc;
11 static size_t grbuflen = PSEUDO_PWD_MAX;
12 static char *grbuf = NULL;
13 int r_rc = ERANGE;
1114
12 r_rc = wrap_getgrent_r(&grp, grbuf, PSEUDO_PWD_MAX, &rc);
15 do {
16 char *new_grbuf = grbuf;
17
18 if (r_rc == ERANGE)
19 new_grbuf = realloc(grbuf, grbuflen);
20
21 if (!new_grbuf) {
22 r_rc = ENOMEM;
23 break;
24 }
25
26 grbuf = new_grbuf;
27
28 r_rc = wrap_getgrent_r(&grp, grbuf, grbuflen, &rc);
29
30 if (r_rc == ERANGE)
31 grbuflen = grbuflen << 1;
32
33 } while (r_rc == ERANGE);
34
1335 /* different error return conventions */
1436 if (r_rc != 0) {
1537 errno = r_rc;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static struct group *
57 * wrap_getgrgid(gid_t gid) {
68 * struct group * rc = NULL;
79 */
810 static struct group grp;
9 static char grbuf[PSEUDO_PWD_MAX];
10 int r_rc;
11 static size_t grbuflen = PSEUDO_PWD_MAX;
12 static char *grbuf = NULL;
13 int r_rc = ERANGE;
1114
12 r_rc = wrap_getgrgid_r(gid, &grp, grbuf, PSEUDO_PWD_MAX, &rc);
15 do {
16 char *new_grbuf = grbuf;
17
18 if (r_rc == ERANGE)
19 new_grbuf = realloc(grbuf, grbuflen);
20
21 if (!new_grbuf) {
22 r_rc = ENOMEM;
23 break;
24 }
25
26 grbuf = new_grbuf;
27
28 r_rc = wrap_getgrgid_r(gid, &grp, grbuf, grbuflen, &rc);
29
30 if (r_rc == ERANGE)
31 grbuflen = grbuflen << 1;
32
33 } while (r_rc == ERANGE);
34
1335 /* different error return conventions */
1436 if (r_rc != 0) {
1537 errno = r_rc;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgrgid_r(gid_t gid, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static struct group *
57 * wrap_getgrnam(const char *name) {
79 */
810
911 static struct group grp;
10 static char grbuf[PSEUDO_PWD_MAX];
11 int r_rc;
12 static size_t grbufsz = PSEUDO_PWD_MAX;
13 static char *grbuf = NULL;
14 int r_rc = ERANGE;
1215
13 r_rc = wrap_getgrnam_r(name, &grp, grbuf, PSEUDO_PWD_MAX, &rc);
16 do {
17 char *new_grbuf = grbuf;
18
19 if (r_rc != 0)
20 new_grbuf = realloc(grbuf, grbufsz);
21
22 if (!new_grbuf) {
23 r_rc = ENOMEM;
24 break;
25 }
26
27 grbuf = new_grbuf;
28
29 r_rc = wrap_getgrnam_r(name, &grp, grbuf, grbufsz, &rc);
30
31 if (r_rc == ERANGE)
32 grbufsz = grbufsz << 1;
33 } while (r_rc == ERANGE);
34
1435 /* different error return conventions */
1536 if (r_rc != 0) {
1637 errno = r_rc;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getgrnam_r(const char *name, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static struct passwd *
57 * wrap_getpwent(void) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static struct passwd *
57 * wrap_getpwnam(const char *name) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static struct passwd *
57 * wrap_getpwuid(uid_t uid) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static uid_t
57 * wrap_getuid(void) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setegid(gid_t egid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_seteuid(uid_t euid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setgid(gid_t gid) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static void
57 * wrap_setgrent(void) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static void
57 * wrap_setpwent(void) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setregid(gid_t rgid, gid_t egid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setreuid(uid_t ruid, uid_t euid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_setuid(uid_t uid) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems, Inc.
22 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the Lesser GNU General Public License version 2.1 as
5 * published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 * See the Lesser GNU General Public License for more details.
11 *
12 * You should have received a copy of the Lesser GNU General Public License
13 * version 2.1 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3 * SPDX-License-Identifier: LGPL-2.1-only
154 *
165 */
00 /*
11 * Copyright (c) 2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_access(const char *path, int mode) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_acct(const char *path) {
00 /*
11 * Copyright (c) 2016 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_chdir(const char *path) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_chmod(const char *path, mode_t mode) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_chown(const char *path, uid_t owner, gid_t group) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_chroot(const char *path) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_close(int fd) {
00 /*
11 * Copyright (c) 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_closedir(DIR *dirp) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_creat(const char *path, mode_t mode) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_dup(int fd) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_dup2(int oldfd, int newfd) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fchdir(int dirfd) {
00 /*
11 * Copyright (c) 2008-2010, 2012, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fchmod(int fd, mode_t mode) {
00 /*
11 * Copyright (c) 2008-2010, 2012, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fchmodat(int dirfd, const char *path, mode_t mode, int flags) {
00 /*
11 * Copyright (c) 2008-2010, 2012, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fchown(int fd, uid_t owner, gid_t group) {
00 /*
11 * Copyright (c) 2008-2010, 2012, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_fclose(FILE *fp) {
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fdatasync(int fd)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static FILE *
57 * wrap_fopen(const char *path, const char *mode) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static FILE *
57 * wrap_freopen(const char *path, const char *mode, FILE *stream) {
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int fsync(int fd)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static FTS *
57 * wrap_fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **)) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int nopenfd) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_getcwd(char *buf, size_t size) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_getwd(char *buf) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) {
00 /*
11 * Copyright (c) 2008,2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int lchown(const char *path, uid_t owner, gid_t group)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2008-2010, 2012, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_link(const char *oldname, const char *newname) {
00 /*
11 * Copyright (c) 2012, 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int linkat(int olddirfd, const char *oldname, int newdirfd, const char *newname, int flags)
57 * int rc = -1;
68 */
79
8 int rc2, rflags, save_errno;
10 int rc2 = 0, rflags, save_errno, tmpfile_fd = -1;
911 pseudo_msg_t *msg;
10 char *oldpath = NULL, *newpath = NULL;
12 const char *oldpath = NULL, *newpath = NULL;
1113 PSEUDO_STATBUF buf;
1214
13 /* This is gratuitously complicated. On Linux 2.6.18 and later,
14 * flags may contain AT_SYMLINK_FOLLOW, which implies following
15 * symlinks; otherwise, linkat() will *not* follow symlinks. FreeBSD
16 * appears to use the same semantics.
17 *
18 * So on Darwin, always pass AT_SYMLINK_FOLLOW, because the
19 * alternative doesn't work. And never pass AT_SYMLINK_NOFOLLOW
20 * because that's not a valid flag to linkat().
21 *
22 * So we need a flag for path resolution which is AT_SYMLINK_NOFOLLOW
23 * unless AT_SYMLINK_FOLLOW was specified, in which case it's 0.
24 */
25
26 rflags = (flags & AT_SYMLINK_FOLLOW) ? 0 : AT_SYMLINK_NOFOLLOW;
15 /* This is gratuitously complicated. On Linux 2.6.18 and later,
16 * flags may contain AT_SYMLINK_FOLLOW, which implies following
17 * symlinks; otherwise, linkat() will *not* follow symlinks. FreeBSD
18 * appears to use the same semantics.
19 *
20 * So on Darwin, always pass AT_SYMLINK_FOLLOW, because the
21 * alternative doesn't work. And never pass AT_SYMLINK_NOFOLLOW
22 * because that's not a valid flag to linkat().
23 *
24 * So we need a flag for path resolution which is AT_SYMLINK_NOFOLLOW
25 * unless AT_SYMLINK_FOLLOW was specified, in which case it's 0.
26 */
27
28 rflags = (flags & AT_SYMLINK_FOLLOW) ? 0 : AT_SYMLINK_NOFOLLOW;
2729
2830 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
2931 if (olddirfd != AT_FDCWD || newdirfd != AT_FDCWD) {
3133 return -1;
3234 }
3335 #endif
34 oldpath = pseudo_root_path(__func__, __LINE__, olddirfd, oldname, rflags);
35 newpath = pseudo_root_path(__func__, __LINE__, newdirfd, newname, AT_SYMLINK_NOFOLLOW);
36 rc = real_link(oldpath, newpath);
37 save_errno = errno;
38 if (rc == -1) {
39 errno = save_errno;
40 return rc;
41 }
36 oldpath = oldname;
37 if (pseudo_chroot_len && strncmp(oldpath, pseudo_chroot, pseudo_chroot_len) &&
38 oldpath[pseudo_chroot_len] == '/') {
39 oldpath += pseudo_chroot_len;
40 }
4241
43 /* if we got this far, the link succeeded, and oldpath and newpath
44 * are the newly-allocated canonical paths. If OS, filesystem, or
45 * the flags value prevent hard linking to symlinks, the resolved
46 * path should be the target's path anyway, so lstat is safe here.
47 */
48 /* find the target: */
49 rc2 = base_lstat(oldpath, &buf);
50 if (rc2 == -1) {
51 pseudo_diag("Fatal: Tried to stat '%s' after linking it, but failed: %s.\n",
52 oldpath, strerror(errno));
53 errno = ENOENT;
54 return rc;
55 }
56 msg = pseudo_client_op(OP_STAT, 0, -1, -1, oldpath, &buf);
57 if (msg && msg->result == RESULT_SUCCEED) {
58 pseudo_stat_msg(&buf, msg);
59 }
60 /* Long story short: I am pretty sure we still want OP_LINK even
61 * if the thing linked is a symlink.
62 */
63 pseudo_client_op(OP_LINK, 0, -1, -1, newpath, &buf);
42 newpath = pseudo_root_path(__func__, __LINE__, newdirfd, newname, AT_SYMLINK_NOFOLLOW);
6443
65 errno = save_errno;
44 /* weird special case: if you link /proc/self/fd/N, you're supposed
45 * to get a link to fd N. Used in conjunction with opening a directory
46 * with O_TMPFILE in flags, which actually opens an already-deleted
47 * file atomically, so there's no way to access the file *at all*
48 * unless it's linked.
49 */
50 #ifdef O_TMPFILE
51 if (!strncmp(oldpath, "/proc/self/fd/", 14) && (flags & AT_SYMLINK_FOLLOW)) {
52 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
53 /* only linkat() lets you do this horrible thing */
54 errno = ENOSYS;
55 return -1;
56 #endif
57 tmpfile_fd = atoi(oldpath + 14);
58 // call actual link
59 rc = real_linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, AT_SYMLINK_FOLLOW);
60 } else
61 #endif
62 {
63 oldpath = pseudo_root_path(__func__, __LINE__, olddirfd, oldname, rflags);
64 rc = real_link(oldpath, newpath);
65 }
66
67 save_errno = errno;
68 if (rc == -1) {
69 return rc;
70 }
71
72 /* if we got this far, the link succeeded, and oldpath and newpath
73 * are the newly-allocated canonical paths. If OS, filesystem, or
74 * the flags value prevent hard linking to symlinks, the resolved
75 * path should be the target's path anyway, so lstat is safe here.
76 */
77 /* find the target: */
78 if (tmpfile_fd != -1) {
79 rc2 = base_fstat(tmpfile_fd, &buf);
80 } else {
81 rc2 = base_lstat(oldpath, &buf);
82 }
83 if (rc2 == -1) {
84 pseudo_diag("Fatal: Tried to stat '%s' after linking it, but failed: %s.\n",
85 oldpath, strerror(errno));
86 errno = ENOENT;
87 return rc2;
88 }
89 if (tmpfile_fd != -1) {
90 /* if tmpfile_fd is set, it's *possible* but not *certain* that
91 * we're looking at a file descriptor from an O_TMPFILE open,
92 * which would not be in the database.
93 *
94 * If it's not, we want to treat this like a CREAT operation,
95 * instead of a "link".
96 */
97 msg = pseudo_client_op(OP_FSTAT, 0, tmpfile_fd, -1, 0, &buf);
98 if (!msg || msg->result != RESULT_SUCCEED) {
99 /* create it, mark it as open so we have a path recorded
100 * in the client, and return rc immediately instead
101 * of continuing on to call OP_LINK.
102 */
103 pseudo_client_op(OP_CREAT, 0, tmpfile_fd, -1, newpath, &buf);
104 pseudo_client_op(OP_OPEN, 0, tmpfile_fd, -1, newpath, &buf);
105 errno = save_errno;
106 return rc;
107 }
108 } else {
109 msg = pseudo_client_op(OP_STAT, 0, -1, -1, oldpath, &buf);
110 }
111 if (msg && msg->result == RESULT_SUCCEED) {
112 pseudo_stat_msg(&buf, msg);
113 }
114 /* Long story short: I am pretty sure we still want OP_LINK even
115 * if the thing linked is a symlink.
116 */
117 pseudo_client_op(OP_LINK, 0, -1, -1, newpath, &buf);
118
119 errno = save_errno;
66120
67121 /* return rc;
68122 * }
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_lutimes(const char *path, const struct timeval *tv) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_mkdir(const char *path, mode_t mode) {
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_mkdirat(int dirfd, const char *path, mode_t mode) {
00 /*
11 * Copyright (c) 2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_mkdtemp(char *template) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_mkfifo(const char *path, mode_t mode) {
00 /*
11 * Copyright (c) 2015 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_mkfifoat(int dirfd, const char *path, mode_t mode) {
00 /*
11 * Copyright (c) 2011,2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int mknod(const char *path, mode_t mode, dev_t dev)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev)
57 * int rc = -1;
0 /*
1 * Copyright (c) 2018 Wind River Systems; see
2 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 * int mkostemp(char *template, int oflags)
7 * int rc = -1;
8 */
9
10 /* mkostemp = mkostemps() with suffixlen of 0 */
11 rc = wrap_mkostemps(template, 0, oflags);
12
13 /* return rc;
14 * }
15 */
0 /*
1 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
2 * guts/COPYRIGHT for information.
3 *
4 * Copyright (c) 2018 Peter Seebach; see
5 * guts/COPYRIGHT for information.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-only
8 *
9 * int mkostemps(char *template, int suffixlen, int oflags)
10 * int rc = -1;
11 */
12
13 PSEUDO_STATBUF buf;
14 int save_errno;
15 size_t len;
16 char *tmp_template;
17
18 if (!template) {
19 errno = EFAULT;
20 return 0;
21 }
22
23 len = strlen(template);
24 tmp_template = PSEUDO_ROOT_PATH(AT_FDCWD, template, AT_SYMLINK_NOFOLLOW);
25
26 if (!tmp_template) {
27 errno = ENOENT;
28 return -1;
29 }
30
31 rc = real_mkostemps(tmp_template, suffixlen, oflags);
32
33 if (rc != -1) {
34 save_errno = errno;
35
36 if (base_fstat(rc, &buf) != -1) {
37 real_fchmod(rc, PSEUDO_FS_MODE(0600, 0));
38 pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
39 pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
40 } else {
41 pseudo_debug(PDBGF_CONSISTENCY, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
42 rc, strerror(errno));
43 pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, 0);
44 }
45 errno = save_errno;
46 }
47 /* WARNING: At least one system allows the number of Xs to be something
48 * other than 6. I do not attempt to handle this.
49 */
50 /* mkstemp only changes the XXXXXX at the end, or suffixlen characters before
51 * the end if mkostemp/mkostemps.
52 */
53 memcpy(template + len - 6 - suffixlen, tmp_template + strlen(tmp_template) - 6 - suffixlen, 6);
54 /* return rc;
55 * }
56 */
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_mkstemp(char *template) {
68 * int rc = -1;
79 */
8 PSEUDO_STATBUF buf;
9 int save_errno;
10 size_t len;
11 char *tmp_template;
10 /* mkstemp() is just like mkostemps() with no flags and no suffix */
11 rc = wrap_mkostemps(template, 0, 0);
1212
13 if (!template) {
14 errno = EFAULT;
15 return 0;
16 }
17
18 len = strlen(template);
19 tmp_template = PSEUDO_ROOT_PATH(AT_FDCWD, template, AT_SYMLINK_NOFOLLOW);
20
21 if (!tmp_template) {
22 errno = ENOENT;
23 return -1;
24 }
25
26 rc = real_mkstemp(tmp_template);
27
28 if (rc != -1) {
29 save_errno = errno;
30
31 if (base_fstat(rc, &buf) != -1) {
32 real_fchmod(rc, PSEUDO_FS_MODE(0600, 0));
33 pseudo_client_op(OP_CREAT, 0, -1, -1, tmp_template, &buf);
34 pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, &buf);
35 } else {
36 pseudo_debug(PDBGF_CONSISTENCY, "mkstemp (fd %d) succeeded, but fstat failed (%s).\n",
37 rc, strerror(errno));
38 pseudo_client_op(OP_OPEN, PSA_READ | PSA_WRITE, rc, -1, tmp_template, 0);
39 }
40 errno = save_errno;
41 }
42 /* mkstemp only changes the XXXXXX at the end. */
43 memcpy(template + len - 6, tmp_template + strlen(tmp_template) - 6, 6);
4413 /* return rc;
4514 * }
4615 */
0 /*
1 * Copyright (c) 2018 Wind River Systems; see
2 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 * int mkstemps(char *template, int suffixlen)
7 * int rc = -1;
8 */
9
10 /* mkstemps() is mkostemps() with no flags */
11 rc = wrap_mkostemps(template, suffixlen, 0);
12
13 /* return rc;
14 * }
15 */
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_mktemp(char *template) {
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int msync(void *addr, size_t length, int flags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int nopenfd, int flag) {
00 /*
11 * Copyright (c) 2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static DIR *
57 * wrap_opendir(const char *path) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static long
57 * wrap_pathconf(const char *path, int name) {
00 /*
11 * Copyright (c) 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * FILE *popen(const char *command, const char *mode)
57 * FILE *rc = NULL;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static ssize_t
57 * wrap_readlink(const char *path, char *buf, size_t bufsiz) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static ssize_t
57 * wrap_readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_realpath(const char *name, char *resolved_name) {
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_remove(const char *path) {
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_rename(const char *oldpath, const char *newpath) {
00 /*
11 * Copyright (c) 2008-2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_rmdir(const char *path) {
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_symlink(const char *oldname, const char *newpath) {
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_symlinkat(const char *oldname, int dirfd, const char *newpath) {
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * void sync(void)
57 *
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2011, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int system(const char *command)
57 * int rc = -1;
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_tempnam(const char *template, const char *pfx) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static char *
57 * wrap_tmpnam(char *s) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_truncate(const char *path, off_t length) {
00 /*
11 * Copyright (c) 2014 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * mode_t umask(mode_t mask)
57 * mode_t rc = 0;
00 /*
11 * Copyright (c) 2008-2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_unlink(const char *path) {
00 /*
11 * Copyright (c) 2008-2010, 2012 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_unlinkat(int dirfd, const char *path, int rflags) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_utime(const char *path, const struct utimbuf *buf) {
00 /*
11 * Copyright (c) 2010 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * static int
57 * wrap_utimes(const char *path, const struct timeval *times) {
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 FILE *
15 popen(const char *command, const char *mode) {
26 sigset_t saved;
00 /*
11 * Copyright (c) 2013 Wind River Systems; see
22 * guts/COPYRIGHT for information.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
35 *
46 * int syncfs(int fd)
57 * int rc = -1;
4545 int mknod(const char *path, mode_t mode, dev_t dev); /* flags=AT_SYMLINK_NOFOLLOW */
4646 int mknodat(int dirfd, const char *path, mode_t mode, dev_t dev); /* flags=AT_SYMLINK_NOFOLLOW */
4747 int mkstemp(char *template); /* flags=AT_SYMLINK_NOFOLLOW */
48 int mkostemp(char *template, int oflags); /* flags=AT_SYMLINK_NOFOLLOW */
49 int mkstemps(char *template, int suffixlen); /* flags=AT_SYMLINK_NOFOLLOW */
50 int mkostemps(char *template, int suffixlen, int oflags); /* flags=AT_SYMLINK_NOFOLLOW */
4851 int rename(const char *oldpath, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
4952 int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); /* flags=AT_SYMLINK_NOFOLLOW */
5053 int rmdir(const char *path); /* flags=AT_SYMLINK_NOFOLLOW */
1515 .\" version 2.1 along with this program; if not, write to the Free Software
1616 .\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1717 .TH pseudo 1 "pseudo - pretending to be root"
18 .SH NAME
19 pseudo \- run a command in a virtual root environment
1820 .SH SYNOPSIS
1921 .B pseudo
2022 .RB [ \-dflv ]
22 *
33 * Copyright (c) 2008-2013 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <stdlib.h>
333322
334323 /* If you didn't specify a command, opt_S shuts down here. */
335324 if (opt_S && argc <= optind) {
336 return pseudo_client_shutdown();
325 return pseudo_client_shutdown(0);
337326 }
338327
339328 if (opt_d && opt_f) {
408397 * the server.
409398 */
410399 if (opt_S) {
411 pseudo_client_shutdown();
400 pseudo_client_shutdown(1);
412401 }
413402 if (WIFEXITED(rc)) {
414403 return WEXITSTATUS(rc);
443432 char *path_by_ino = 0;
444433 char *oldpath = 0;
445434 size_t oldpathlen = 0;
446 int found_path = 0, found_ino = 0;
435 int found_path = 0, found_ino = 0, found_exact = 0;
447436 int prefer_ino = 0;
448437 int xattr_flags = 0;
449438 int trailing_slash = 0;
542531 *msg = msg_header;
543532 found_path = 1;
544533 found_ino = 1;
534 found_exact = 1;
545535 /* note: we have to avoid freeing this later */
546536 path_by_ino = msg->path;
547537 if (msg->op == OP_LINK) {
628618 pseudo_diag("dir mismatch: '%s' [%llu] db mode 0%o, header mode 0%o (unlinking db)\n",
629619 msg->path, (unsigned long long) by_path.ino,
630620 (int) by_path.mode, (int) msg_header.mode);
631 /* unlink everything with this inode */
632 pdb_unlink_file_dev(&by_path);
621 /* unlink this path -- the inode may be in use elsewhere */
622 pdb_unlink_file(msg);
633623 found_path = 0;
634624 } else if (S_ISLNK(by_path.mode) != S_ISLNK(msg_header.mode)) {
635625 pseudo_diag("symlink mismatch: '%s' [%llu] db mode 0%o, header mode 0%o (unlinking db)\n",
636626 msg->path, (unsigned long long) by_path.ino,
637627 (int) by_path.mode, (int) msg_header.mode);
638 /* unlink everything with this inode */
639 pdb_unlink_file_dev(&by_path);
628 /* unlink this path -- the inode may be in use elsewhere */
629 pdb_unlink_file(msg);
640630 found_path = 0;
641631 }
642632 if (trailing_slash && !S_ISDIR(by_path.mode)) {
704694 msg->path);
705695 pdb_did_unlink_file(path_by_ino, &by_ino, by_ino.deleting);
706696 } else {
707 pseudo_diag("path mismatch [%d link%s]: ino %llu db '%s' req '%s'.\n",
697 int flags = 0;
698 if (msg->nlink > 1) {
699 flags = PDBGF_FILE | PDBGF_VERBOSE;
700 }
701 pseudo_debug(flags, "path mismatch [%d link%s]: ino %llu db '%s' req '%s'.\n",
708702 msg->nlink,
709703 msg->nlink == 1 ? "" : "s",
710704 (unsigned long long) msg_header.ino,
767761 break;
768762 case OP_CREAT:
769763 /* implies a new file -- not a link, which would be OP_LINK */
770 if (found_ino) {
764 if (found_ino && !found_exact) {
771765 /* CREAT should never be sent if the file existed.
772766 * So, any existing entry is an error. Nuke it.
767 * ... But only if it wasn't a match on both inode *and*
768 * path, because if it were, that would be harmless.
773769 */
774770 pseudo_diag("creat for '%s' replaces existing %llu ['%s'].\n",
775771 msg->pathlen ? msg->path : "no path",
10111007 if (msg->op == OP_REPLACE_XATTR) {
10121008 xattr_flags = XATTR_REPLACE;
10131009 }
1010 /* fallthrough */
10141011 case OP_SET_XATTR:
10151012 if (pdb_set_xattr(msg, oldpath, oldpathlen, xattr_flags)) {
10161013 msg->result = RESULT_FAIL;
22 *
33 * Copyright (c) 2008-2010, 2013 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <stdlib.h>
5241 if ((x) & PDBGF_VERBOSE) { \
5342 if ((pseudo_util_debug_flags & PDBGF_VERBOSE) && (pseudo_util_debug_flags & ((x) & ~PDBGF_VERBOSE))) { pseudo_diag(__VA_ARGS__); } \
5443 } else { \
55 if (pseudo_util_debug_flags & (x)) { pseudo_diag(__VA_ARGS__); } \
44 if ((pseudo_util_debug_flags & (x)) || ((x) == 0)) { pseudo_diag(__VA_ARGS__); } \
5645 } \
5746 } while (0)
5847 #define pseudo_debug_call(x, fn, ...) do { \
22 *
33 * Copyright (c) 2008-2013 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #define _GNU_SOURCE
13301319 * indicating a successful send.
13311320 */
13321321 pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sent!\n");
1333 if (msg->type != PSEUDO_MSG_FASTOP) {
1334 response = pseudo_msg_receive(connect_fd);
1335 if (!response) {
1336 pseudo_debug(PDBGF_CLIENT, "expected response did not occur; retrying\n");
1322 response = pseudo_msg_receive(connect_fd);
1323 if (!response) {
1324 pseudo_debug(PDBGF_CLIENT, "expected response did not occur; retrying\n");
1325 } else {
1326 if (response->type != PSEUDO_MSG_ACK) {
1327 pseudo_debug(PDBGF_CLIENT, "got non-ack response %d\n", response->type);
1328 return 0;
13371329 } else {
1338 if (response->type != PSEUDO_MSG_ACK) {
1339 pseudo_debug(PDBGF_CLIENT, "got non-ack response %d\n", response->type);
1340 return 0;
1341 } else {
1342 pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "got response type %d\n", response->type);
1343 return response;
1344 }
1345 }
1346 } else {
1347 return 0;
1330 pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "got response type %d\n", response->type);
1331 return response;
1332 }
13481333 }
13491334 }
13501335 pseudo_diag("pseudo: server connection persistently failed, aborting.\n");
13561341 }
13571342
13581343 int
1359 pseudo_client_shutdown(void) {
1344 pseudo_client_shutdown(int wait_on_socket) {
13601345 pseudo_msg_t msg;
13611346 pseudo_msg_t *ack;
13621347 char *pseudo_path;
14271412 pseudo_diag("server did not respond to shutdown query.\n");
14281413 return 1;
14291414 }
1430 if (ack->type == PSEUDO_MSG_ACK) {
1431 return 0;
1432 }
1433 pseudo_diag("Server refused shutdown. Remaining client fds: %d\n", ack->fd);
1434 pseudo_diag("Client pids: %s\n", ack->path);
1435 pseudo_diag("Server will shut down after all clients exit.\n");
1415 if (ack->type != PSEUDO_MSG_ACK) {
1416 pseudo_diag("Server refused shutdown. Remaining client fds: %d\n", ack->fd);
1417 pseudo_diag("Client pids: %s\n", ack->path);
1418 pseudo_diag("Server will shut down after all clients exit.\n");
1419 }
1420 if (wait_on_socket) {
1421 /* try to receive a message the server won't send;
1422 * this should abort/error-out when the server actually
1423 * shuts down. */
1424 ack = pseudo_msg_receive(connect_fd);
1425 }
14361426 return 0;
14371427 }
14381428
14831473 }
14841474
14851475 newpath = pseudo_fix_path(basepath, path, minlen, baselen, NULL, leave_last);
1486 pseudo_debug(PDBGF_PATH, "base_path: %s</>%s\n",
1476 pseudo_debug(PDBGF_PATH, "base_path[%s]: %s</>%s => %s\n",
1477 leave_last ? "nofollow" : "follow",
14871478 basepath ? basepath : "<nil>",
1488 path ? path : "<nil>");
1479 path ? path : "<nil>",
1480 newpath ? newpath : "<nil>");
14891481 return newpath;
14901482 }
14911483
16751667 * empty path for that.
16761668 */
16771669 if (path_extra_1) {
1678 size_t full_len = path_extra_1len + 1 + pathlen;
1670 size_t full_len = path_extra_1len + 1 + pathlen - strip_slash;
16791671 size_t partial_len = pathlen - 1 - strip_slash;
16801672 if (path_extra_2) {
16811673 full_len += path_extra_2len + 1;
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 extern pseudo_msg_t *pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...);
3322 extern void pseudo_client_touchuid(void);
3423 extern void pseudo_client_touchgid(void);
3524 extern char *pseudo_client_fdpath(int fd);
36 extern int pseudo_client_shutdown(void);
25 extern int pseudo_client_shutdown(int);
3726 extern int pseudo_fd(int fd, int how);
3827 #define MOVE_FD 0
3928 #define COPY_FD 1
22 *
33 * Copyright (c) 2008-2010,2013 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <stdio.h>
209 #include <stdlib.h>
2110 #include <string.h>
11 #include <stdint.h>
2212 #include <sys/stat.h>
2313 #include <sys/xattr.h>
2414 #include <time.h>
369359 }
370360 }
371361
362 /* sqlite3 supports only signed integers, thus, the highest positive
363 * value is 2^63-1. some filesystems with 64-bit ino_t will produce
364 * ino_t values in the 2^63..2^64-1 range. we convert those into
365 * the value you'd get treating the 2^63 bit as a sign bit, so sqlite
366 * doesn't convert them into floats, because the float type can't
367 * represent values accurately in this range, which can result in
368 * erroneous matches, etcetera.
369 *
370 * note, when reading the values back out, the conversion does the
371 * right thing. e.g., if the inode number had been 2^63 exactly,
372 * it will convert to -(2^63). that, converted to unsigned, will
373 * convert back to 2^63 exactly, etcetera.
374 *
375 * so far as i know, ino_t is always unsigned. we don't care about
376 * the 32-bit inode case; sqlite can represent those just fine.
377 */
378 static int64_t
379 signed_ino(ino_t ino) {
380 if (ino > (uint64_t) INT64_MAX) {
381 return (int64_t) (ino + INT64_MIN) + INT64_MIN;
382 }
383 return (int64_t) ino;
384 }
385
372386 #ifdef USE_MEMORY_DB
373387
374388 static void
781795 e->gid = trait->data.ivalue;
782796 break;
783797 case PSQF_INODE:
784 e->ino = trait->data.ivalue;
798 e->ino = (ino_t) trait->data.ivalue;
785799 break;
786800 case PSQF_MODE:
787801 e->mode = trait->data.ivalue;
874888 sqlite3_bind_int(insert, field++, e->client);
875889 sqlite3_bind_int(insert, field++, e->dev);
876890 sqlite3_bind_int(insert, field++, e->gid);
877 sqlite3_bind_int64(insert, field++, e->ino);
891 sqlite3_bind_int64(insert, field++, signed_ino(e->ino));
878892 sqlite3_bind_int(insert, field++, e->mode);
879893 if (e->path) {
880894 sqlite3_bind_text(insert, field++, e->path, -1, SQLITE_STATIC);
968982 sqlite3_bind_int(insert, field++, msg->client);
969983 sqlite3_bind_int(insert, field++, msg->dev);
970984 sqlite3_bind_int(insert, field++, msg->gid);
971 sqlite3_bind_int64(insert, field++, msg->ino);
985 sqlite3_bind_int64(insert, field++, signed_ino(msg->ino));
972986 sqlite3_bind_int(insert, field++, msg->mode);
973987 if (msg->pathlen) {
974988 sqlite3_bind_text(insert, field++, msg->path, -1, SQLITE_STATIC);
13751389 l->gid = sqlite3_column_int64(h->stmt, column++);
13761390 break;
13771391 case PSQF_INODE:
1378 l->ino = sqlite3_column_int64(h->stmt, column++);
1392 l->ino = (ino_t) sqlite3_column_int64(h->stmt, column++);
13791393 break;
13801394 case PSQF_MODE:
13811395 l->mode = sqlite3_column_int64(h->stmt, column++);
14941508 static void
14951509 pdb_clear_xattrs(pseudo_msg_t *msg) {
14961510 static sqlite3_stmt *delete;
1497 char *delete_sql = "DELETE FROM xattrs WHERE dev = ? AND ino = ?;";
1511 char *delete_sql = "DELETE FROM xattrs WHERE dev = ? AND ino = ? AND (SELECT COUNT(*) FROM files WHERE dev = ? AND ino = ?) = 0;";
14981512 int rc;
14991513
15001514 if (!msg)
15061520 if (!delete) {
15071521 rc = sqlite3_prepare_v2(file_db, delete_sql, strlen(delete_sql), &delete, NULL);
15081522 if (rc) {
1509 dberr(file_db, "couldn't prepare DELETE statement for unused xattrs");
1523 dberr(file_db, "couldn't prepare DELETE statement for specific inode xattrs");
15101524 return;
15111525 }
15121526 }
15131527 sqlite3_bind_int(delete, 1, msg->dev);
1514 sqlite3_bind_int(delete, 2, msg->ino);
1528 sqlite3_bind_int64(delete, 2, signed_ino(msg->ino));
1529 sqlite3_bind_int(delete, 3, msg->dev);
1530 sqlite3_bind_int64(delete, 4, signed_ino(msg->ino));
15151531 rc = sqlite3_step(delete);
15161532 if (rc != SQLITE_DONE) {
15171533 dberr(file_db, "delete of unused xattrs may have failed");
15461562 }
15471563 }
15481564 sqlite3_bind_int(copy, 1, msg->dev);
1549 sqlite3_bind_int(copy, 2, msg->ino);
1565 sqlite3_bind_int64(copy, 2, signed_ino(msg->ino));
15501566 sqlite3_bind_int(copy, 3, oldmsg->dev);
1551 sqlite3_bind_int(copy, 4, oldmsg->ino);
1567 sqlite3_bind_int64(copy, 4, signed_ino(oldmsg->ino));
15521568 rc = sqlite3_step(copy);
15531569 if (rc != SQLITE_DONE) {
15541570 dberr(file_db, "copy of xattrs may have failed");
15781594 }
15791595 int existing;
15801596 sqlite3_bind_int(scan, 1, msg->dev);
1581 sqlite3_bind_int(scan, 2, msg->ino);
1597 sqlite3_bind_int64(scan, 2, signed_ino(msg->ino));
15821598 rc = sqlite3_step(scan);
15831599 if (rc == SQLITE_ROW) {
15841600 existing = (int) sqlite3_column_int64(scan, 0);
16321648 sqlite3_bind_text(insert, 1, "NAMELESS FILE", -1, SQLITE_STATIC);
16331649 }
16341650 sqlite3_bind_int(insert, 2, msg->dev);
1635 sqlite3_bind_int64(insert, 3, msg->ino);
1651 sqlite3_bind_int64(insert, 3, signed_ino(msg->ino));
16361652 sqlite3_bind_int(insert, 4, msg->uid);
16371653 sqlite3_bind_int(insert, 5, msg->gid);
16381654 sqlite3_bind_int(insert, 6, msg->mode);
16731689 return 1;
16741690 }
16751691 sqlite3_bind_int(sql_delete, 1, msg->dev);
1676 sqlite3_bind_int64(sql_delete, 2, msg->ino);
1692 sqlite3_bind_int64(sql_delete, 2, signed_ino(msg->ino));
16771693 file_db_dirty = 1;
16781694 rc = sqlite3_step(sql_delete);
16791695 if (rc != SQLITE_DONE) {
21652181 pdb_copy_xattrs(oldmsg, msg);
21662182 }
21672183 sqlite3_bind_int(update, 1, msg->dev);
2168 sqlite3_bind_int64(update, 2, msg->ino);
2184 sqlite3_bind_int64(update, 2, signed_ino(msg->ino));
21692185 rc = sqlite3_bind_text(update, 3, msg->path, -1, SQLITE_STATIC);
21702186 if (rc) {
21712187 /* msg->path can never be null, and if msg didn't
22222238 sqlite3_bind_int(update, 3, msg->mode);
22232239 sqlite3_bind_int(update, 4, msg->rdev);
22242240 sqlite3_bind_int(update, 5, msg->dev);
2225 sqlite3_bind_int64(update, 6, msg->ino);
2241 sqlite3_bind_int64(update, 6, signed_ino(msg->ino));
22262242
22272243 file_db_dirty = 1;
22282244 rc = sqlite3_step(update);
22632279 dberr(file_db, "error binding %s to select", msg->pathlen ? msg->path : "<nil>");
22642280 }
22652281 sqlite3_bind_int(select, 2, msg->dev);
2266 sqlite3_bind_int64(select, 3, msg->ino);
2282 sqlite3_bind_int64(select, 3, signed_ino(msg->ino));
22672283 rc = sqlite3_step(select);
22682284 switch (rc) {
22692285 case SQLITE_ROW:
23222338 switch (rc) {
23232339 case SQLITE_ROW:
23242340 msg->dev = sqlite3_column_int64(select, 2);
2325 msg->ino = sqlite3_column_int64(select, 3);
2341 msg->ino = (ino_t) sqlite3_column_int64(select, 3);
23262342 msg->uid = sqlite3_column_int64(select, 4);
23272343 msg->gid = sqlite3_column_int64(select, 5);
23282344 msg->mode = sqlite3_column_int64(select, 6);
23672383 return 0;
23682384 }
23692385 sqlite3_bind_int(select, 1, msg->dev);
2370 sqlite3_bind_int64(select, 2, msg->ino);
2386 sqlite3_bind_int64(select, 2, signed_ino(msg->ino));
23712387 rc = sqlite3_step(select);
23722388 switch (rc) {
23732389 case SQLITE_ROW:
24162432 return 1;
24172433 }
24182434 sqlite3_bind_int(select, 1, msg->dev);
2419 sqlite3_bind_int64(select, 2, msg->ino);
2435 sqlite3_bind_int64(select, 2, signed_ino(msg->ino));
24202436 rc = sqlite3_step(select);
24212437 switch (rc) {
24222438 case SQLITE_ROW:
24682484 }
24692485 pseudo_debug(PDBGF_XATTR, "requested xattr named '%s' for ino %lld\n", *value, (long long) msg->ino);
24702486 sqlite3_bind_int(select, 1, msg->dev);
2471 sqlite3_bind_int(select, 2, msg->ino);
2487 sqlite3_bind_int64(select, 2, signed_ino(msg->ino));
24722488 rc = sqlite3_bind_text(select, 3, *value, -1, SQLITE_STATIC);
24732489 if (rc) {
24742490 dberr(file_db, "couldn't bind xattr name to SELECT.");
25302546 }
25312547 }
25322548 sqlite3_bind_int(select, 1, msg->dev);
2533 sqlite3_bind_int(select, 2, msg->ino);
2549 sqlite3_bind_int64(select, 2, signed_ino(msg->ino));
25342550 do {
25352551 rc = sqlite3_step(select);
25362552 if (rc == SQLITE_ROW) {
25842600 }
25852601 }
25862602 sqlite3_bind_int(delete, 1, msg->dev);
2587 sqlite3_bind_int(delete, 2, msg->ino);
2603 sqlite3_bind_int64(delete, 2, signed_ino(msg->ino));
25882604 rc = sqlite3_bind_text(delete, 3, value, len, SQLITE_STATIC);
25892605 if (rc) {
25902606 dberr(file_db, "couldn't bind xattr name to DELETE.");
26252641 }
26262642 }
26272643 sqlite3_bind_int(select, 1, msg->dev);
2628 sqlite3_bind_int(select, 2, msg->ino);
2644 sqlite3_bind_int64(select, 2, signed_ino(msg->ino));
26292645 rc = sqlite3_bind_text(select, 3, value, -1, SQLITE_STATIC);
26302646 if (rc) {
26312647 dberr(file_db, "couldn't bind xattr name to SELECT.");
26942710 }
26952711 }
26962712 sqlite3_bind_int64(insert, 1, msg->dev);
2697 sqlite3_bind_int64(insert, 2, msg->ino);
2713 sqlite3_bind_int64(insert, 2, signed_ino(msg->ino));
26982714 rc = sqlite3_bind_text(insert, 3, vname, -1, SQLITE_STATIC);
26992715 if (rc) {
27002716 dberr(file_db, "couldn't bind xattr name to INSERT statement");
27402756 if (!msg) {
27412757 return 1;
27422758 }
2743 sqlite3_bind_int64(select, 1, msg->ino);
2759 sqlite3_bind_int64(select, 1, signed_ino(msg->ino));
27442760 rc = sqlite3_step(select);
27452761 switch (rc) {
27462762 case SQLITE_ROW:
28152831 }
28162832 pseudo_debug(PDBGF_DB, "pdb_file: '%s'\n", s ? (const char *) s : "<nil>");
28172833 m->dev = sqlite3_column_int64(l->stmt, column++);
2818 m->ino = sqlite3_column_int64(l->stmt, column++);
2834 m->ino = (ino_t) sqlite3_column_int64(l->stmt, column++);
28192835 m->uid = sqlite3_column_int64(l->stmt, column++);
28202836 m->gid = sqlite3_column_int64(l->stmt, column++);
28212837 m->mode = sqlite3_column_int64(l->stmt, column++);
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 typedef struct {
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <stddef.h>
2514 #include <ctype.h>
2615 #include <errno.h>
2716 #include <sys/stat.h>
17 #include <sys/socket.h>
2818
2919 #include "pseudo.h"
3020 #include "pseudo_ipc.h"
3121
32 /* Short reads or writes can cause a sigpipe, killing the program, so we
33 * trap it and report that something happened.
34 */
22 /* Short reads or writes can cause a sigpipe, killing the program, so
23 * we trap it and report that something happened. We can avoid the
24 * overhead of setting/restoring the SIGPIPE handler if MSG_NOSIGNAL
25 * is available.
26 */
27 #ifndef MSG_NOSIGNAL
3528 static sig_atomic_t pipe_error = 0;
3629 static void (*old_handler)(int) = SIG_DFL;
3730
5043 allow_sigpipe(void) {
5144 signal(SIGPIPE, old_handler);
5245 }
46 #else
47 #define pipe_error 0
48 #endif
5349
5450 #if 0
5551 /* useful only when debugging crazy stuff */
6561 }
6662 #endif
6763
64 #ifdef MSG_NOSIGNAL
65 static int
66 do_send(int fd, struct iovec *iov, int iovlen)
67 {
68 struct msghdr hdr;
69
70 memset(&hdr, 0, sizeof(hdr));
71 hdr.msg_iov = iov;
72 hdr.msg_iovlen = iovlen;
73
74 return sendmsg(fd, &hdr, MSG_NOSIGNAL);
75 }
76 #else
77 static int
78 do_send(int fd, struct iovec *iov, int iovlen)
79 {
80 int r, s = 0, i;
81
82 ignore_sigpipe();
83 for (i = 0; i < iovlen; ++i) {
84 r = write(fd, iov[i].iov_base, iov[i].iov_len);
85 s += r;
86 if (r != (int)iov[i].iov_len)
87 break;
88 }
89 allow_sigpipe();
90 return s;
91 }
92 #endif
93
6894 /*
6995 * send message on fd
7096 * return:
74100 */
75101 int
76102 pseudo_msg_send(int fd, pseudo_msg_t *msg, size_t len, const char *path) {
77 int r;
103 struct iovec iov[2];
104 int r, iovc;
78105
79106 if (!msg)
80107 return 1;
88115 if (len == (size_t) -1)
89116 len = strlen(path) + 1;
90117 msg->pathlen = len;
91 ignore_sigpipe();
92 r = write(fd, msg, PSEUDO_HEADER_SIZE);
93 if (r == PSEUDO_HEADER_SIZE) {
94 r += write(fd, path, len);
95 }
96 allow_sigpipe();
97 pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "wrote %d bytes\n", r);
98 if (pipe_error || (r == -1 && errno == EBADF))
99 return -1;
100 return ((size_t) r != PSEUDO_HEADER_SIZE + len);
118 iov[0].iov_base = msg;
119 iov[0].iov_len = PSEUDO_HEADER_SIZE;
120 iov[1].iov_base = (void*)path;
121 iov[1].iov_len = len;
122 iovc = 2;
101123 } else {
102124 pseudo_debug(PDBGF_IPC, "msg type %d (%s), result %d (%s), path %.*s, mode 0%o\n",
103125 msg->type, pseudo_op_name(msg->op),
104126 msg->result, pseudo_res_name(msg->result),
105127 msg->pathlen, msg->path, (int) msg->mode);
106128 // display_msg_header(msg);
107 ignore_sigpipe();
108 r = write(fd, msg, PSEUDO_HEADER_SIZE + msg->pathlen);
109 allow_sigpipe();
110 pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "wrote %d bytes\n", r);
111 if (pipe_error || (r == -1 && errno == EBADF))
112 return -1;
113 return ((size_t) r != PSEUDO_HEADER_SIZE + msg->pathlen);
114 }
129 iov[0].iov_base = msg;
130 iov[0].iov_len = PSEUDO_HEADER_SIZE + msg->pathlen;
131 iovc = 1;
132 }
133 r = do_send(fd, iov, iovc);
134 pseudo_debug(PDBGF_IPC | PDBGF_VERBOSE, "wrote %d bytes\n", r);
135 if (pipe_error || (r == -1 && (errno == EBADF || errno == EPIPE)))
136 return -1;
137 return ((size_t) r != PSEUDO_HEADER_SIZE + msg->pathlen);
115138 }
116139
117140 /* attempts to receive a message from fd
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198
0 /*
1 * SPDX-License-Identifier: LGPL-2.1-only
2 *
3 */
04 #define _GNU_SOURCE
15
26 #include <errno.h>
22 *
33 * Copyright (c) 2008-2010, 2013 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <stdio.h>
2413
2514 #include <unistd.h>
2615 #include <fcntl.h>
16 #include <sys/ioctl.h>
2717 #include <sys/select.h>
2818 #include <sys/time.h>
2919 #include <sys/types.h>
3121 #include <sys/un.h>
3222 #include <sys/stat.h>
3323 #include <sys/wait.h>
24 #ifdef PSEUDO_EPOLL
25 #include <sys/epoll.h>
26 #endif
3427 #include <signal.h>
3528
3629 #include "pseudo.h"
5851
5952 #define LOOP_DELAY 2
6053 #define DEFAULT_PSEUDO_SERVER_TIMEOUT 30
54 #define EPOLL_MAX_EVENTS 10
6155 int pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
6256 static int die_peacefully = 0;
6357 static int die_forcefully = 0;
58 static sig_atomic_t do_list_clients = 0;
6459
6560 /* when the client is linked with pseudo_wrappers, these are defined there.
6661 * when it is linked with pseudo_server, though, we have to provide different
7671 die_forcefully = 1;
7772 }
7873
74 static void
75 set_do_list_clients(int sig) {
76 do_list_clients = sig;
77 }
78
7979 static int messages = 0, responses = 0;
8080 static struct timeval message_time = { .tv_sec = 0 };
8181
82 #ifdef PSEUDO_EPOLL
83 static void pseudo_server_loop_epoll(void);
84 #else
8285 static void pseudo_server_loop(void);
86 #endif
8387
8488 /* helper function to make a directory, just like mkdir -p.
8589 * Can't use system() because the child shell would end up trying
368372 kill(ppid, SIGUSR1);
369373 }
370374 }
375 #ifdef PSEUDO_EPOLL
376 pseudo_server_loop_epoll();
377 #else
371378 pseudo_server_loop();
379 #endif
372380 return 0;
373381 }
374382
375383 /* mess with internal tables as needed */
376 static void
384 static unsigned int
377385 open_client(int fd) {
378386 pseudo_client_t *new_clients;
379387 int i;
389397 ++active_clients;
390398 if (i > highest_client)
391399 highest_client = i;
392 return;
400 return i;
393401 }
394402 }
395403
413421
414422 max_clients += 16;
415423 ++active_clients;
424 return max_clients - 16;
416425 } else {
417426 pseudo_diag("error allocating new client, fd %d\n", fd);
418427 close(fd);
428 return 0;
419429 }
420430 }
421431
451461 serve_client(int i) {
452462 pseudo_msg_t *in;
453463 int rc;
454
464 struct timeval tv1, tv2;
465 gettimeofday(&tv1, NULL);
466
467 ++messages;
455468 pseudo_debug(PDBGF_SERVER, "message from client %d [%d:%s - %s] fd %d\n",
456469 i, (int) clients[i].pid,
457470 clients[i].program ? clients[i].program : "???",
461474 if (in) {
462475 char *response_path = 0;
463476 size_t response_pathlen;
464 int send_response = 1;
477 int send_response = 1;
465478 pseudo_debug(PDBGF_SERVER | PDBGF_VERBOSE, "got a message (%d): %s\n", in->type, (in->pathlen ? in->path : "<no path>"));
466479 /* handle incoming ping */
467480 if (in->type == PSEUDO_MSG_PING && !clients[i].pid) {
488501 }
489502 pseudo_debug(PDBGF_SERVER, "\n");
490503 }
504 if (in->type == PSEUDO_MSG_SHUTDOWN && !clients[i].pid) {
505 pseudo_debug(PDBGF_SERVER, "shutdown request from client %d [pid %d]\n",
506 i, in->client);
507 in->client = clients[i].pid;
508 }
491509 /* sanity-check client ID */
492510 if (in->client != clients[i].pid) {
493511 pseudo_debug(PDBGF_SERVER, "uh-oh, expected pid %d for client %d, got %d\n",
497515 * pseudo_server_response.
498516 */
499517 if (in->type != PSEUDO_MSG_SHUTDOWN) {
500 if (in->type == PSEUDO_MSG_FASTOP)
501 send_response = 0;
502518 /* most messages don't need these, but xattr may */
503519 response_path = 0;
504520 response_pathlen = -1;
514530 in->pathlen = response_pathlen;
515531 } else {
516532 in->pathlen = 0;
533 }
534 if (in->type == PSEUDO_MSG_FASTOP) {
535 /* respond instantly */
536 send_response = 0;
537 int t_type = in->type;
538 int t_pathlen = in->pathlen;
539 in->type = PSEUDO_MSG_ACK;
540 in->pathlen = 0;
541 if ((rc = pseudo_msg_send(clients[i].fd, in, in->pathlen, response_path)) != 0) {
542 pseudo_debug(PDBGF_SERVER, "failed to send response to client %d [%d]: %d (%s)\n",
543 i, (int) clients[i].pid, rc, strerror(errno));
544 }
545 in->type = t_type;
546 in->pathlen = t_pathlen;
517547 }
518548 } else {
519549 /* the server's listen fd is "a client", and
545575 die_peacefully = 1;
546576 }
547577 }
548 if (send_response) {
549 if ((rc = pseudo_msg_send(clients[i].fd, in, in->pathlen, response_path)) != 0) {
550 pseudo_debug(PDBGF_SERVER, "failed to send response to client %d [%d]: %d (%s)\n",
551 i, (int) clients[i].pid, rc, strerror(errno));
552 }
553 } else {
554 rc = 1;
555 }
578 if (send_response) {
579 if ((rc = pseudo_msg_send(clients[i].fd, in, in->pathlen, response_path)) != 0) {
580 pseudo_debug(PDBGF_SERVER, "failed to send response to client %d [%d]: %d (%s)\n",
581 i, (int) clients[i].pid, rc, strerror(errno));
582 }
583 } else {
584 rc = 1;
585 }
556586 free(response_path);
557 return rc;
558587 } else {
559588 /* this should not be happening, but the exceptions aren't
560589 * being detected in select() for some reason.
561590 */
562591 pseudo_debug(PDBGF_SERVER, "client %d: no message\n", (int) clients[i].pid);
563592 close_client(i);
564 return 0;
565 }
566 }
567
568 /* get clients, handle messages, shut down.
569 * This doesn't actually do any work, it just calls a ton of things which
570 * do work.
571 */
572 static void
573 pseudo_server_loop(void) {
593 rc = 0;
594 }
595
596 gettimeofday(&tv2, NULL);
597 if (rc == 0)
598 ++responses;
599 message_time.tv_sec += (tv2.tv_sec - tv1.tv_sec);
600 message_time.tv_usec += (tv2.tv_usec - tv1.tv_usec);
601 if (message_time.tv_usec < 0) {
602 message_time.tv_usec += 1000000;
603 --message_time.tv_sec;
604 } else while (message_time.tv_usec > 1000000) {
605 message_time.tv_usec -= 1000000;
606 ++message_time.tv_sec;
607 }
608 return rc;
609 }
610
611 #ifdef PSEUDO_EPOLL
612 static void pseudo_server_loop_epoll(void)
613 {
574614 struct sockaddr_un client;
575615 socklen_t len;
576 fd_set reads, writes, events;
577 int max_fd, current_clients;
578 struct timeval timeout;
579616 int i;
580617 int rc;
581618 int fd;
619 int timeout;
620 struct epoll_event ev, events[EPOLL_MAX_EVENTS];
582621 int loop_timeout = pseudo_server_timeout;
622 struct sigaction eat_usr2 = {
623 .sa_handler = set_do_list_clients
624 };
583625
584626 clients = malloc(16 * sizeof(*clients));
627
628 sigaction(SIGUSR2, &eat_usr2, NULL);
585629
586630 clients[0].fd = listen_fd;
587631 clients[0].pid = getpid();
602646 pseudo_diag("got into loop with no valid listen fd.\n");
603647 exit(PSEUDO_EXIT_LISTEN_FD);
604648 }
649
650 timeout = LOOP_DELAY * 1000;
651
652 int epollfd = epoll_create1(0);
653 if (epollfd == -1) {
654 pseudo_diag("epoll_create1() failed.\n");
655 exit(PSEUDO_EXIT_EPOLL_CREATE);
656 }
657 ev.events = EPOLLIN;
658 ev.data.u64 = 0;
659 if (epoll_ctl(epollfd, EPOLL_CTL_ADD, clients[0].fd, &ev) == -1) {
660 pseudo_diag("epoll_ctl() failed with listening socket.\n");
661 exit(PSEUDO_EXIT_EPOLL_CTL);
662 }
663
605664 pdb_log_msg(SEVERITY_INFO, NULL, NULL, NULL, "server started (pid %d)", getpid());
606665
607 FD_ZERO(&reads);
608 FD_ZERO(&writes);
609 FD_ZERO(&events);
610 FD_SET(clients[0].fd, &reads);
611 FD_SET(clients[0].fd, &events);
612 max_fd = clients[0].fd;
613 timeout = (struct timeval) { .tv_sec = LOOP_DELAY, .tv_usec = 0 };
614
615 /* EINTR tends to come from profiling, so it is not a good reason to
616 * exit; other signals are caught and set the flag causing a graceful
617 * exit. */
618 while ((rc = select(max_fd + 1, &reads, &writes, &events, &timeout)) >= 0 || (errno == EINTR)) {
666 for (;;) {
667 rc = epoll_wait(epollfd, events, EPOLL_MAX_EVENTS, timeout);
619668 if (rc == 0 || (rc == -1 && errno == EINTR)) {
620669 /* If there's no clients, start timing out. If there
621670 * are active clients, never time out.
622671 */
623672 if (active_clients == 1) {
624673 loop_timeout -= LOOP_DELAY;
625 /* maybe flush database to disk */
626 pdb_maybe_backup();
674 /* maybe flush database to disk */
675 pdb_maybe_backup();
627676 if (loop_timeout <= 0) {
628677 pseudo_debug(PDBGF_SERVER, "no more clients, got bored.\n");
629678 die_peacefully = 1;
633682 messages,
634683 (double) message_time.tv_sec +
635684 (double) message_time.tv_usec / 1000000.0,
636 responses);
685 responses);
637686 }
638687 }
639688 } else if (rc > 0) {
640689 loop_timeout = pseudo_server_timeout;
641 for (i = 1; i <= highest_client; ++i) {
642 if (clients[i].fd == -1)
643 continue;
644 if (FD_ISSET(clients[i].fd, &events)) {
645 /* this should happen but doesn't... */
646 close_client(i);
647 } else if (FD_ISSET(clients[i].fd, &reads)) {
648 struct timeval tv1, tv2;
649 int rc;
650 gettimeofday(&tv1, NULL);
651 rc = serve_client(i);
652 gettimeofday(&tv2, NULL);
653 ++messages;
654 if (rc == 0)
655 ++responses;
656 message_time.tv_sec += (tv2.tv_sec - tv1.tv_sec);
657 message_time.tv_usec += (tv2.tv_usec - tv1.tv_usec);
658 if (message_time.tv_usec < 0) {
659 message_time.tv_usec += 1000000;
660 --message_time.tv_sec;
661 } else while (message_time.tv_usec > 1000000) {
662 message_time.tv_usec -= 1000000;
663 ++message_time.tv_sec;
690 for (i = 0; i < rc; ++i) {
691 int client_id = events[i].data.u64;
692 if (clients[client_id].fd == listen_fd) {
693 if (!die_forcefully) {
694 len = sizeof(client);
695 if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
696 /* Don't allow clients to end up on fd 2, because glibc's
697 * malloc debug uses that fd unconditionally.
698 */
699 if (fd == 2) {
700 int newfd = fcntl(fd, F_DUPFD, 3);
701 close(fd);
702 fd = newfd;
703 }
704 pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
705 /* A new client implicitly cancels any
706 * previous shutdown request, or a
707 * shutdown for lack of clients.
708 */
709 pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
710 die_peacefully = 0;
711
712 ev.events = EPOLLIN;
713 ev.data.u64 = open_client(fd);
714 if (ev.data.u64 != 0 && epoll_ctl(epollfd, EPOLL_CTL_ADD, clients[ev.data.u64].fd, &ev) == -1) {
715 pseudo_diag("epoll_ctl() failed with accepted socket.\n");
716 exit(PSEUDO_EXIT_EPOLL_CTL);
717 }
718 } else if (errno == EMFILE) {
719 // select() loop would drop a client here, we do nothing (for now)
720 pseudo_debug(PDBGF_SERVER, "Hit max open files.\n");
721 }
722 }
723 } else {
724 int n = 0;
725 ioctl(clients[client_id].fd, FIONREAD, &n);
726 if (n == 0) {
727 close_client(client_id);
728 } else {
729 serve_client(client_id);
664730 }
665731 }
666732 if (die_forcefully)
667733 break;
668734 }
669 if (!die_forcefully &&
670 (FD_ISSET(clients[0].fd, &events) ||
671 FD_ISSET(clients[0].fd, &reads))) {
672 len = sizeof(client);
673 if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
674 /* Don't allow clients to end up on fd 2, because glibc's
675 * malloc debug uses that fd unconditionally.
676 */
677 if (fd == 2) {
678 int newfd = fcntl(fd, F_DUPFD, 3);
679 close(fd);
680 fd = newfd;
681 }
682 pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
683 open_client(fd);
684 /* A new client implicitly cancels any
685 * previous shutdown request, or a
686 * shutdown for lack of clients.
687 */
688 pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
689 die_peacefully = 0;
690 }
691 }
692735 pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);
736 } else {
737 pseudo_diag("epoll_wait failed: %s\n", strerror(errno));
738 break;
739 }
740 if (do_list_clients) {
741 do_list_clients = 0;
742 pseudo_diag("listing clients [1 through %d]:\n", highest_client);
743 for (i = 1; i <= highest_client; ++i) {
744 if (clients[i].fd == -1) {
745 pseudo_diag("client %4d: inactive.\n", i);
746 continue;
747 }
748 pseudo_diag("client %4d: fd %4d, pid %5d, program %s\n",
749 i, clients[i].fd, clients[i].pid,
750 clients[i].program ? clients[i].program : "<unspecified>");
751 }
752 pseudo_diag("done.\n");
693753 }
694754 if (die_peacefully || die_forcefully) {
695755 pseudo_debug(PDBGF_SERVER, "quitting.\n");
708768 /* usleep(300000); */
709769 exit(0);
710770 }
771 }
772
773 }
774 #else
775
776 /* get clients, handle messages, shut down.
777 * This doesn't actually do any work, it just calls a ton of things which
778 * do work.
779 */
780 static void
781 pseudo_server_loop(void) {
782 struct sockaddr_un client;
783 socklen_t len;
784 fd_set reads, writes, events;
785 int max_fd, current_clients;
786 struct timeval timeout;
787 int i;
788 int rc;
789 int fd;
790 int loop_timeout = pseudo_server_timeout;
791 struct sigaction eat_usr2 = {
792 .sa_handler = set_do_list_clients
793 };
794
795 clients = malloc(16 * sizeof(*clients));
796
797 sigaction(SIGUSR2, &eat_usr2, NULL);
798
799 clients[0].fd = listen_fd;
800 clients[0].pid = getpid();
801
802 for (i = 1; i < 16; ++i) {
803 clients[i].fd = -1;
804 clients[i].pid = 0;
805 clients[i].tag = NULL;
806 clients[i].program = NULL;
807 }
808
809 active_clients = 1;
810 max_clients = 16;
811 highest_client = 0;
812
813 pseudo_debug(PDBGF_SERVER, "server loop started.\n");
814 if (listen_fd < 0) {
815 pseudo_diag("got into loop with no valid listen fd.\n");
816 exit(PSEUDO_EXIT_LISTEN_FD);
817 }
818 pdb_log_msg(SEVERITY_INFO, NULL, NULL, NULL, "server started (pid %d)", getpid());
819
820 FD_ZERO(&reads);
821 FD_ZERO(&events);
822 FD_ZERO(&writes);
823 FD_SET(clients[0].fd, &reads);
824 FD_SET(clients[0].fd, &events);
825 max_fd = clients[0].fd;
826 timeout = (struct timeval) { .tv_sec = LOOP_DELAY, .tv_usec = 0 };
827
828 /* EINTR tends to come from profiling, so it is not a good reason to
829 * exit; other signals are caught and set the flag causing a graceful
830 * exit. */
831 sigset_t maskusr2;
832 sigemptyset(&maskusr2);
833 sigaddset(&maskusr2, SIGUSR2);
834 sigprocmask(SIG_BLOCK, &maskusr2, NULL);
835 while ((rc = select(max_fd + 1, &reads, &writes, &events, &timeout)) >= 0 || (errno == EINTR)) {
836 sigprocmask(SIG_UNBLOCK, &maskusr2, NULL);
837 if (rc == 0 || (rc == -1 && errno == EINTR)) {
838 /* If there's no clients, start timing out. If there
839 * are active clients, never time out.
840 */
841 if (active_clients == 1) {
842 loop_timeout -= LOOP_DELAY;
843 /* maybe flush database to disk */
844 pdb_maybe_backup();
845 if (loop_timeout <= 0) {
846 pseudo_debug(PDBGF_SERVER, "no more clients, got bored.\n");
847 die_peacefully = 1;
848 } else {
849 /* display this if not exiting */
850 pseudo_debug(PDBGF_SERVER | PDBGF_BENCHMARK, "%d messages handled in %.4f seconds, %d responses\n",
851 messages,
852 (double) message_time.tv_sec +
853 (double) message_time.tv_usec / 1000000.0,
854 responses);
855 }
856 }
857 } else if (rc > 0) {
858 loop_timeout = pseudo_server_timeout;
859 for (i = 1; i <= highest_client; ++i) {
860 if (clients[i].fd == -1) {
861 continue;
862 } else if (FD_ISSET(clients[i].fd, &reads)) {
863 int n = 0;
864 ioctl(clients[i].fd, FIONREAD, &n);
865 if (n == 0) {
866 close_client(i);
867 } else {
868 serve_client(i);
869 }
870 }
871 if (die_forcefully)
872 break;
873 }
874 if (!die_forcefully &&
875 (FD_ISSET(clients[0].fd, &events) ||
876 FD_ISSET(clients[0].fd, &reads))) {
877 len = sizeof(client);
878 if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
879 /* Don't allow clients to end up on fd 2, because glibc's
880 * malloc debug uses that fd unconditionally.
881 */
882 if (fd == 2) {
883 int newfd = fcntl(fd, F_DUPFD, 3);
884 close(fd);
885 fd = newfd;
886 }
887 pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
888 open_client(fd);
889 /* A new client implicitly cancels any
890 * previous shutdown request, or a
891 * shutdown for lack of clients.
892 */
893 pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
894 die_peacefully = 0;
895 }
896 }
897 pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);
898 }
899 if (do_list_clients) {
900 do_list_clients = 0;
901 pseudo_diag("listing clients [1 through %d]:\n", highest_client);
902 for (i = 1; i <= highest_client; ++i) {
903 if (clients[i].fd == -1) {
904 pseudo_diag("client %4d: inactive.\n", i);
905 continue;
906 }
907 pseudo_diag("client %4d: fd %4d, pid %5d, state %s, program %s\n",
908 i, clients[i].fd, clients[i].pid,
909 FD_ISSET(clients[i].fd, &reads) ? "R" : "-",
910 clients[i].program ? clients[i].program : "<unspecified>");
911 }
912 pseudo_diag("done.\n");
913 }
914 if (die_peacefully || die_forcefully) {
915 pseudo_debug(PDBGF_SERVER, "quitting.\n");
916 pseudo_debug(PDBGF_SERVER | PDBGF_BENCHMARK, "server %d exiting: handled %d messages in %.4f seconds\n",
917 getpid(), messages,
918 (double) message_time.tv_sec +
919 (double) message_time.tv_usec / 1000000.0);
920 pdb_log_msg(SEVERITY_INFO, NULL, NULL, NULL, "server %d exiting: handled %d messages in %.4f seconds",
921 getpid(), messages,
922 (double) message_time.tv_sec +
923 (double) message_time.tv_usec / 1000000.0);
924 /* and at this point, we'll start refusing connections */
925 close(clients[0].fd);
926 /* This is a good place to insert a delay for
927 * debugging race conditions during startup. */
928 /* usleep(300000); */
929 exit(0);
930 }
711931 FD_ZERO(&reads);
712932 FD_ZERO(&writes);
713933 FD_ZERO(&events);
723943 if (clients[i].fd != -1) {
724944 ++current_clients;
725945 FD_SET(clients[i].fd, &reads);
726 FD_SET(clients[i].fd, &events);
727946 if (clients[i].fd > max_fd)
728947 max_fd = clients[i].fd;
729948 }
734953 }
735954 /* reinitialize timeout because Linux select alters it */
736955 timeout = (struct timeval) { .tv_sec = LOOP_DELAY, .tv_usec = 0 };
956 sigprocmask(SIG_BLOCK, &maskusr2, NULL);
737957 }
738958 pseudo_diag("select failed: %s\n", strerror(errno));
739959 }
960 #endif /* this is the else of #ifdef PSEUDO_EPOLL */
22 *
33 * Copyright (c) 2008-2009 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 extern int pseudo_server_start(int);
22 *
33 * Copyright (c) 2008-2013 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 /* we need access to RTLD_NEXT for a horrible workaround */
264253 static int debugged_newline = 1;
265254 static char pid_text[32];
266255 static size_t pid_len;
267 static int pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurrent, const char *element, size_t elen, int leave_this);
268 static int pseudo_append_elements(char *newpath, char *root, size_t allocated, char **current, const char *elements, size_t elen, int leave_last);
256 static int pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurrent, const char *element, size_t elen, PSEUDO_STATBUF *buf, int leave_this);
257 static int pseudo_append_elements(char *newpath, char *root, size_t allocated, char **current, const char *elements, size_t elen, int leave_last, PSEUDO_STATBUF *sbuf);
269258 extern char **environ;
270259 static ssize_t pseudo_max_pathlen = -1;
271260 static ssize_t pseudo_sys_max_pathlen = -1;
617606 * the symlink, appending each element in turn the same way.
618607 */
619608 static int
620 pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurrent, const char *element, size_t elen, int leave_this) {
609 pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurrent, const char *element, size_t elen, PSEUDO_STATBUF *buf, int leave_this) {
621610 static int link_recursion = 0;
622611 size_t curlen;
612 int is_dir = S_ISDIR(buf->st_mode);
623613 char *current;
624 PSEUDO_STATBUF buf;
625614 if (!newpath ||
626615 !pcurrent || !*pcurrent ||
627616 !root || !element) {
629618 return -1;
630619 }
631620 current = *pcurrent;
632 /* sanity-check: ignore // or /./ */
633 if (elen == 0 || (elen == 1 && *element == '.')) {
634 return 1;
635 }
636 /* backtrack for .. */
637 if (elen == 2 && element[0] == '.' && element[1] == '.') {
638 /* if newpath's whole contents are '/', do nothing */
639 if (current <= root + 1)
621 pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "pae: '%s', + '%.*s', is_dir %d\n",
622 newpath, (int) elen, element, is_dir);
623 /* the special cases here to skip empty paths, or ./.., should apply
624 * only to directories; plain files, nodes, etcetera should just get
625 * bogus paths.
626 */
627 if (is_dir) {
628 /* sanity-check: ignore // or /./ */
629 if (elen == 0 || (elen == 1 && *element == '.')) {
630 return 0;
631 }
632 /* backtrack for .. */
633 if (elen == 2 && element[0] == '.' && element[1] == '.') {
634 /* if newpath is empty, do nothing. */
635 if (current <= root)
636 return 0;
637 /* now find the previous slash */
638 while (current > root && *current != '/') {
639 --current;
640 }
641 /* either we're at root, or we're at a slash.
642 * either way, nul that out, leaving us with a
643 * possibly-empty path which is not slash-terminated.
644 */
645 *current = '\0';
646 *pcurrent = current;
640647 return 1;
641 /* backtrack to the character before the / */
642 current -= 2;
643 /* now find the previous slash */
644 while (current > root && *current != '/') {
645 --current;
646 }
647 /* and point to the nul just past it */
648 *(++current) = '\0';
649 *pcurrent = current;
650 return 1;
648 }
651649 }
652650 curlen = current - newpath;
653651 /* current length, plus / <element> / \0 */
656654 pseudo_diag("pseudo_append_element: path too long (wanted %lu bytes).\n", (unsigned long) curlen + elen + 3);
657655 return -1;
658656 }
657 /* append a slash */
658 *current++ = '/';
659659 memcpy(current, element, elen);
660660 current += elen;
661 /* nul-terminate, and we now point to the nul after the slash */
661 /* nul-terminate, and we now point to the nul after the element just added. */
662662 *current = '\0';
663 /* now, the moment of truth... is that a symlink? */
664 /* if lstat fails, that's fine -- nonexistent files aren't symlinks */
665 if (!leave_this) {
666 int is_link;
667 is_link = (pseudo_real_lstat) && (pseudo_real_lstat(newpath, &buf) != -1) && S_ISLNK(buf.st_mode);
663 /* if we are not on the last element of a path and supposed to leave
664 * it alone (for SYMLINK_NOFOLLOW type cases), and we are not trying to
665 * go further under a regular file, we want to know whether this is a symlink.
666 * either way, we want to update buf to show the correct state of the file.
667 */
668 if (!pseudo_real_lstat || (pseudo_real_lstat(newpath, buf) == -1)) {
669 // if we can't stat it, zero mode so we don't think it's
670 // known to be a link or a regular file.
671 buf->st_mode = 0;
672 }
673 /* it is intentional that this uses the "stale" is_dir for the file we
674 * were appending to. we don't want to actually try to do this when
675 * we're appending names to a regular file.
676 */
677 if (!leave_this && is_dir) {
678 int is_link = S_ISLNK(buf->st_mode);
668679 if (link_recursion >= PSEUDO_MAX_LINK_RECURSION && is_link) {
669680 pseudo_diag("link recursion too deep, not expanding path '%s'.\n", newpath);
670681 is_link = 0;
683694 linkbuf[linklen] = '\0';
684695 /* absolute symlink means start over! */
685696 if (*linkbuf == '/') {
686 current = newpath + 1;
697 current = newpath;
687698 } else {
688699 /* point back at the end of the previous path... */
689 current -= elen;
700 current -= (elen + 1);
690701 }
691702 /* null terminate at the new pointer */
692703 *current = '\0';
704 *pcurrent = current;
705 /* we know that we're now pointing either at a directory we
706 * already decided was safe to go into, or root. either way,
707 * the parent item mode should reflect it being a directory.
708 * we don't need to call stat for that.
709 */
710 buf->st_mode = S_IFDIR;
693711 /* append all the elements in series */
694 *pcurrent = current;
695712 ++link_recursion;
696 retval = pseudo_append_elements(newpath, root, allocated, pcurrent, linkbuf, linklen, 0);
713 retval = pseudo_append_elements(newpath, root, allocated, pcurrent, linkbuf, linklen, 0, buf);
697714 --link_recursion;
698715 return retval;
699716 }
700717 }
701 /* okay, not a symlink, go ahead and append a slash */
702 *(current++) = '/';
703 *current = '\0';
718 /* we used to always append a slash here. now we don't; append_elements
719 * handles slashes, so just update the pointer.
720 */
704721 *pcurrent = current;
705722 return 1;
706723 }
707724
708725 static int
709 pseudo_append_elements(char *newpath, char *root, size_t allocated, char **current, const char *element, size_t elen, int leave_last) {
726 pseudo_append_elements(char *newpath, char *root, size_t allocated, char **current, const char *path, size_t elen, int leave_last, PSEUDO_STATBUF *sbuf) {
710727 int retval = 1;
711 const char * start = element;
728 /* a shareable buffer so we can cache stat results while walking the path */
729 PSEUDO_STATBUF buf;
730 buf.st_mode = 0;
731 const char * start = path;
712732 if (!newpath || !root ||
713733 !current || !*current ||
714 !element) {
734 !path) {
715735 pseudo_diag("pseudo_append_elements: invalid arguments.");
716736 return -1;
717737 }
718 while (element < (start + elen) && *element) {
738 if (!sbuf) {
739 /* we will use this buffer to hold "the current state of newpath".
740 * append_element will update that whenever it appends an element,
741 * and any calls back here from there will pass in the same buffer.
742 * if we didn't get one, we start using this local one, which will
743 * then get shared by anything we call.
744 */
745 sbuf = &buf;
746 if (*current > root) {
747 if (!pseudo_real_lstat || (pseudo_real_lstat(newpath, sbuf) == -1)) {
748 sbuf->st_mode = 0;
749 }
750 } else {
751 /* Don't call lstat on an empty path, or at all when we
752 * know that "root" is always directory-like.
753 */
754 sbuf->st_mode = S_IFDIR;
755 }
756 }
757 pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "paes: newpath %s, element list <%.*s>\n",
758 newpath, (int) elen, path);
759 while (path < (start + elen) && *path) {
719760 size_t this_elen;
720761 int leave_this = 0;
721 char *next = strchr(element, '/');
762 char *next = strchr(path, '/');
722763 if (!next) {
723 next = strchr(element, '\0');
764 next = strchr(path, '\0');
724765 leave_this = leave_last;
725766 }
726 this_elen = next - element;
727 switch (this_elen) {
728 case 0: /* path => '/' */
767 this_elen = next - path;
768 /* for a directory, we skip the append for empty path or ".";
769 * regular files get it appended so they can fail properly
770 * later for being invalid paths.
771 */
772 pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "element to add: '%.*s'\n",
773 (int) this_elen, path);
774 if (pseudo_append_element(newpath, root, allocated, current, path, this_elen, sbuf, leave_this) == -1) {
775 retval = -1;
729776 break;
730 case 1: /* path => '?/' */
731 if (*element != '.') {
732 if (pseudo_append_element(newpath, root, allocated, current, element, this_elen, leave_this) == -1) {
733 retval = -1;
734 }
735 }
736 break;
737 default:
738 if (pseudo_append_element(newpath, root, allocated, current, element, this_elen, leave_this) == -1) {
739 retval = -1;
740 }
741 break;
742 }
777 }
778 pseudo_debug(PDBGF_FILE | PDBGF_VERBOSE, "paes: append_element gave us '%s', current '%s'\n",
779 newpath, *current);
743780 /* and now move past the separator */
744 element += this_elen + 1;
781 path += this_elen + 1;
745782 }
746783 return retval;
747784 }
777814 newpath = pathbufs[pathbuf];
778815 pathbuf = (pathbuf + 1) % PATHBUFS;
779816 pathlen = strlen(path);
780 /* a trailing slash has special meaning */
781 if (pathlen > 0 && path[pathlen - 1] == '/') {
817 /* a trailing slash has special meaning, but processing
818 * trailing slashes is expensive.
819 */
820 while (pathlen > 0 && path[pathlen - 1] == '/') {
782821 trailing_slash = 1;
822 --pathlen;
783823 }
784824 /* allow a bit of slush. overallocating a bit won't
785825 * hurt. rounding to 256's in the hopes that it makes life
799839 * part of the string; you can't back up over it.
800840 */
801841 effective_root = newpath + rootlen;
802 *current++ = '/';
803842 *current = '\0';
804843 /* at any given point:
805 * current points to just after the last / of newpath
844 * path is not slash-terminated
845 * current points to the null byte immediately after the path
806846 * path points to the next element of path
807847 * newpathlen is the total allocated length of newpath
808848 * (current - newpath) is the used length of newpath
809849 */
810 if (pseudo_append_elements(newpath, effective_root, newpathlen, &current, path, pathlen, leave_last) != -1) {
811 --current;
812 if (*current == '/' && current > effective_root && !trailing_slash) {
813 *current = '\0';
850 int save_errno = errno;
851 if (pseudo_append_elements(newpath, effective_root, newpathlen, &current, path, pathlen, leave_last, 0) != -1) {
852 /* if we are expecting a trailing slash, or the path ended up being completely
853 * empty (meaning it's pointing at either effective_root or the beginning of
854 * the path), we need a slash here.
855 */
856 if ((current == effective_root) || trailing_slash) {
857 if ((current - newpath) < (int) newpathlen) {
858 *current++ = '/';
859 *current = '\0';
860 }
814861 }
815862 pseudo_debug(PDBGF_PATH, "%s + %s => <%s>\n",
816863 base ? base : "<nil>",
819866 if (lenp) {
820867 *lenp = current - newpath;
821868 }
869 errno = save_errno;
822870 return newpath;
823871 } else {
872 errno = save_errno;
824873 return 0;
825874 }
826875 }
843892 if (ld_preload && strlen(ld_preload)) {
844893 SETENV(PRELINK_LIBRARIES, ld_preload, 1);
845894 } else {
846 UNSETENV(PRELINK_LIBRARIES);
895 SETENV(PRELINK_LIBRARIES, "", 1);
847896 }
848897 }
849898 }
15651614 pseudo_util_debug_fd = fd;
15661615 }
15671616 free(pseudo_path);
1568 if (fd == -1)
1569 return -1;
1570 else
1571 return fd;
1617 return fd;
15721618 }
15731619
15741620 int
22 *
33 * Copyright (c) 2008-2012 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <assert.h>
3625 #include <sys/wait.h>
3726 #include <dlfcn.h>
3827
28 /* include this to get PSEUDO_PORT_* definitions */
29 #include "pseudo.h"
30
3931 /* used for various specific function arguments */
4032 #include <dirent.h>
4133 #include <fts.h>
4436 #include <grp.h>
4537 #include <pwd.h>
4638 #include <utime.h>
47
48 #include "pseudo.h"
39 #ifdef PSEUDO_PORT_LINUX_STATVFS
40 #include <sys/statvfs.h>
41 #endif
42
4943 #include "pseudo_wrapfuncs.h"
5044 #include "pseudo_ipc.h"
5145 #include "pseudo_client.h"
46
5247
5348 /* Types and declarations we need in advance. */
5449 #include "pseudo_wrapper_table.c"
9792 extern int (*pseudo_real_fsetxattr)(int, const char *, const void *, size_t, int);
9893 #endif
9994
95 static void libpseudo_atfork_child(void)
96 {
97 pthread_mutex_init(&pseudo_mutex, NULL);
98 pseudo_mutex_recursion = 0;
99 pseudo_mutex_holder = 0;
100 }
101
100102 static void
101103 _libpseudo_init(void) {
104 if (!_libpseudo_initted)
105 pthread_atfork(NULL, NULL, libpseudo_atfork_child);
106
102107 pseudo_getlock();
103108 pseudo_antimagic();
104109 _libpseudo_initted = 1;
120125 pseudo_init_one_wrapper(pseudo_function *func) {
121126 int (*f)(void) = (int (*)(void)) NULL;
122127
123 char *e;
124128 if (*func->real != NULL) {
125129 /* already initialized */
126130 return;
136140 f = dlsym(RTLD_NEXT, func->name);
137141 if (f) {
138142 *func->real = f;
139 } else {
140 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
141 char *s = func->name;
142 s += strlen(s) - 2;
143 /* *at() don't have to exist */
144 if (!strcmp(s, "at")) {
145 return;
146 }
147 #endif
148 e = dlerror();
149 if (e != NULL) {
150 pseudo_diag("No real function for %s: %s\n", func->name, e);
151 } else {
152 pseudo_diag("No real function for %s, but dlerror NULL.\n", func->name);
153 }
154 }
143 }
144 /* it turns out that in some cases, we get apparently-harmless
145 * errors if a function is missing, and that printing output
146 * for these seems unhelpful. so we no longer do that.
147 */
155148 }
156149
157150 void
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 #include <stdio.h>
1515 .\" version 2.1 along with this program; if not, write to the Free Software
1616 .\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1717 .TH pseudolog 1 "pseudo - pretending to be root"
18 .SH NAME
19 pseudolog \- pseudo log parser
1820 .SH SYNOPSIS
1921 .B pseudolog \-l
2022 .RB [ \-Pv ]
22 *
33 * Copyright (c) 2008-2010 Wind River Systems, Inc.
44 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the Lesser GNU General Public License version 2.1 as
7 * published by the Free Software Foundation.
8 *
9 * This program 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.
12 * See the Lesser GNU General Public License for more details.
13 *
14 * You should have received a copy of the Lesser GNU General Public License
15 * version 2.1 along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 * SPDX-License-Identifier: LGPL-2.1-only
176 *
187 */
198 /* We need _XOPEN_SOURCE for strptime(), but if we define that,
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
4
15 opt_verbose=
26
37 usage()
0 #
1 # SPDX-License-Identifier: LGPL-2.1-only
2 #
3
04 from string import Template
15 import os
26
7882 return
7983 path = Template(self.path).safe_substitute(item)
8084 if os.path.exists(path):
81 # print "We don't overwrite existing files."
85 # print("We don't overwrite existing files.")
8286 return
8387 self.file = open(path, 'w')
8488 if not self.file:
85 print "Couldn't open '%s' (expanded from %s), " \
89 print("Couldn't open '%s' (expanded from %s), " \
8690 "not emitting '%s'." % \
87 (path, self.path, template)
91 (path, self.path, template))
8892 return
8993
9094 def emit(self, template, item=None):
102106 self.file.write(templ.safe_substitute(item))
103107 self.file.write("\n")
104108 else:
105 print "Warning: Unknown template '%s'." % template
109 print("Warning: Unknown template '%s'." % template)
106110
107111 if self.file_per_item:
108112 if self.file:
11 @header
22 @body
33 /*
4 * Copyright (c) ${date} Wind River Systems; see
4 * Copyright (c) ${date} Peter Seebach/Seebs <seebs@seebs.net>; see
55 * guts/COPYRIGHT for information.
6 *
7 * [Note: copyright added by code generator, may be
8 * incorrect. Remove this if you fix it.]
9 *
10 * SPDX-License-Identifier: LGPL-2.1-only
611 *
712 * ${comment}
813 * ${rc_decl}
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Return vals: 2 - invalid arg list
36 # 1 - chroot failed
0 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
4 set -e
5
6 # Verify that special bits (setuid/setgid/sticky) are preserved.
7 #
8 # Return vals:
9 #
10 # 2 - Incorrect permissions
11 # All other nonzero - Unexpected command error
12 # 0 - Pass
13
14 trap "rm -rf d1 d2" EXIT
15
16 mkdir d1
17 chmod 7777 d1
18 cp -Rp d1 d2
19 perms=`ls -od d1 d2 | cut -c 1-10 | uniq`
20 if [ "$perms" != drwsrwsrwt ]; then
21 exit 2
22 fi
23
24
25 exit 0
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14 mkdir d1
25 touch d1/f1
36 mv d1 d2
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 env -i A=A B=B C=C env | grep -q "PSEUDO_"
36
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14 cat > execl_test.c << EOF
25 #include <unistd.h>
36 int main() {
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Verify normal operation...
36 uid=`env -i id -u`
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Verify normal operation...
36 uid=`id -u`
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Verify normal operation...
36 uid=`env -i id -u`
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Verify normal operation...
36 uid=`id -u`
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Test if we re-invoke pseudo that chroot still works
36
0 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
4
5 # Check that tclsh doesn't hang. Note that the timeout is not needed to
6 # reproduce the hang in tclsh, it's only there to ensure that this test script
7 # doesn't hang in case of a failing test.
8 timeout 2s bash -c "echo 'open {|true} r+' | tclsh"
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 mode() {
36 ls -l "$1" | awk '{ print $1 }'
47 }
8
9 rm -f a b
510
611 # Verify normal operation...
712 umask 022
00 #!/bin/bash
1 #
2 # SPDX-License-Identifier: LGPL-2.1-only
3 #
14
25 # Return vals: 2 - Unable to run xattr commands
36 # 1 - Invalid return value