ObjFW  History of src/OFSubprocess.m of 72c6e67a23fac1c5

History of file src/OFSubprocess.m at check-in 72c6e67a23fac1c5

2024-04-03
02:16
Change license to LGPLv3 only file: [104b24bd0b] check-in: [7413a728a7] user: js, branch: trunk, size: 893 [annotate] [blame] [check-ins using] [diff]
2024-01-02
17:17
Update copyright file: [54c0453ebb] check-in: [26ddd2e4e4] user: js, branch: trunk, size: 685 [annotate] [blame] [check-ins using] [diff]
2023-01-06
09:04
Update copyright file: [9698c0f2ee] check-in: [8939cbdb52] user: js, branch: trunk, size: 685 [annotate] [blame] [check-ins using] [diff]
2022-02-12
07:46
Update copyright file: [c37900d1dc] check-in: [1a86b8175b] user: js, branch: trunk, size: 685 [annotate] [blame] [check-ins using] [diff]
2021-05-01
03:02
Rename directories in src/platform file: [f686b80ad6] check-in: [4a6e3b42f5] user: js, branch: trunk, size: 685 [annotate] [blame] [check-ins using] [diff]
2021-03-30
21:06
Renamed src/OFProcess.m → src/OFSubprocess.m. Rename OFProcess to OFSubprocess file: [6a65d9f1d2] check-in: [79548b3c29] user: js, branch: trunk, size: 685 [annotate] [blame] [check-ins using] [diff]
2021-01-02
22:04
Update copyright file: [80953e8b4c] check-in: [374e1a1bfa] user: js, branch: trunk, size: 679 [annotate] [blame] [check-ins using] [diff]
2020-02-29
16:09
Move OFProcess to platform subdirectory file: [07d8cb1dd6] check-in: [5ca0376aa3] user: js, branch: trunk, size: 768 [annotate] [blame] [check-ins using] [diff]
2020-01-14
00:16
More consistent -[close] behavior

This means refusing to close twice, calling -[close] from -[dealloc] and
not calling -[cancelAsyncRequests].

Calling -[cancelAsyncRequests] in -[close] is too dangerous, as -[close]
gets called by -[dealloc]: If the queue is the last reference to the
object, at the point where -[cancelAsyncRequests] removes it from the
queue, the object will start to deallocate and call into
-[cancelAsyncRequests] again, which is still in the middle of removing
it and now finds itself with an inconsistent state. file: [dc3506687f] check-in: [3b43d51006] user: js, branch: trunk, size: 14308 [annotate] [blame] [check-ins using] [diff]

2020-01-02
01:51
Update copyright file: [7babcc132e] check-in: [c7f0229795] user: js, branch: trunk, size: 14211 [annotate] [blame] [check-ins using] [diff]
2019-03-09
10:48
Several minor fixes file: [c878371199] check-in: [c1e949a8c6] user: js, branch: trunk, size: 14208 [annotate] [blame] [check-ins using] [diff]
2019-03-08
00:35
Use dot syntax file: [c46d227848] check-in: [bceb7ed4c9] user: js, branch: trunk, size: 14201 [annotate] [blame] [check-ins using] [diff]
2019-01-03
19:13
Update copyright file: [ebfcdb4565] check-in: [0509d7a844] user: js, branch: trunk, size: 14249 [annotate] [blame] [check-ins using] [diff]
2018-07-28
18:45
Rename OFLocalization -> OFLocale file: [2efa587efd] check-in: [aa0384d1bf] user: js, branch: trunk, size: 14243 [annotate] [blame] [check-ins using] [diff]
2018-02-25
04:31
Reintroduce of_char{16,32}_t

There is no reliable way to check if C++ already defined those, as Clang
now defines char{16,32}_t even when it is not in C++ 11 mode. So we
cannot check if we are not in C++ 11 and then define them and otherwise
rely on the C++ 11 types. file: [bf28fd0153] check-in: [505137f25f] user: js, branch: trunk, size: 14267 [annotate] [blame] [check-ins using] [diff]

2018-01-03
19:49
Update copyright notice file: [49cc46fab4] check-in: [7e5c81e186] user: js, branch: trunk, size: 14246 [annotate] [blame] [check-ins using] [diff]
2017-11-19
11:04
Do not conform to OFReadyFor*Observing by default

Instead of letting OFStream conform to it, which itself does not really
conform to it, let all the subclasses that actually do conform to it. file: [b38c51b4de] check-in: [69749b6a5b] user: js, branch: trunk, size: 14223 [annotate] [blame] [check-ins using] [diff]

2017-10-17
00:33
Do not use implicit method return types

Instead, explicitly declare them, as OF_ASSUME_NONNULL_{BEGIN,END} does
not apply to implicit return types. This means that after this commit,
all init methods have a nonnull return type, as they should have. file: [47e26e30a9] check-in: [2f4e0df8be] user: js, branch: trunk, size: 14313 [annotate] [blame] [check-ins using] [diff]

2017-09-24
12:24
OFStream: Add support for async writes file: [7459e546ae] check-in: [481225349f] user: js, branch: trunk, size: 14222 [annotate] [blame] [check-ins using] [diff]
2017-07-22
20:50
Split OFDataArray into OFData and OFMutableData file: [fe4d78c81a] check-in: [c8f7b90082] user: js, branch: trunk, size: 14379 [annotate] [blame] [check-ins using] [diff]
2017-06-12
22:29
OFWriteFailedException: Add -[bytesWritten]

This allows retrieving the number of bytes already written before the
write failed, allowing to retry without writing data that has already
been written. file: [b2487462e5] check-in: [2ae01218ef] user: js, branch: trunk, size: 14385 [annotate] [blame] [check-ins using] [diff]

2017-06-05
17:36
Clean up exceptions a little

This removes several initializers that omitted the errNo. Removing those
forces to think about whether there is a meaningful errNo to set instead
of just omitting it. file: [a980832db2] check-in: [4f36894ce7] user: js, branch: trunk, size: 14117 [annotate] [blame] [check-ins using] [diff]

15:51
OFStream: Don't throw when at end of stream

Instead, let reads return 0 and let writes append after the end. file: [ea4c0fa50a] check-in: [f9cd4f9cab] user: js, branch: trunk, size: 14093 [annotate] [blame] [check-ins using] [diff]

2017-05-27
10:33
Add unistd.h wrapper to make things less horrible file: [5a7b7eae60] check-in: [d31ec806ef] user: js, branch: trunk, size: 14236 [annotate] [blame] [check-ins using] [diff]
10:08
Make things work with glibc 2.17 and Clang 3.4.2 file: [4c6eb1f07f] check-in: [ec36a82d68] user: js, branch: trunk, size: 14401 [annotate] [blame] [check-ins using] [diff]
2017-05-22
23:31
Make includes of unistd.h and fcntl.h conditional file: [c5ef32205f] check-in: [1287e77e04] user: js, branch: trunk, size: 14368 [annotate] [blame] [check-ins using] [diff]
2017-05-21
21:28
Prefix private methods with of_ instead of OF_

This matches Apple's style. file: [57b3b6c720] check-in: [6b77a5dd8b] user: js, branch: trunk, size: 14339 [annotate] [blame] [check-ins using] [diff]

2017-05-07
21:25
Use char{16,32}_t instead of of_char{16,32}_t file: [8cc38c1f3c] check-in: [37d2a81754] user: js, branch: trunk, size: 14339 [annotate] [blame] [check-ins using] [diff]
20:10
Small code style change

Casts are now written like types in variable declarations. file: [08732d57f8] check-in: [4af49a13c3] user: js, branch: trunk, size: 14360 [annotate] [blame] [check-ins using] [diff]

2017-01-09
17:36
Update copyright

Forgot to add 2017, even though I already did quite some changes in
2017. file: [e88047c399] check-in: [44f45c2e35] user: js, branch: trunk, size: 14320 [annotate] [blame] [check-ins using] [diff]

06:26
Add OFLocalization

This singleton gives access to all things locale, including the ability
to get localized strings.

This also adds the OF_LOCALIZED() macro. Its first argument is an ID for
the string to be localized and its second argument is the fallback
string to be used if it cannot retrieve the localized string. Following
that are variable name / value pairs to be replaced in the localized
string.

Getting translated strings is not implemented yet: Instead, it always
uses the fallback string.

This also switches ofhttp to localized strings. file: [b11627a172] check-in: [06bcb21fc7] user: js, branch: trunk, size: 14314 [annotate] [blame] [check-ins using] [diff]

2016-06-07
22:56
Add support for reusing OFStreams after close

Right now, this is only useful for OFTCPSocket, as this is the only
class so far not establishing the stream in the init method. However,
this adds the general infrastructure to allow reuse to all subclasses of
OFStream. file: [273ab6b21b] check-in: [1de551cb5f] user: js, branch: trunk, size: 14342 [annotate] [blame] [check-ins using] [diff]

2016-05-28
13:18
OFProcess: Improve environment handling on Win32

This makes sure to return NULL if the passed environment is nil and
makes sure that the environment is always terminated with 4 zero bytes,
even if the environment is empty. file: [e8f32c52e1] check-in: [0c7c53dd58] user: js, branch: trunk, size: 14325 [annotate] [blame] [check-ins using] [diff]

2016-01-03
00:43
Update copyright

While at it, also update the mail address. file: [5507b0fea2] check-in: [cec0f072f8] user: js, branch: 0.8, size: 14296 [annotate] [blame] [check-ins using] [diff]

00:41
Update copyright

While at it, also update the mail address. file: [03cde41f41] check-in: [2a27cf3000] user: js, branch: trunk, size: 14251 [annotate] [blame] [check-ins using] [diff]

2015-11-29
14:23
Clean up class extensions

Now that we can require GCC >= 4.6, we no longer need to fall back to
using a category on old compilers. file: [b05e103aab] check-in: [2aca549d60] user: js, branch: trunk, size: 14247 [annotate] [blame] [check-ins using] [diff]

14:02
Make use of fast enumeration

Now that we require GCC >= 4.6 anyway, there's no more reason to not use
it anymore. file: [3256a71833] check-in: [6b13727ce0] user: js, branch: trunk, size: 14266 [annotate] [blame] [check-ins using] [diff]

2015-10-19
22:15
Add platform.h & make platform defines consistent file: [b8e8f16191] check-in: [1ba08eebc5] user: js, branch: trunk, size: 14375 [annotate] [blame] [check-ins using] [diff]
2015-10-04
11:30
Better length checks for write / send calls file: [09488f3c9c] check-in: [fc73801932] user: js, branch: trunk, size: 14292 [annotate] [blame] [check-ins using] [diff]
2015-08-26
08:24
OFProcess: Send SIGTERM on close

SIGKILL was a little bit too much. file: [dc696d6c83] check-in: [3ff339cf42] user: js, branch: trunk, size: 14204 [annotate] [blame] [check-ins using] [diff]

2015-08-09
14:59
OFProcess: Use vfork() instead of fork() file: [30416b7510] check-in: [87b1318a27] user: js, branch: trunk, size: 14204 [annotate] [blame] [check-ins using] [diff]
2015-02-16
08:39
Explicitly pass errno to exceptions

The old behaviour where the exception would access errno directly on
creation of the exception was very fragile. The two main problems with
it were that sometimes it would pick up an errno even though none had
been set and in other cases that when the exception was created errno
had already been overridden.

This also greatly increases errno handling on Win32, especially in
conjunction with sockets. It can still be improved further, though. file: [5b951c5966] check-in: [62e2de30b9] user: js, branch: trunk, size: 14203 [annotate] [blame] [check-ins using] [diff]

2015-01-03
20:57
Update copyright file: [957d79c2fa] check-in: [cfd374b906] user: js, branch: trunk, size: 13657 [annotate] [blame] [check-ins using] [diff]
2014-12-14
17:35
OFProcess: Use posix_spawnp if available file: [8e7954549c] check-in: [e9984d112a] user: js, branch: trunk, size: 13651 [annotate] [blame] [check-ins using] [diff]
2014-12-13
16:53
Fix compilation with GCC file: [7cc001dd62] check-in: [12ceeb7853] user: js, branch: trunk, size: 12383 [annotate] [blame] [check-ins using] [diff]
2014-11-09
18:54
OFProcess: Do all memory allocation before fork() file: [ffa482714b] check-in: [30e5c5ea27] user: js, branch: trunk, size: 12241 [annotate] [blame] [check-ins using] [diff]
2014-10-24
19:12
OFProcess: Use _exit() on failure file: [02e2a0da24] check-in: [f45a6bb10b] user: js, branch: trunk, size: 11922 [annotate] [blame] [check-ins using] [diff]
2014-10-04
21:59
Add +[OFSystemInfo native8BitEncoding]

This replaces +[OFString nativeOSEncoding]. file: [940798f49a] check-in: [ec66e49dca] user: js, branch: trunk, size: 11983 [annotate] [blame] [check-ins using] [diff]

2014-06-21
21:43
Move all macros from OFObject.h to macros.h

This means that OFObject.h imports macros.h now, making it unnecessary
to manually import macros.h in almost every file. And while at it, also
import autorelease.h in OFObject.h, so that this doesn't need to be
manually imported in almost every file as well. file: [486d495193] check-in: [13ee56edf3] user: js, branch: trunk, size: 11946 [annotate] [blame] [check-ins using] [diff]

2014-06-16
15:06
Make return type of -[OFArray objects] const

After all, this might (and does for OFArray_adjacent!) return an
internal representation that must not be changed, so changes should be
prevented at compile-time. file: [bf59320c7a] check-in: [68d32a92c1] user: js, branch: trunk, size: 11990 [annotate] [blame] [check-ins using] [diff]

2014-05-29
21:27
Work around __block being used by old glibc file: [521a1f3185] check-in: [d1e559b643] user: js, branch: trunk, size: 11984 [annotate] [blame] [check-ins using] [diff]
2014-05-15
01:50
Don't define _*_SOURCE

Instead, just define _GNU_SOURCE when __GLIBC__ is defined. After all,
that's the only libc that doesn't work properly without any defines. file: [816fb9bfe7] check-in: [17be12b6e5] user: js, branch: trunk, size: 11893 [annotate] [blame] [check-ins using] [diff]

2014-04-26
00:40
Fix a few issues on LLP64 and Win64

LLP64 was mostly fast enumeration using an unsigned long for the state,
which can't store a pointer or a size_t on LLP64. This is now solved by
either throwing an OFOutOfRangeException if the value of the size_t is
bigger than ULONG_MAX or storing the pointer in the extra field (copied
using memcpy, as it's an array of unsigned long, which again would be
too small to store a pointer).

Win64 was mostly Microsoft not being able to decide whether a length is
a size_t, a DWORD, an int or an unsigned int (thus the different types
in places that seem to be almost the same). But since that would not be
confusing enough, a file descriptor is an int if it's for a file, but a
long long if it is for a socket. But of course, for ReadFile and friends
it's a DWORD instead of an int then. file: [f1314df72d] check-in: [4e59d2692f] user: js, branch: trunk, size: 11916 [annotate] [blame] [check-ins using] [diff]

2014-02-13
23:26
Use -std=c11 instead of -std=gnu11

Not using -std=gnu11 means _GNU_SOURCE does not get defined anymore,
therefore this commit also adds the required feature defines for glibc.

Additionally, this adds of_strdup in macros.h, as strdup is an
extension. file: [69b09cd9ef] check-in: [2f5af58573] user: js, branch: trunk, size: 11542 [annotate] [blame] [check-ins using] [diff]

2014-01-25
17:39
Generalize stream / socket related exceptions

This is in preparation for adding UDP sockets, as UDP sockets and TCP
sockets have no common superclass, as one is stream-oriented while the
other is packet-oriented.

Read and write exceptions are for any object now, as they are useful for
a lot more than just for streams, while the others (bind, listen, etc.)
are for any socket now (the type is id in this case, though, as there is
no common superclass). file: [754335c8dd] check-in: [8d2a5052fd] user: js, branch: trunk, size: 11519 [annotate] [blame] [check-ins using] [diff]

2014-01-16
23:38
Add +[OFString nativeOSEncoding].

This replaces OF_STRING_ENCODING_NATIVE, as a define was not flexible
enough (determining the native OS encoding at startup was not possible). file: [8b087c9ef5] check-in: [e54c8c0368] user: js, branch: trunk, size: 11519 [annotate] [blame] [check-ins using] [diff]

2014-01-04
00:24
Update copyright. file: [1aa806b8bb] check-in: [3b97fc3cd9] user: js, branch: trunk, size: 11519 [annotate] [blame] [check-ins using] [diff]
2013-11-23
01:27
Add OF_UNRECOGNIZED_SELECTOR. file: [4601d52af5] check-in: [6e19bd47ee] user: js, branch: trunk, size: 11513 [annotate] [blame] [check-ins using] [diff]
01:12
Add OF_INVALID_INIT_METHOD. file: [fbf3337ae3] check-in: [35dafd5c57] user: js, branch: trunk, size: 11581 [annotate] [blame] [check-ins using] [diff]
2013-08-15
19:00
Move private methods into private headers. file: [cf4262ee3c] check-in: [1d7a1cbca0] user: js, branch: trunk, size: 11526 [annotate] [blame] [check-ins using] [diff]
2013-06-22
12:12
Rework exceptions.

This mostly removes the argument for the class in which the exception
occurred. As backtraces were recently added for all platforms, the
passed class does not give any extra information on where the exception
occurred anymore.

This also removes a few other arguments which were not too helpful. In
the past, the idea was to pass as many arguments as possible so that it
is easier to find the origin of the exception. However, as backtraces
are a much better way to find the origin, those are not useful anymore
and just make the exception more cumbersome to use. The rule is now to
only pass arguments that might help in recovering from the exception or
provide information that is otherwise not easily accessible. file: [6a59691f03] check-in: [3d16a30f41] user: js, branch: trunk, size: 11311 [annotate] [blame] [check-ins using] [diff]

2013-06-17
08:44
Rename -[OFDataArray readDataArrayWithSize:].

It is now called -[readDataArrayWithCount:]. file: [499c5dab3d] check-in: [eceebefeab] user: js, branch: trunk, size: 11368 [annotate] [blame] [check-ins using] [diff]

2013-04-09
22:09
Fix incomplete of_char16_t migration. file: [4f94efa779] check-in: [8fe08864f8] user: js, branch: trunk, size: 11369 [annotate] [blame] [check-ins using] [diff]
2013-03-04
17:20
Replace BOOL with bool.

The only places where BOOL is left are those where they are required by
the ABI. file: [c2449bdcce] check-in: [c5ef582958] user: js, branch: trunk, size: 11354 [annotate] [blame] [check-ins using] [diff]

2013-02-12
18:22
Prefix all ivars with an underscore. file: [ef90137219] check-in: [e40729d406] user: js, branch: trunk, size: 11351 [annotate] [blame] [check-ins using] [diff]
2013-01-12
17:29
Rename *UsingEncoding: to *WithEncoding:.

This reverts 5362941.

Even though *UsingEncoding: is what Foundation uses, *WithEncoding: is
more natural and is more consistent with the rest. Also, this means this
restores it to the API of 0.7. file: [8542470fa0] check-in: [9ddd33a258] user: js, branch: trunk, size: 11279 [annotate] [blame] [check-ins using] [diff]

2013-01-09
22:24
Update copyright. file: [298fa3b559] check-in: [813c00ccf0] user: js, branch: trunk, size: 11286 [annotate] [blame] [check-ins using] [diff]
2013-01-08
03:41
OFProcess: Kill the process in -[close]. file: [d218abb29b] check-in: [382e89a033] user: js, branch: trunk, size: 11280 [annotate] [blame] [check-ins using] [diff]
03:13
OFProcess: Correctly handle Unicode env on Win32. file: [3b9c1e042c] check-in: [52f2c17f55] user: js, branch: trunk, size: 11102 [annotate] [blame] [check-ins using] [diff]
2013-01-07
14:49
OFProcess: Implement environment passing on Win32. file: [805ee3827f] check-in: [f51bceaa35] user: js, branch: trunk, size: 10726 [annotate] [blame] [check-ins using] [diff]
2012-12-26
14:10
OFProcess: Add a parameter for the environment. file: [2f6a6d8482] check-in: [891c0faad4] user: js, branch: trunk, size: 9936 [annotate] [blame] [check-ins using] [diff]
2012-12-22
15:37
Add -[doesNotRecognizeSelector:]. file: [77862565be] check-in: [917ce5754c] user: js, branch: trunk, size: 7954 [annotate] [blame] [check-ins using] [diff]
2012-12-15
23:31
OFString: Improved API for getting C strings. file: [ed7607de4d] check-in: [e2f4c1283c] user: js, branch: trunk, size: 8082 [annotate] [blame] [check-ins using] [diff]
2012-10-14
19:22
Add a missing include and fix a typo. file: [0d39282550] check-in: [9fce2c470e] user: js, branch: trunk, size: 8077 [annotate] [blame] [check-ins using] [diff]
2012-10-09
15:07
Make use of instancetype. file: [3ceef225bf] check-in: [fb515e8e24] user: js, branch: trunk, size: 8039 [annotate] [blame] [check-ins using] [diff]
2012-09-16
15:43
OFStream: Use lowlevel as prefix instead of _. file: [7f1558d0a7] check-in: [61c1932caf] user: js, branch: trunk, size: 7990 [annotate] [blame] [check-ins using] [diff]
2012-09-12
17:27
Split -[OFStream fileDescriptor].

It is now -[fileDescriptorForReading] and -[fileDescriptorForWriting].
The split was necessary as some stream types (e.g. OFProcess) don't have
a single file descriptor, but two. This allows to use those stream types
with OFStreamObserver as well. file: [fe517b8418] check-in: [440e95fd4a] user: js, branch: trunk, size: 7969 [annotate] [blame] [check-ins using] [diff]

2012-08-10
20:08
Directly use the runtime's autorelease pools.

This greatly improves performance, as it gets rid of the overhead of
OFAutoreleasePool. file: [769871dec1] check-in: [1255f3a11a] user: js, branch: trunk, size: 7808 [annotate] [blame] [check-ins using] [diff]

2012-07-12
01:28
Don't access isa directly. file: [a1bb959d69] check-in: [8892ae9fcc] user: js, branch: trunk, size: 7817 [annotate] [blame] [check-ins using] [diff]
2012-06-10
13:28
More API improvements. file: [8d0f0fd4b4] check-in: [11d3d69a22] user: js, branch: trunk, size: 7727 [annotate] [blame] [check-ins using] [diff]
2012-06-07
12:03
Rework OFStream API. file: [fb8b1060e5] check-in: [0d4059306a] user: js, branch: trunk, size: 7735 [annotate] [blame] [check-ins using] [diff]
2012-06-06
13:47
Slightly change the memory management API.

Also fix a bug where OFBigDataArray would waste memory. file: [6f88407ce3] check-in: [f7576a66ce] user: js, branch: trunk, size: 7734 [annotate] [blame] [check-ins using] [diff]

2012-03-12
11:54
OFArray: +[arrayWithCArray:length:] -> +[arrayWithObjects:count:].

This is required for the new array literals. file: [53a70ada66] check-in: [008be86a16] user: js, branch: trunk, size: 7728 [annotate] [blame] [check-ins using] [diff]

2012-02-28
14:29
Don't use alloca, as it could be unsafe. file: [39656659f7] check-in: [92412c8453] user: js, branch: 0.6, size: 7725 [annotate] [blame] [check-ins using] [diff]
2012-01-05
00:56
Update copyright. file: [be6e10ea82] check-in: [ce70e17b38] user: js, branch: trunk, size: 7681 [annotate] [blame] [check-ins using] [diff]
2011-12-01
02:16
Implement OFProcess for Win32. file: [afc4a2ba04] check-in: [e8b7d0dd0d] user: js, branch: trunk, size: 7675 [annotate] [blame] [check-ins using] [diff]
2011-10-11
22:35
OFProcess: Make programName and arguments optional init arguments. file: [3ee20593c1] check-in: [d605361c8b] user: js, branch: trunk, size: 4140 [annotate] [blame] [check-ins using] [diff]
22:30
Make it possible to close an OFProcess for writing. file: [7e13a65e14] check-in: [88a34646a4] user: js, branch: trunk, size: 3560 [annotate] [blame] [check-ins using] [diff]
21:37
Include stdlib.h instead of alloca.h. file: [eb421acf0f] check-in: [adf57d7dbf] user: js, branch: trunk, size: 3462 [annotate] [blame] [check-ins using] [diff]
2011-10-06
00:11
Add forgotten copyright. file: [e808b0835a] check-in: [85ba47f0ea] user: js, branch: trunk, size: 3462 [annotate] [blame] [check-ins using] [diff]
00:10
OFProcess: Make sure that we don't leave zombies behind. file: [12b36ce01a] check-in: [20ba008347] user: js, branch: trunk, size: 2915 [annotate] [blame] [check-ins using] [diff]
2011-10-05
23:26
Added: Add OFProcess.

Win32 implementation following later. file: [a1d37f278e] check-in: [02ab9aa8a9] user: js, branch: trunk, size: 2901 [annotate] [blame] [check-ins using]