375 Commits

Author SHA1 Message Date
Ben Gras
b015dae3e7 fix packman cd/net quirks 2007-04-13 17:13:53 +00:00
Ben Gras
dc67b37a10 more removing of warning and debug messages. 2007-04-13 14:00:31 +00:00
Ben Gras
4e0316611a update boot message for prerelease 2007-04-13 10:00:29 +00:00
Ben Gras
6b2ad6fdfd verbose message out 2007-04-12 17:01:54 +00:00
Ben Gras
a2b1a5134b . leave out hardware-fp code from library
. minor packman usage tweaks
 . kernel feature for printing version number
 . removed some verbose debug messages from vfs/mfs
2007-04-12 16:45:00 +00:00
Ben Gras
7dd225ffb2 delete redundant source 2007-04-12 16:30:59 +00:00
Ben Gras
2958815463 leave out debug message 2007-04-12 15:24:45 +00:00
Ben Gras
9200a8a253 feature to display svn version on kernel boot 2007-04-12 15:13:10 +00:00
Ben Gras
691b09f232 This will become 3.1.3 2007-04-12 14:31:16 +00:00
Ben Gras
d61a481169 put the zoneinfo library files directly in the lib/stdtime dir 2007-04-12 14:29:30 +00:00
Ben Gras
ef8ec86b78 Don't always update CMOS on shutdown. 2007-04-10 13:40:09 +00:00
Ben Gras
18e7b315a1 remove debug message 2007-04-05 13:58:35 +00:00
Ben Gras
01c0669075 Bigger shell 2007-04-05 12:30:24 +00:00
Ben Gras
57a5797045 no /usr/gnu/man in base system 2007-04-05 10:52:20 +00:00
Ben Gras
7b4cfd585a as needs more. 2007-04-05 10:47:04 +00:00
Ben Gras
3354ba1b6c . add /usr/share for zoneinfo
. throw out non-base /usr/gnu stuff
2007-04-05 10:37:22 +00:00
Ben Gras
21e61a600d /bin/echo is used during early bootstrap too. 2007-04-04 13:05:13 +00:00
Ben Gras
4928e42efb fix packman sort col, and make sort case-insensitive 2007-04-02 16:23:55 +00:00
Ben Gras
70b95c31bc version /usr/lib/crontab too 2007-04-02 16:18:46 +00:00
Ben Gras
9581f1596f explanations with common test3 errors. 2007-04-02 16:00:06 +00:00
Ben Gras
85198a280c fix some compiler warnings. 2007-04-02 15:10:07 +00:00
Ben Gras
647d1496f3 fix for warning 2007-04-02 14:45:56 +00:00
Ben Gras
321622a318 accept 'q' to exit. 2007-04-02 14:44:16 +00:00
Ben Gras
c0ed0de7d1 mount needs more memory to do system() for rs_down in the event a mount fails. 2007-04-02 14:41:06 +00:00
Ben Gras
c808aeb74e fix off-by-one error in 'all' 2007-04-02 12:09:43 +00:00
Ben Gras
735d605330 remove debug line 2007-03-30 15:55:36 +00:00
Ben Gras
056ac0a0d3 replace library time handling functions
mktime, tzset, asctime, ctime, gmtime, localtime, strftime
with zoneinfo implementations in src/commands/zoneinfo, referenced
from src/lib/stdtime/Makefile.in.
2007-03-30 15:36:49 +00:00
Ben Gras
6ccd37a982 fix for filenames with paths 2007-03-30 15:35:15 +00:00
Ben Gras
0be7f44224 . added zoneinfo to build, with fixes for minix
. now using zoneinfo date command, instead of commands/simple/date.c
2007-03-30 15:32:55 +00:00
Ben Gras
a2d3b518d8 rename svn revision variable to one with underscore, to not pollute
application namespace
2007-03-30 15:17:32 +00:00
Ben Gras
7507ebfeca remove debug message 2007-03-30 15:17:03 +00:00
Ben Gras
f3f2e92191 move date(1) to minix manual page place. 2007-03-26 11:24:13 +00:00
Ben Gras
288ee57135 tz database is in /usr/share/zoneinfo. 2007-03-26 11:22:20 +00:00
Ben Gras
fedb5c0368 make way for new date(1). 2007-03-26 11:21:54 +00:00
Ben Gras
3b2c65e323 Import of original zoneinfo code and database - tzcode
old-tzcode-32-bit-output and tzdata2007d.
2007-03-26 10:55:16 +00:00
Ben Gras
5596ab1ec7 Minor corrections by ASW. 2007-03-22 16:24:06 +00:00
Ben Gras
75f8ceb70e let tty do sys_physcopy; needed for loadfont. 2007-03-22 16:15:33 +00:00
Ben Gras
31c62a7347 include svn revision number in <minix/sys_config.h>, printed by kernel
at startup, to easily identify releases.
2007-03-21 13:35:06 +00:00
Ben Gras
70ab580d6b Let user exit without pressing ^C 2007-03-21 09:54:09 +00:00
Ben Gras
bd2ddd5fd4 after enqueue()ing a process, only pick_proc() a new one if the current
process is not PREEMPTIBLE (or it's not ready, or there isn't a current
process yet). This fixes a case where a process that isn't
PREEMPTIBLE actually gets preempted. (This solves a race condition
between CLOCK and SYSTEM.)
2007-03-21 09:45:01 +00:00
Ben Gras
4e63801916 a script to decode stack traces. 2007-03-21 09:33:39 +00:00
Ben Gras
1588a9ba77 slightly more accurate and verbose sanity checking 2007-03-15 10:57:39 +00:00
Ben Gras
98410fd5fe remove extra arg 2007-03-15 10:54:35 +00:00
Ben Gras
5c4a1e5c95 Slightly more flexible packman. 2007-03-12 16:55:02 +00:00
Ben Gras
9843d7a625 For /dev/mem, map in memory to be copied to memory's own address space
one page at a time, and use safecopies to copy it to the requesting
process.

This lets /dev/mem access the entire physical address space, as the minix
page tables only allow access by default to physical RAM, which breaks
e.g. the VESA X driver in some cases.
2007-03-09 16:03:19 +00:00
Ben Gras
f4b7a16f7b output CRLF instead of just LF to serial 2007-03-09 15:45:35 +00:00
Ben Gras
3fcf9fde61 Make /dev/mouse an alias for /dev/kbdaux for X 2007-03-08 16:04:59 +00:00
Ben Gras
6d50591226 . let kernel use read_tsc() from sysutil library
. read_tsc() in sysutil library saves edx and eax now
 . added read_tsc_64() by Antonio Mancina to load tsc into
   a 64-bit data type directly
 . deleted read_tsc.h in favour of a prototype in <minix/syslib.h>
2007-03-08 15:39:14 +00:00
Ben Gras
4148c24393 Russian setup document contributed by Roman Ignatov. 2007-03-08 15:18:57 +00:00
Ben Gras
454bb40129 correct references to manpage section 9 to 1x. 2007-03-05 16:43:03 +00:00
Ben Gras
f8eb059bb9 move manpages in section 9 to new section 1x. 2007-03-05 16:36:40 +00:00
Ben Gras
5f46b37a3d Rename section 9 to section 1x 2007-03-05 16:32:30 +00:00
Ben Gras
97fa05d773 Merge of kjb's update to man system to move section 9 to 1x. 2007-03-05 16:31:39 +00:00
Ben Gras
52b71b2396 Minor change to path lookup that fixes the bug that creating a file
as a first component of an absolute path failed (e.g. 'touch /file'),
due to leading slashes not being skipped in the processed path counter
in that case, causing create to fail.
2007-02-28 13:13:39 +00:00
Ben Gras
84b77d5bfd explicitly mask byte i/o values to bytes. 2007-02-26 11:52:04 +00:00
Ben Gras
8c9e1cf4c5 Uninitialized vector entry? 2007-02-23 20:58:10 +00:00
Ben Gras
92e57afdf3 Explicitly mask off 8-bit values (so new sanity check doesn't trip) 2007-02-23 20:53:32 +00:00
Ben Gras
3b08825d85 . service tells you which device it couldn't stat
. bigger rs and ramdisk for drivers
. sanity check for pv_set macro for oversized arguments
2007-02-23 18:22:46 +00:00
Ben Gras
bf08c90e74 Slew of debugging / sanity check features. 2007-02-23 18:21:19 +00:00
Ben Gras
238ae978ba Don't allow sys_kill to SELF alltogether. 2007-02-23 13:01:55 +00:00
Ben Gras
a9f2f36f46 If a process does sys_kill on SELF (such as in panic() of servers and drivers
if a PM exit fails, until they are compiled with the new panic() function that
is), don't reply to it as the endpoint has been cleared.
2007-02-23 12:55:29 +00:00
Ben Gras
be30a639cd Don't sys_kill SELF if a PM exit fails; just generate a fault to get
us killed through the kernel with PM finding out.

This makes it unnecessary for servers and drivers to be able to do
sys_kill generally, so KILL can go out of /etc/drivers.conf.
2007-02-23 12:54:02 +00:00
Ben Gras
1bf8a2e8bf Changed logic checking for valid device. 2007-02-23 10:21:55 +00:00
Ben Gras
d75a1c3f38 Note about mkfs needing more memory after r2751. 2007-02-23 08:33:33 +00:00
Ben Gras
3bb73b431b add/re-enable at_wini debug output 2007-02-21 17:49:35 +00:00
Ben Gras
2d95b37f12 Copypaste bug. 2007-02-21 17:01:43 +00:00
Ben Gras
77474b28e8 Typo reported by Al Woodhull. 2007-02-21 15:17:28 +00:00
Ben Gras
f7992c94ec at_wini also needs a pci_reserve() for the pci compatability device, if
present, for dma.
2007-02-20 18:42:43 +00:00
Ben Gras
168d766f32 . pci driver now returns devices, even when they have been pci_reserve()d
. pci_reserve() returns an error on devices that have already been reserved,
  instead of panic()ing; the pci_reserve() library call still panics,
  pci_reserve_ok() returns an int.
. this allows at_wini to use the instance value as intended, as all devices
  are seen, even reserved ones
. only devices actually used by at_wini are pci_reserve()d
. pci doesn't release devices based on argv[0], as at_wini both have the
  same name and multiple instances won't work together properly
2007-02-20 17:09:19 +00:00
Ben Gras
825f29fd89 TZ update for new US/Canadian DST rules, fixed by Al Woodhull. 2007-02-20 16:29:26 +00:00
Ben Gras
cbb67705d5 Include svn revision number in iso filename when doing build
based on svn export.
2007-02-19 16:40:33 +00:00
Ben Gras
f150b11a7b Removed args debugging line 2007-02-16 15:58:05 +00:00
Ben Gras
654f6faf05 don't let /dev/mem read beyond top of physical memory 2007-02-16 15:57:05 +00:00
Ben Gras
49d2195722 made default wakeup time correct 2007-02-16 15:56:00 +00:00
Ben Gras
448376ee7e . use library function to parse memory string
. remove unused variables and some other gcc warnings
2007-02-16 15:55:20 +00:00
Ben Gras
3275602598 . made memory parsing function into a library call
(moved 'struct memory' to <minix/type.h> for this library call)
 . removed some debugging messages from pci library
2007-02-16 15:54:28 +00:00
Ben Gras
a47531cc97 removed some verbose messages 2007-02-16 15:53:10 +00:00
Ben Gras
0d5c50f3fc Update CMOS time at shutdown time. 2007-02-16 15:52:39 +00:00
Ben Gras
3f58857ce9 removed/optionalized debugging messages 2007-02-16 15:50:49 +00:00
Ben Gras
b267d42531 removed or optionalized verbose/debugging messages 2007-02-16 15:50:30 +00:00
Ben Gras
1ff8616378 set 'w_testing' during w_identify(). this means 0-tolerance to
timeouts, and an ATA_IDENTIFY timeout will cause the ATAPI_IDENTIFY
to be skipped, making the cd probe a lot faster.
2007-02-12 13:35:33 +00:00
Ben Gras
cb2f124830 mkfs needs more memory for the boot ramdisk. 2007-02-12 13:10:06 +00:00
Ben Gras
bd27c5240b Typo's. 2007-02-12 12:27:43 +00:00
Ben Gras
b857dec78d Don't complain about missing ip address. 2007-02-09 16:28:34 +00:00
Ben Gras
1d300550cf Memory requirements a bit more now with mfs processes 2007-02-09 16:27:59 +00:00
Ben Gras
c6f8154df0 use shorter ata timeout for identify commands when running from cd
to shorten probe time.
2007-02-09 15:58:33 +00:00
Ben Gras
304471a107 Fixes for /usr/xbin binaries bootstrap dir. 2007-02-08 17:41:40 +00:00
Ben Gras
20a13246a8 include /usr/xbin bootstrap dir in $PATH 2007-02-08 16:48:34 +00:00
Ben Gras
9f2f3dd488 don't call mkdep with an absolute path 2007-02-08 16:26:20 +00:00
Ben Gras
df9326a340 Use temporary binary directory as bootstrap 2007-02-08 16:18:48 +00:00
Ben Gras
624f17ee04 Extend cdprobe probe list to c1, and reorder minors to do most-likely
first.

Make at_wini include instance number in error messages.
2007-02-08 15:56:58 +00:00
Ben Gras
ebde52a9bc supply instance to 2nd at_wini instance.
requires a little cooperation from at_wini.
2007-02-08 14:23:03 +00:00
Ben Gras
a12c7ad963 Start a 2nd copy of at_wini, for /dev/c1*. This requires a slightly
larger rs.
2007-02-08 14:04:59 +00:00
Ben Gras
63a271200e Make /dev/c1* device nodes on disk and on the boot ramdisk.
. include c1* nodes in std in MAKEDEV
 . this requires a slightly larger shell
 . this requires a larger blocksize on the boot ramdisk (to fit
   /dev/ in direct blocks for mkfs with a proto file)
 . also more inodes and kB's on the boot ramdisk
2007-02-08 13:51:35 +00:00
Ben Gras
3c907e6ef1 Sanity check in clock - process is supposed to be runnable when it's
interrupted.
2007-02-08 12:59:29 +00:00
Ben Gras
8ea438ae93 Retired DEV_{READ,WRITE,GATHER,SCATTER,IOCTL} (safe versions *_S are to
be used and drivers should never receieve these 'unsafe' variants
any more).
2007-02-07 16:22:19 +00:00
Ben Gras
41e9fedf87 Mostly bugfixes of bugs triggered by the test set.
bugfixes:
 SYSTEM:
 . removed
        rc->p_priv->s_flags = 0;
   for the priv struct shared by all user processes in get_priv(). this
   should only be done once. doing a SYS_PRIV_USER in sys_privctl()
   caused the flags of all user processes to be reset, so they were no
   longer PREEMPTIBLE. this happened when RS executed a policy script.
   (this broke test1 in the test set)

 VFS/MFS:
 . chown can change the mode of a file, and chmod arguments are only
   part of the full file mode so the full filemode is slightly magic.
   changed these calls so that the final modes are returned to VFS, so
   that the vnode can be kept up-to-date.
   (this broke test11 in the test set)

 MFS:
 . lookup() checked for sizeof(string) instead of sizeof(user_path),
   truncating long path names
   (caught by test 23)
 . truncate functions neglected to update ctime
   (this broke test16)

 VFS:
 . corner case of an empty filename lookup caused fields of a request
   not to be filled in in the lookup functions, not making it clear
   that the lookup had failed, causing messages to garbage processes,
   causing strange failures.
   (caught by test 30)
 . trust v_size in vnode when doing reads or writes on non-special
   files, truncating i/o where necessary; this is necessary for pipes,
   as MFS can't tell when a pipe has been truncated without it being
   told explicitly each time.
   when the last reader/writer on a pipe closes, tell FS about
   the new size using truncate_vn().
   (this broke test 25, among others)
 . permission check for chdir() had disappeared; added a
   forbidden() call
   (caught by test 23)

new code, shouldn't change anything:
 . introduced RTS_SET, RTS_UNSET, and RTS_ISSET macro's, and their
   LOCK variants. These macros set and clear the p_rts_flags field,
   causing a lot of duplicated logic like

       old_flags = rp->p_rts_flags;            /* save value of the flags */
       rp->p_rts_flags &= ~NO_PRIV;
       if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);

   to change into the simpler

       RTS_LOCK_UNSET(rp, NO_PRIV);

   so the macros take care of calling dequeue() and enqueue() (or lock_*()),
   as the case may be). This makes the code a bit more readable and a
   bit less fragile.
 . removed return code from do_clocktick in CLOCK as it currently
   never replies
 . removed some debug code from VFS
 . fixed grant debug message in device.c
 
preemptive checks, tests, changes:
 . added return code checks of receive() to SYSTEM and CLOCK
 . O_TRUNC should never arrive at MFS (added sanity check and removed
   O_TRUNC code)
 . user_path declared with PATH_MAX+1 to let it be null-terminated
 . checks in MFS to see if strings passed by VFS are null-terminated
 
 IS:
 . static irq name table thrown out
2007-02-01 17:50:02 +00:00
Ben Gras
fa59af2bc0 Also exclude /home 2007-02-01 17:10:03 +00:00
Ben Gras
047847e628 simpler /usr/bin/vi check 2007-02-01 17:09:49 +00:00
Ben Gras
5358dc42bf Only install /usr/bin/vi as a hardlink to elvis if there's nothing already
there (so e.g. nvi isn't overwritten).
2007-01-31 13:00:39 +00:00
Ben Gras
ce5add84e8 put mfs in /sbin, where mount expects it. 2007-01-24 15:50:04 +00:00
Ben Gras
e8edfe876d . no .vimrc in standard user's dirs
. install a vi hardlink to elvis
2007-01-22 17:08:36 +00:00
Ben Gras
73e4e31376 Don't reply to the caller on RS_DOWN until process is actually dead -
otherwise (e.g.) mounts right after an unmount of the same device don't
work (duplicate label).
2007-01-22 16:44:03 +00:00
Ben Gras
f9e4768eb4 No /usr/src.* shenanigans any more. 2007-01-22 15:47:40 +00:00
Ben Gras
82ae9b9c5c Install sources in /usr/bigsrc, not /usr/src/commands. 2007-01-22 15:42:40 +00:00
Ben Gras
980b58d8d2 ramdisk can be set only once. 2007-01-22 15:37:26 +00:00
Ben Gras
2194bc0310 vfs/mount/rs/service changes:
. changed umount() and mount() to call 'service', so that it can include
   a custom label, so that umount() works again (RS slot gets freed now).
   merged umount() and mount() into one file to encode keep this label
   knowledge in one file.
 . removed obsolete RS_PID field and RS_RESCUE rescue command
 . added label to RS_START struct
 . vfs no longer does kill of fs process on unmount (which was failing
   due to RS_PID request not working)
 . don't assume that if error wasn't one of three errors, that no error
   occured in vfs/request.c
mfs changes:
 . added checks to copy statements to truncate copies at buffer sizes
   (left in debug code for now)
 . added checks for null-terminatedness, if less than NAME_MAX was copied
 . added checks for copy function success
is changes: 
 . dump rs label
drivers.conf changes:
 . added acl for mfs so that mfs can be started with 'service start',
   so that a custom label can be provided
2007-01-22 15:25:41 +00:00
Ben Gras
d954a122f7 Added register clobber warning to read_tsc. 2007-01-22 15:15:30 +00:00
Philip Homburg
78fe72e198 Many more IDs. 2007-01-19 17:27:51 +00:00
Philip Homburg
7d6b1dcf1e PCI IDs for Accton SMC2-1211TX 2007-01-18 11:40:13 +00:00
Ben Gras
a6ab1cbd34 remove debug (%d) in fsck 2007-01-16 16:52:51 +00:00
Ben Gras
722f1b2b9f . added checks for buffer sizes in sys_datacopy() functions in mfs,
print debug message if copy is truncated
. increased buffer in lookup() to be PATH_MAX instead of NAME_MAX
. sanity check in fetch_name() in vfs to see if name fits, and
  is null-terminated
. first check i < NAME_MAX, then string[i] in search_dir, as we're
  not supposed to look at string[NAME_MAX]
2007-01-16 14:50:10 +00:00
Ben Gras
94b936d7c1 . added super-user check for mount
. corrected device match for unmount (otherwise unmount would
  proceed with bogus mount slot, often sending messages to 0 (PM))
. added some sanity checking to fs process number
. made fs_sendrec PRIVATE to request.c
2007-01-16 13:57:35 +00:00
Ben Gras
8412423248 Fsck needs more memory for bigger filesystems 2007-01-16 12:59:13 +00:00
Ben Gras
bcbac65a07 Don't panic if opening a block device fails. 2007-01-12 17:16:51 +00:00
Ben Gras
80e2b3ade6 Truncate s_max_size at LONG_MAX, now that off_t is signed. 2007-01-12 16:53:12 +00:00
Ben Gras
f47aa04a30 . removed readclock command and cmos driver.
. replaced by a readclock 'driver' that runs once, a re-imported version
  of the minix 2.0.4 readclock command.
. this has also restored cmos writing.
. readclock wrapper script calls service command to run /bin/readclock.drv
  once.
2007-01-12 16:35:04 +00:00
Ben Gras
f65b3b8fbf Use bitwise not instead of logical not on PIE flag when disabling periodic
interrupts to avoid clobbering register B. This seems to have fixed the
corrupting-CMOS bug when enabling profiling.
2007-01-12 16:33:41 +00:00
Ben Gras
b01aff70d2 use servers/inet/mq.[ch] to queue messages using mq_queue() in
libdriver.  at_wini now queues messages it can't handle it receives when
waiting for an interrupt. this way it can do receive(ANY) and timeouts
should be working again (were broken for VFS, as with the advent of VFS,
at_wini could get requests from a filesystem while it was waiting for an
interrupt - as a hack, the receive() was changed to receive(HARDWARE)).

Added mq.c to libdriver, and made libdriver an actual library that
drivers link with -L../libdriver -ldriver. (So adding files, if
necessary, is easier next time.)
2007-01-12 13:33:12 +00:00
Ben Gras
8b3ddfc19f In some configurations of non-working networking, packman will hang a
very long time or forever retrieving the packages list. It's tricky to
test connectivity automatically, so ask every time.  Reported by
Stanislav Kapustin <kapustin_stanislav@hotmail.com>.
2007-01-11 14:35:29 +00:00
Ben Gras
f307d84cda Zlib is now an optional package. 2007-01-09 17:08:31 +00:00
Ben Gras
61b9193ced Take arch+version specific packages List file. 2007-01-08 15:10:27 +00:00
Philip Homburg
7d46116e47 ctty command without parameters to disable serial console. 2007-01-08 14:30:11 +00:00
Philip Homburg
9092146be7 VFS cleanup (mostly open). 2007-01-05 16:36:55 +00:00
Ben Gras
753f7bebde Don't let rs232 code send REVIVEs. 2007-01-04 12:06:04 +00:00
Ben Gras
324c6f583d Use svn instead of cvs 2006-12-22 16:43:30 +00:00
Ben Gras
dfaf30e54d interface.h is unused (remainder from Ingmar's work) 2006-12-22 15:50:17 +00:00
Ben Gras
53a6054b66 arch/i386/include/protect.h is unnecessary; add make.conf to etc/ and
note about it in docs/UPDATING.
2006-12-22 15:48:27 +00:00
Ben Gras
6f77685609 Split of architecture-dependent and -independent functions for i386,
mainly in the kernel and headers. This split based on work by
Ingmar Alting <iaalting@cs.vu.nl> done for his Minix PowerPC architecture
port.

 . kernel does not program the interrupt controller directly, do any
   other architecture-dependent operations, or contain assembly any more,
   but uses architecture-dependent functions in arch/$(ARCH)/.
 . architecture-dependent constants and types defined in arch/$(ARCH)/include.
 . <ibm/portio.h> moved to <minix/portio.h>, as they have become, for now,
   architecture-independent functions.
 . int86, sdevio, readbios, and iopenable are now i386-specific kernel calls
   and live in arch/i386/do_* now.
 . i386 arch now supports even less 86 code; e.g. mpx86.s and klib86.s have
   gone, and 'machine.protected' is gone (and always taken to be 1 in i386).
   If 86 support is to return, it should be a new architecture.
 . prototypes for the architecture-dependent functions defined in
   kernel/arch/$(ARCH)/*.c but used in kernel/ are in kernel/proto.h
 . /etc/make.conf included in makefiles and shell scripts that need to
   know the building architecture; it defines ARCH=<arch>, currently only
   i386.
 . some basic per-architecture build support outside of the kernel (lib)
 . in clock.c, only dequeue a process if it was ready
 . fixes for new include files

files deleted:
 . mpx/klib.s - only for choosing between mpx/klib86 and -386
 . klib86.s - only for 86

i386-specific files files moved (or arch-dependent stuff moved) to arch/i386/:
 . mpx386.s (entry point)
 . klib386.s
 . sconst.h
 . exception.c
 . protect.c
 . protect.h
 . i8269.c
2006-12-22 15:22:27 +00:00
Ben Gras
f7984144d5 . fsck needs more memory
. fsck must deal with s_max_file_size in superblock being larger
   than LONG_MAX now that off_t is signed
2006-12-22 13:40:37 +00:00
Philip Homburg
dac2e8fcc9 More detailed upgrade procedure. 2006-12-22 13:36:18 +00:00
Ben Gras
da42185e1c Removed verbose statements from vfs and mfs 2006-12-22 11:54:42 +00:00
Ben Gras
4daf936bd2 BSD versions of strcasecmp() and strncasecmp() after a bug
in strcasecmp() reported by Rogier Meurs <rogier@meurs.org>.
2006-12-19 13:15:16 +00:00
Ben Gras
7d012272a1 make pci driver run as root, so it can call procstat 2006-12-15 15:56:36 +00:00
David van Moolenbroek
d4e6fe3546 Setjmp/longjmp updates and cleanup. 2006-12-08 16:23:18 +00:00
Philip Homburg
170a72fd61 Missing lseek64 library functions. 2006-12-07 20:01:43 +00:00
Philip Homburg
8a2a957d49 Some 64-bit file offset changes that were left out accidentally in the first
commit.
2006-12-06 15:21:27 +00:00
Philip Homburg
bafc45a309 First cut at 64-bit file offsets in block devices for mkfs/fsck. 2006-11-27 14:21:43 +00:00
Philip Homburg
828e87862f Replaced <servers/fs/...> with <servers/mfs/...> 2006-11-24 14:04:01 +00:00
Philip Homburg
d84dd06b3f Better error handling in _mount.c 2006-11-24 14:01:14 +00:00
Philip Homburg
2032e23e8c chmod needs more space 2006-11-24 13:59:13 +00:00
Philip Homburg
0438bca7aa Small image doesn't fit on boot floppy. 2006-11-24 13:57:37 +00:00
Ben Gras
1030187965 Revert back to previous minised 2006-11-17 16:12:08 +00:00
Ben Gras
03be184bd6 Fix warnings (Ingmar Alting) 2006-11-10 18:19:38 +00:00
Ben Gras
f8a5db5ab0 Fix some warnings (by Ingmar Alting) 2006-11-10 18:13:02 +00:00
Philip Homburg
d83e4d3b2e Added missing defines in include/minix/vfsif.h 2006-11-10 15:05:32 +00:00
Philip Homburg
ca448f0b0f Getdents implementation in library/vfs/mfs.
Changed readdir, etc. to use getdents
2006-11-09 16:22:54 +00:00
Ben Gras
12eb228aae Typo reported by ville.solarius@gmail.com 2006-11-06 18:02:22 +00:00
Ben Gras
07c4c00181 set $PATH so /usr/local/egrep isn't used; also exclude /var/log from package 2006-11-03 14:47:28 +00:00
Ben Gras
1250e94d56 New sed manpage 2006-11-02 16:51:04 +00:00
Ben Gras
f6436dc1a0 old sed out, new sed in 2006-11-02 16:48:47 +00:00
Ben Gras
aa8206941c New sed 2006-11-02 16:48:15 +00:00
Ben Gras
64dbdd855d obsolete server. 2006-11-01 16:53:45 +00:00
Philip Homburg
954ad990e5 at_wini now calls pci_reserve. 2006-11-01 14:55:00 +00:00
Ben Gras
86303b3024 Explicit conversion from O_ACCMODE to minix [RW]_BIT is clearer
and catches bogus values (such as 3).
2006-11-01 14:17:47 +00:00
Philip Homburg
0c1d433f60 rs changes (also use driver configurations in the image ramdisk) 2006-10-31 13:35:04 +00:00
Ben Gras
9ac537eb7c Ignore .svn dir as well as CVS dir. 2006-10-30 16:11:57 +00:00
Ben Gras
7195fe3325 System statistical and call profiling
support by Rogier Meurs <rogier@meurs.org>.
2006-10-30 15:53:38 +00:00
Ben Gras
fa0ba56bc9 Merge of VFS by Balasz Gerofi with Minix trunk. 2006-10-25 13:40:36 +00:00
Ben Gras
21ed846479 More memory for these drivers 2006-10-25 13:39:53 +00:00
Ben Gras
65a1d21963 Part of wait()/waitpid() fix in revision 2629:2634 in PM - kernel
unblocks a process that has no priority (stopped with sys_nice()
and PRIO_STOP) and reschedules it if that gives it RTS flags of 0.
2006-10-25 13:38:31 +00:00
Ben Gras
f84653d908 Default amount of memory for tests (some ran out of memory) 2006-10-25 13:35:03 +00:00
Philip Homburg
7c0fda0932 Include kernel/priv.h for rs/manager.h 2006-10-25 13:07:58 +00:00
Ben Gras
1e656b349d . processes stay ZOMBIE, even after wait(), to avoid wrongly seeing them
as living processes  before they are cleaned up (fixes
  wait()/waitpid() hanging forever on previously-ZOMBIE processes)

. stop processes from running using sys_nice() with PRIO_STOP
  when a handled signal is delivered, before computing 
  stack locations for sys_sigsend(). (fixes race condition
  when runnable processes get signals, and e.g. get scheduled
  before FS sends a reply to unpause(), which can make the
  signal stack location wrong.)
2006-10-25 11:29:43 +00:00
Ben Gras
4933f34715 Don't do make clean if flex Makefile doesn't exist. 2006-10-24 14:20:59 +00:00
Philip Homburg
f9ccfca2a1 (Incomplete) support for access control in PCI (pci_set_acl).
-script argument to service for crash recovery scripts
-config argument to service for driver resource configuration
restart command in service to restart a driver after a crash (for use in
crash recovery scripts).
down and refresh now take labels instead of pids.
verious changes in rs to make this work.
2006-10-20 15:01:32 +00:00
Philip Homburg
fd448c332b Access control in do_sdevio and do_vdevio 2006-10-20 14:46:55 +00:00
Philip Homburg
dd3ee082b2 Initialize priv from user supplied priv structure in SYS_PRIV_INIT.
Added SYS_PRIV_USER call to downgrade a privileged process to a user process.
2006-10-20 14:42:48 +00:00
Philip Homburg
1ce2f75627 Additional ptrace commands for fault injection. 2006-10-20 14:14:08 +00:00
Philip Homburg
be928f01a5 Nice(3) implementation 2006-10-20 14:10:53 +00:00
Philip Homburg
0b2c167c48 Bigger ramdisk 2006-10-20 13:59:42 +00:00
Philip Homburg
8082aad9b2 Use /usr/tmp as temp dir for compiling imgrd_s.s 2006-10-20 13:58:45 +00:00
Philip Homburg
61bbef2f4e More stack for the log driver. 2006-10-20 13:54:14 +00:00
Ben Gras
140afcfb7d Use size-dependant no. of words, with OPEN_MAX as default for fd_set size. 2006-10-06 15:45:13 +00:00
Ben Gras
1f3560229d Fix for clean target. 2006-10-06 15:44:41 +00:00
Ben Gras
84c93dd20e Remove objects in aes subdir too 2006-10-05 09:58:50 +00:00
Ben Gras
b5a6e7bbb0 make clean in ibm subdir too 2006-10-05 09:56:17 +00:00
Ben Gras
810de3b474 Leftover junk 2006-10-05 09:55:29 +00:00
Ben Gras
3b295eb002 Don't include this in the distribution. 2006-10-05 09:53:42 +00:00
Ben Gras
cbfa0f4fb8 Change select() so that only as many words as necessary for the 'nfds'
argument from the fd bitmasks are copied from and back to userspace. This
solves an ABI dependency on OPEN_MAX. If nfds is too big for the current
OPEN_MAX, select() fails (but that's relatively easy to fix by 'just'
recompiling the system and not the application binaries), but if it's
smaller, binaries keep working.
2006-10-04 13:28:38 +00:00
Ben Gras
1d4be8052f Don't install progressbar suid. 2006-09-27 15:40:10 +00:00
Ben Gras
b5b76d5691 Reorder for port order, and add svn (Subversion) as service (port 3690) 2006-09-27 13:55:54 +00:00
Ben Gras
c2bbcfe560 _NSIG is supposed to be highest signal number plus one, not highest
signal number.
2006-09-27 08:56:37 +00:00
Philip Homburg
d9bfb27282 Missing negation in comment 2006-09-21 13:33:23 +00:00
Philip Homburg
d24a880003 Added EOPNOTSUPP and better error handling in accept. 2006-09-14 13:48:41 +00:00
Philip Homburg
c39a693274 Disabled /etc/rc.rescue 2006-09-08 13:20:57 +00:00
Philip Homburg
4cc6be8532 NUL terminate timingdata[cat].names instead of timingdata[0].names. Reported
by <devel@pop3.ru>.
2006-08-28 15:30:14 +00:00
Philip Homburg
3e35db1514 Also clear word 6 in the ATAPI SCSI_READ10 command packet (in atapi_transfer). 2006-08-28 15:10:10 +00:00
Philip Homburg
f6c4002b35 first commit of extra ptrace code for fault injection. 2006-08-28 15:03:03 +00:00
Philip Homburg
c5efbf71c0 first commit of extra ptrace code for fault injection 2006-08-28 14:59:56 +00:00
Philip Homburg
62cb625f1b Removed superfluous assignment to text_base. Reported by Ildar Ismagilov. 2006-08-28 14:59:55 +00:00
Philip Homburg
d68627f3a8 No need for .depend files in CVS. 2006-08-28 14:32:24 +00:00
Philip Homburg
66f9a5f508 Do not abort/panic when an ethernet driver does something unexpected. 2006-08-28 12:59:36 +00:00
Philip Homburg
0ac9521c94 TTY should not panic when it is impossible to reply. A driver may crash
before receiving the reply from TTY.
2006-08-28 12:16:15 +00:00
Ben Gras
2f58281a20 New UPDATING file with hints for source updating. 2006-08-18 16:18:54 +00:00
Ben Gras
8ecf9cb9b8 Undo configure script regeneration - not using --libdir 2006-08-18 16:16:06 +00:00
Ben Gras
32f8abc362 Installing in build file sidesteps problems installing as bin 2006-08-17 14:21:10 +00:00
Ben Gras
150a68c940 set $PATH to avoid (e.g.) /usr/local/bin/grep (gnu grep) being found
which has unexpected return codes compared to minix grep.
2006-08-17 14:03:06 +00:00
Ben Gras
b90b5898e4 Let installing work as bin 2006-08-17 10:10:42 +00:00
Ben Gras
cdfe90a6ca Fixes to build and install flex as bin. 2006-08-17 09:53:26 +00:00
Ben Gras
bf195531b3 new command 'dumpcore' that can write core files of running processes. 2006-08-15 15:59:38 +00:00
Ben Gras
5a6052119f Force yacc to be /usr/bin/yacc, in case someone has /usr/local/bin/yacc
(bison) before /usr/bin/yacc in $PATH
2006-08-15 15:59:04 +00:00
Ben Gras
8f7876b1d1 /usr/local/gnu removed as prefix; gcc libs go into /usr/local/lib/gcc now 2006-08-15 15:58:24 +00:00
Ben Gras
87f95d7c02 No separate beta dir 2006-08-15 15:57:13 +00:00
Ben Gras
a178a15950 Make packman minix-version-aware 2006-08-15 15:56:42 +00:00
Ben Gras
030d4a7e2c add xxl to usage
don't touch non-compiler binaries
2006-08-15 15:56:09 +00:00
Ben Gras
1d7257b613 Code for 'service run' 2006-08-15 15:55:04 +00:00
Ben Gras
b888922d62 Added 'service run' to run a service without restart. 2006-08-15 15:54:51 +00:00
Philip Homburg
82a5bffa7d Pass 'service' instead of 'argv[1]' to servxcheck. 2006-08-10 14:13:28 +00:00
Philip Homburg
6076eddf9c Use syslog for logging. 2006-08-10 14:11:25 +00:00
Ben Gras
4539e54d8b . fix for wild store at startup time by calling dev_io without fp
initialized
 . fix for writing exactly PIPE_SIZE to a pipe with O_NONBLOCK blocking
   anyway because of incomplete logic in pipe_check
2006-08-10 11:51:11 +00:00
Philip Homburg
4ba5826ba6 Improved access checks in system.c. Grant drivers and FS the rights they need. 2006-08-10 10:56:16 +00:00
Ben Gras
c3c08d252c report driver source of grant mismatch 2006-08-04 13:31:06 +00:00
Ben Gras
4c7c64cd66 Clarify du units. 2006-08-04 13:26:05 +00:00
Ben Gras
e3ffd4c2b1 Start calling it 3.1.3rc1 2006-08-04 12:12:06 +00:00
Ben Gras
9d9e14941e At least 8k stack for all drivers so that malloc() works, for grants,
for printf().
2006-08-02 22:51:47 +00:00
Ben Gras
23e1bffd7a lance needs 8k in order for safecopies to work (malloc()). 2006-08-02 22:42:10 +00:00
Ben Gras
6dbca44030 Turn off prototypes for readv and writev until they're defined
(properly) in the library.
2006-08-02 15:18:49 +00:00
Ben Gras
5d8c07b3f2 Fix by Joren for setjmp to not clobber %ebx. 2006-08-02 12:03:02 +00:00
Ben Gras
bc8b79da53 Make includes for gcc 4.1.1 too if found. 2006-08-01 09:17:43 +00:00
Ben Gras
636b368dd0 Actually make top suid root 2006-07-31 15:06:53 +00:00
Ben Gras
153e2c406c make top suid root to do getsysinfo. 2006-07-31 14:37:56 +00:00
Ben Gras
99644bed66 /usr/local/src for easypack-fetched sources. 2006-07-31 11:40:14 +00:00
Ben Gras
18327f02a8 Introduced unprivileged getsysinfo variant, to retrieve harmless data
in formats that don't change (or is upwards compatible).
2006-07-27 16:23:01 +00:00
Ben Gras
4d7f2af576 big for big commands 2006-07-27 16:05:17 +00:00
Ben Gras
a284f55473 Bigger bigsh for gcc and binutils 2006-07-27 08:51:08 +00:00
Ben Gras
36e9a43109 Force minix install 2006-07-26 14:26:26 +00:00
Ben Gras
4a6cd8f878 Make ps suid root instead of sguid kmem. This makes getsysinfo
work for it.
2006-07-26 11:34:26 +00:00
Philip Homburg
baa3ac5853 Fix for 'cleanup: not idle: 2313' bug. 2006-07-25 14:13:09 +00:00
Ben Gras
13d1de5122 Taught log driver to return REP_IO_GRANT on revive events, makes revive
work again.
2006-07-25 11:01:54 +00:00
Ben Gras
82173212ee Introduction of a 'big' ioctl, with more bits (20) reserved for encoding the
size field. The TIOCSFON ioctl size (8192) didn't get encoded properly,
as there weren't enough bits for it (12) in the regular format.

The new format has only one type field, and an extra flag (_IOC_BIG)
turned on. FS checks for this flag and uses the alternative decoding
of the ioctl codes to determine the size when doing grants.

This unbreaks loadfont, although that still uses a phys copy in tty.
2006-07-25 09:41:40 +00:00
Ben Gras
7573c41657 flex build fix - can't build and install separately with two different
compilers.
2006-07-25 09:39:13 +00:00
Ben Gras
ec4223d96a More stack for system. 2006-07-25 09:38:24 +00:00
Ben Gras
e6076e2c95 Don't give an error message for usage. 2006-07-24 13:27:17 +00:00
Philip Homburg
61337d5f7b Allow holes in executables. 2006-07-24 13:07:25 +00:00
Ben Gras
0020ad8ac7 Make /usr/local/lib/{ack,gcc} for ack and gcc format libraries. 2006-07-21 16:09:05 +00:00
Ben Gras
75267305f1 distclean first, then install 2006-07-21 14:56:23 +00:00
Ben Gras
deca72b814 Only install. 2006-07-21 14:55:33 +00:00
Ben Gras
cbfcdcc4c2 Use grant address type in loadfont ioctl. 2006-07-21 14:39:48 +00:00
Ben Gras
f7c36e31e5 More stack for env to build g++. 2006-07-21 12:51:56 +00:00
Ben Gras
53cbd9acbf Manpage bug fix reported by Matej Kosik. 2006-07-21 11:19:32 +00:00
Ben Gras
6c7004423d Fix for %#02x bug (shouldn't print 0x, but junk was printed) found by
Joren l'Ami.  Also fixes %p when arg is 0 (printed 0 instead of 0x0).
2006-07-21 10:08:47 +00:00
Philip Homburg
f6d1f6fdf6 Switch to vc 0 and softscrolling when /dev/video is opened and switch back
at the close. This should prevent problems with X on (emulated) Cirrus
cards.
2006-07-19 11:50:18 +00:00
Ben Gras
0d9976ae9f Don't call X 'X Windows'. 2006-07-19 10:51:30 +00:00
Ben Gras
2bb759206f Build gcc library of libfl. 2006-07-18 14:52:53 +00:00
Ben Gras
4033ccc08d 'zmodem' is 'big'. remove unused bits from autopart. This unbreaks
the commands build.
2006-07-17 17:05:54 +00:00
Philip Homburg
59830eda3f Prototypes for send and recv. Fixed send (pass null address) and sendto
(fail when a null address is passed to a socket that is not connected).
2006-07-14 14:34:00 +00:00
Philip Homburg
371ac29c9f Clear NONBLOCK flag after probing ethernet device. 2006-07-14 13:35:21 +00:00
Philip Homburg
ee46e92dd2 Fixed ruserok not to required /etc/hosts.equiv. 2006-07-14 12:48:01 +00:00
Ben Gras
b0fc01eb82 <minix/ds.h> - ds definitions. 2006-07-14 12:40:32 +00:00
Philip Homburg
8f19ca2039 More stack for in.rshd. 2006-07-14 11:22:37 +00:00
Ben Gras
3512a86b44 . DS understands publishing and subscribing where keys are in string
form. Subscriptions are regular expressions.
 . different types are stored per key; currently u32 and/or string.
   the same key can be referenced (publish, subscribe, check) as any type.
 . notify()s are sent when subscriptions are triggered (publishing or
   updating of matching keys); optionally, a subscribe flag sends
   updates for all matching keys at subscription time, instead of only
   after updates after subscribing
 . all interfacing to ds is in /usr/src/lib/syslib/ds.c.
 . subscribe is ds_subscribe
   publish functions are ds_publish_<type>
   retrieve functions are ds_retrieve_<type> (one-time retrieval of a value)
   check functions are ds_check_<type> (check for updated key caller
      subscribes to not yet checked for, or ESRCH for none)
 . ramdisk driver updated with new ds interface
2006-07-13 14:50:23 +00:00
Philip Homburg
d40007667c Do not report non-safe sys_sdevio calls when the address is 'SELF' 2006-07-13 14:46:53 +00:00
Philip Homburg
c06bc3ead8 Left consistency checks enabled in INET in the previous commit. 2006-07-13 13:25:55 +00:00
Philip Homburg
04b478f177 More stack for tcpd.
Safecopies renders the NWIOQUERYPARAM ioctl useless. This functionality
is now replaced with /dev/ipstat. Write the request to the device and
read the answer in one read request.
2006-07-13 13:19:48 +00:00
Ben Gras
2d79ae7831 When installing in a free partition larger than the maximum, don't align
on cylinder boundary.
2006-07-13 12:43:47 +00:00
Ben Gras
b52a516521 Joren's proposed fix for a too-conservative split point selection.
(Making building packages with long filenames difficult.)
2006-07-10 15:05:33 +00:00
Philip Homburg
9939089dea Safecopy support for INET. 2006-07-10 12:55:33 +00:00
Philip Homburg
7ce17fe655 Support for SI_CALL_STATS (counting systemcalls). 2006-07-10 12:44:43 +00:00
Philip Homburg
2cf649db2e Safecopy support in ethernet drivers. 2006-07-10 12:43:38 +00:00
Philip Homburg
9392742cc4 Use safecopy version to get log messages from TTY. 2006-07-10 12:42:31 +00:00
Philip Homburg
fd62815e73 Fixed a bug that would report a device more than once. Added safecopy
version of do_dev_name and do_slot_name.
2006-07-10 12:39:54 +00:00
Philip Homburg
ee09d50403 Changed to use sys_readbios to get screen parameters. Added safecopy version
to get log messages.
2006-07-10 12:37:39 +00:00
Philip Homburg
a3fce7ce8d Changed to use sys_readbios get the 'machine ID'. 2006-07-10 12:35:55 +00:00
Philip Homburg
dcb7cae67c Changed to use sys_readbios to get BIOS parameters. 2006-07-10 12:34:41 +00:00
Philip Homburg
6f4091eb8c Added do_readbios. Added debugging output for unexpected use of unsafe copy
functions.
2006-07-10 12:27:26 +00:00
Philip Homburg
73e5de6354 Added sys_readbios.
Changed pci_dev_name and pci_slot_name to use safecopies.
Mae it possible to disable the use of safecopies in kputc for debugging.
2006-07-10 12:17:16 +00:00
Philip Homburg
d7174ec0ab Added SI_CALL_STATS and ENABLE_SYSCALL_STATS for system call statistics.
Added BUSC_PCI_DEV_NAME_S and BUSC_PCI_SLOT_NAME_S to support safecopies in PCI.
Added DL_WRITEV_S, DL_READV_S, DL_GETSTAT_S, DL_GRANT, and iovec_s_t to support
safecopies in ethernet drviers. Renamed DL_INIT to DL_CONF, and DL_INIT_REPLY
to DL_CONF_REPLY.
Added SYS_READBIOS and sys_readbios to read from BIOS data areas.
Added GET_KMESS_S for safecopy support in LOG.
Added sys_safe_insb and sys_safe_outsb.
2006-07-10 12:13:29 +00:00
Ben Gras
cac387bc1e Clean ramdisk image .s too 2006-07-06 14:09:54 +00:00
Ben Gras
5c55d94007 Bigger BUFSIZ for bigger fs block size. 2006-07-06 10:02:25 +00:00
Ben Gras
1561067ee4 Grant system dynamic-only. 2006-06-30 14:40:29 +00:00
Ben Gras
b654c02f55 Give pm its own brk() so malloc() works in pm. pm needs more stack for this. 2006-06-30 14:36:11 +00:00
Ben Gras
b5179d7025 Split do_brk in a stub and a function that does the real work, so that
the real work can be called from elsewhere too. Specifically, to allow PM
its own brk().
2006-06-30 14:35:38 +00:00
Ben Gras
0323892f71 3rd fix for improper behaviour on crashing driver with safe_io_conversion 2006-06-29 14:24:07 +00:00
Ben Gras
407eefe63a Compile fix 2006-06-29 14:23:33 +00:00
Ben Gras
f1222a09a6 Make stack traces on exceptions possible. 2006-06-29 13:35:27 +00:00
Ben Gras
bfca7d68ba Fix another bug related to trying i/o more than once 2006-06-28 12:20:30 +00:00
Ben Gras
46646a49a8 Don't print cloexec 2006-06-28 10:04:32 +00:00
Ben Gras
f9fb0ff546 Fix bug where safe conversion doesn't happen after 1st time in loop 2006-06-28 10:03:18 +00:00
Ben Gras
6b1f8de38a Added _select() stub for select(). 2006-06-27 18:28:33 +00:00
Ben Gras
bd535a120b . satisfy some gcc warnings (uninitialized/unused variables)
. change cloexec mask from long to fd_set to remove 32 fd's per
   process restriction (from cloexec at least)
2006-06-27 16:47:35 +00:00
Ben Gras
a0f8161fe7 Stopgap for tar creating insane group ownerships due to tiny gid_t. 2006-06-27 16:30:46 +00:00
Ben Gras
59bedc2074 let dynamic allocation of table work 2006-06-27 14:15:47 +00:00
Ben Gras
607fb6bf7f Add a flag to grants system indicating a slot is VALID; so a slot
can be reserved (USED), while toggling VALID on and off.
2006-06-27 12:19:45 +00:00
Ben Gras
a587273c56 . expanded grant manipulation interface to more direct
manipulation
. made fs allocate a grant for every ioctl, even if no data
  is being copied, in order to disambiguate concurrent ioctls
  on the same minor
2006-06-26 16:08:42 +00:00
Philip Homburg
2f50f92eb3 Move inet to safe copies. 2006-06-26 16:03:35 +00:00
Ben Gras
961a173573 Fix to let elle understand window size. 2006-06-26 15:15:40 +00:00
Philip Homburg
de07a562d1 Vectored safe copies for inet. 2006-06-26 14:20:11 +00:00
Philip Homburg
14c9743ecf First cut at safe copies for inet. Breaks tcpstat. 2006-06-26 11:17:19 +00:00
Ben Gras
48a6203ae7 A backup of the readclock command that shouldn't have been imported into cvs. 2006-06-26 08:58:11 +00:00
Ben Gras
3b814d36d1 Rename paramctl to setgrant. 2006-06-23 15:35:05 +00:00
Philip Homburg
add4be444f get_sys_bits 2006-06-23 15:32:24 +00:00
Ben Gras
002922fa4c New kernel call, SYS_PARAMCTL, that sets parameters of the caller
and is therefore unprivileged. Used to set grant tables.
2006-06-23 15:07:41 +00:00
Philip Homburg
8dfac43a75 Print ipc_to in hex. Also print the 'system' call mask. 2006-06-23 13:27:03 +00:00
Ben Gras
777dbbe3f7 Everyone's endpoint number 2006-06-23 12:16:22 +00:00
Ben Gras
0e9c6932c4 use malloc() + copy + free() instead of realloc() 2006-06-23 12:07:41 +00:00
Ben Gras
3ffa1684ae New option -E for ps that prints endpoint numbers instead of pids. 2006-06-23 11:59:20 +00:00
Ben Gras
31318a8ce5 library interface for vectored safecopy variant. 2006-06-23 11:54:35 +00:00
Ben Gras
d402047222 Added vectored variant of sys_safecopy*. 2006-06-23 11:54:03 +00:00
Ben Gras
82855e9cf5 . leave out dead code from device.c
. don't loop doing a receive() after sendrec() - chance of recovering is not
  high, and can lead to receive()ing a notify() (which can't happen in sendrec()),
  which is terrible
. return status from device when DEV_CANCEL is done on a signal; hardcode EAGAIN to
  become EINTR though
2006-06-23 11:51:56 +00:00
Philip Homburg
08bb0f7708 No longer build Michael Temari's httpd. Install a httpd from ports. 2006-06-22 11:53:03 +00:00
Philip Homburg
529ca8a4df Added strlcat and strlcpy. 2006-06-22 11:47:18 +00:00
Philip Homburg
bd783b901f Added prototype for inet_aton. 2006-06-22 11:45:59 +00:00
Philip Homburg
20a9ca246d Added __minix3 to make it easier to figure out that we are compiling on/for
Minix 3.
2006-06-22 11:44:17 +00:00
Ben Gras
ed9be75384 <minix/safecopies> 2006-06-20 14:25:42 +00:00
Ben Gras
7b6a1e5f59 More space for rs 2006-06-20 10:59:45 +00:00
Ben Gras
0d39b17655 Changed order of -lsys and -lsysutil for printf() 2006-06-20 10:50:29 +00:00
Ben Gras
705f1039d9 order changed for printf() 2006-06-20 10:47:25 +00:00
Ben Gras
cef426ee54 There is no lex. 2006-06-20 10:14:25 +00:00
Ben Gras
848b96a9a4 Fixes for usb and bios. 2006-06-20 10:13:56 +00:00
Ben Gras
223a0e7b60 Fix for KERNEL definition. 2006-06-20 10:13:32 +00:00
Ben Gras
150c964b49 Fix for losing REVIVE 2006-06-20 10:12:30 +00:00
Ben Gras
2384a85296 FS support for grant-based i/o.
For character device i/o, FS does a so-called 'magic' grant to let the
driver copy from or to user space. As this is done in FS address space,
the driver is told to do this in FS address space. The redirection to
the right user process then happens at copy-time in the kernel, using the
FS grant table. This also happens for DEV_READ and DEV_WRITE on block
devices.

For other block device i/o, which happens from/to FS buffers, FS does
a 'direct' grant to its own address space for the driver.

After the i/o returns, this access has to be K-I-L-L-E-D, revoked.
Sometimes this is after a SUSPEND and DEV_REVIVE, in which case the
revoking happens in pipe.c.

This conversion happens in safe_io_conversion() in device.c, called
by dev_io and dev_bio.

FS has to pre-allocate its own space for these grant tables. This happens
in main.c.
2006-06-20 10:12:09 +00:00
Ben Gras
54f1e6d3d4 Use endpoint_t 2006-06-20 10:04:33 +00:00
Ben Gras
7a76a7a495 Rename protected to prot
Also print size of grant table known in system
2006-06-20 10:03:48 +00:00
Ben Gras
3061d7b17a Changed do_devio not to require DIO_TYPE, but to extract type
from DIO_REQUEST. Also do_vdevio. Also do_sdevio, but this
function also supports grant id's and offsets.

do_segctl: rename protected to prot.

do_umap: support for GRANT_SEG umap.

do_privctl: support SYS_PRIV_SET_GRANTS, which sets location and size
of in-own-address-space grant table.

do_safecopy: functions to verify and perform 'safe' (grant-based) copies.
2006-06-20 10:03:10 +00:00
Ben Gras
ada6592af9 Prototype of do_safecopy 2006-06-20 09:59:50 +00:00
Ben Gras
bf6fa2acd0 Introduced global sys_call_code to check in called kernel call
implementation functions.

Changed check in system.c to check compile-time-sized bitmap of
kernel calls.

Added SYS_SAFECOPYFROM and SYS_SAFECOPYTO, both mapping to
do_safecopy (that's what sys_call_code is used for).
2006-06-20 09:58:58 +00:00
Ben Gras
b89c6634f5 Use endpoint_t. New prototypes for related to grants and safecopy functions. 2006-06-20 09:57:00 +00:00
Ben Gras
2e89eb5270 Change allowed kernel call bitmap to an array of bitmaps to allow
any number of kernel calls.

Allowed kernel calls are stored in table.c for every image process as a
variably-sized array of allowed calls. This is used to fill the bitmap
of size determined at compile time by the number of kernel calls. This
filling is done by main.c. There is a special call called SYS_ALL_CALLS
which fills the bitmap of allowed calls completely, if that is the only
entry in the array.
2006-06-20 09:56:06 +00:00
Ben Gras
eecb40cf21 Rename protected to prot for g++ 2006-06-20 09:52:11 +00:00
Ben Gras
28950e6104 Use endpoint_t type 2006-06-20 09:51:49 +00:00
Ben Gras
831bc7ecd1 Move bitmap manipulation macros to <minix/bitmap.h> 2006-06-20 09:50:26 +00:00
Ben Gras
281e76364a Conversion to safe calls, and returning grant in DEV_REVIVE messages 2006-06-20 09:49:02 +00:00
Ben Gras
d61715a69e Fix for new *_ins* i/o functions 2006-06-20 09:48:26 +00:00
Ben Gras
6d8fa97233 Kick out REVIVE 2006-06-20 09:47:23 +00:00
Ben Gras
b80626c878 safe conversion 2006-06-20 09:46:57 +00:00
Ben Gras
1c8b206a5d . Safe I/O, ioctl() and DIAGNOSTICS variants conversion - safe copies,
include grant id in DEV_REVIVE messages.
. Removal of TTY_FLAGS field (and so O_NONBLOCK support).
. Fixed CANCEL behaviour and return code on blocking I/O,
  previously handled by O_NONBLOCK
. Totally removed REVIVE replies, previously still possible on
  blocking ioctls (REVIVE directly called) and ptys (missing TTY_REVIVE
  check), removes deadlock bug with FS
. Removed obsolete *COMPAT options and associated code
2006-06-20 09:02:54 +00:00
Ben Gras
9fa06d5e3f safe conversion 2006-06-20 08:56:58 +00:00
Ben Gras
5350645c86 Safe I/O and ioctl functions 2006-06-20 08:56:15 +00:00
Ben Gras
60bbcab13f Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S,
include grant id in DEV_REVIVE messages
2006-06-20 08:55:35 +00:00
Ben Gras
3ca26c812d Change to 'safe' copy variant 2006-06-20 08:54:22 +00:00
Ben Gras
ad6d8a53c8 Understand *_S variants 2006-06-20 08:52:26 +00:00
Ben Gras
4fa6691106 Change for safe copies, and DEV_REVIVE message including grant id 2006-06-20 08:52:11 +00:00
Ben Gras
3bd3c2cee1 Change at driver to understand 'safe' transfers and ioctls; do corresponding
safe copy and safe sys_insw and sys_outsw calls.
2006-06-20 08:51:24 +00:00
Ben Gras
e929676268 . made libdriver understand *_S variants
. ioctl, transfer and 'other' functions get an extra parameter: 'safe', int
  is nonzero if function is called with *_S variant ('other' if ioctl)
2006-06-20 08:49:51 +00:00
Ben Gras
9be69be836 . flex moved back into the base system, so prefix is /usr
. sysenv.c and umount.c need <minix/type.h> now
2006-06-20 08:46:45 +00:00
Ben Gras
296a0fb33d /CD check unnecessary 2006-06-20 08:46:09 +00:00
Ben Gras
9df1183b94 . removed const from putenv() for g++
. added safecopies.c:
  these are library functions to maintain grant tables in own address space
. sys_safecopy.c:
  interfaces to kernel calls to perform safe copy functions in from or to
  foreign process
. changes in i/o fields (type merged with request) reflected in
  library functions (sys_out.c, sys_vinb.c, sys_vinl.c, sys_vinw.c,
  sys_voutb.c, sys_voutl.c, sys_voutw.c)
. type merged with request in sys_sdevio, also now accepts offset which
  is used when a grant is specified (the _DIO_SAFE subtype)
. system printf() function changed to send DIAGNOSTICS_S messages, which
  specify a grant id instead of a direct address for the buffer to be
  printed; tty and log can then safecopy the buffer
2006-06-20 08:45:04 +00:00
Ben Gras
cfb984e9bd . renamed __str to __makestr to allow for g++
. changed some CMOS ioctl codes to have correct sizes (struct tm instead
  of u32_t), a disk ioctl code from W to RW, and memory ioctl codes from R
  to W, needed for proper matching of grant in FS
2006-06-20 08:40:26 +00:00
Ben Gras
aaca17c36d . introduced DEV_READ_S, DEV_WRITE_S, DEV_SCATTER_S, DEV_GATHER_S
and DEV_IOCTL_S as replacements for DEV_READ, DEV_WRITE, DEV_SCATTER,
  DEV_GATHER and DEV_IOCTL. Instead of a direct address, the *_S commands
  pass 'grant ids' to the drivers which are referenced through a new set
  of copy calls (sys_safecopyfrom and sys_safecopyto). in order for this
  copy to succeed, the grant must have previously been created in the
  address space of the granter.
. bitmap manipulation functions moved to <minix/bitmap.h>
. HIGHPOS introduced as field containing high 32 bits of position in
  device I/O message; TTY_FLAGS no longer used
. IO_GRANT field introduced for GRANTs, to replace ADDRESS
. REP_IO_GRANT field for un-SUSPEND messages introduced to indicate
  grant for which I/O was done to disambiguate messages
. SYS_SAFECOPYFROM and SYS_SAFECOPYTO introduced as new calls
. SYS_PRIV_SET_GRANTS code introduced as a code to set the address and
  size of the grant table in a process' own address space
. 'type' and 'direction' field of _ins* and _outs* I/O functions
  are merged into one by ORing _DIO_INPUT/_DIO_OUTPUT and _DIO_BYTE/_DIO_WORD
  etc. This allows for an additional parameter, _DIO_SAFE, which indicates
  the address in another address space isn't actually an address, but
  a grant id. Also needs an offset, for which fields had to be merged.
. SCP_* are field names for SYS_SAFECOPY* functions
. DIAGNOSTICS and GET_KMESS moved to their own range above DIAG_BASE,
  added DIAGNOSTICS_S which is a grant-based variant of DIAGNOSTICS
. removed obsolete BINCOMPAT and SRCCOMPAT options
. added GRANT_SEG type for use in vircopy - allows copying to a grant
  id (without offset)
. added _MINIX_IOCTL_* macros that decode information encoded by
  _IO* macros in ioctl codes, used to check which grants are necessary
  for an ioctl
. introduced the type endpoint_t for process endpoints, changed some
  prototypes and struct field types to match
. renamed protected to prot for g++
2006-06-20 08:38:15 +00:00
Ben Gras
6ef5aa4fb2 . flex back into the base system
. imports of Michael Temari's httpd and ftp
2006-06-19 14:58:20 +00:00
Ben Gras
aa5efff203 Initial revision 2006-06-19 14:55:09 +00:00
Ben Gras
ede3e5ab83 Al Woodhull's new manual pages 2006-06-19 14:51:41 +00:00
Philip Homburg
3edf4c2854 Prototype for readline. 2006-06-14 13:19:48 +00:00
Philip Homburg
a617a46e35 Retry read after EINTR. 2006-06-14 13:18:53 +00:00
Philip Homburg
221e731e45 Wake up writer when selecting for read on an empty pipe.
Set fp_revived to NOT_REVIVING when decrementing reviving.
2006-06-14 13:17:41 +00:00
Philip Homburg
474d137c39 Forgot include some Minix 3 specific changes. 2006-06-07 15:03:42 +00:00
Philip Homburg
cb02a90b77 Fixed some select bugs related to pipes. Removed SELFD_* because they were
bogus and unused.
2006-06-07 14:41:47 +00:00
Philip Homburg
373ea53510 A bigger ramdisk is needed for the new version of ash. 2006-06-07 14:39:50 +00:00
Philip Homburg
acebf7b52f Important BSD version of setenv, added killpg, replaced _sigsetjmp.c with
an assembler jump to longjmp.
2006-06-07 14:38:39 +00:00
Philip Homburg
3f297ffd9f Added killpg to signal.h, rearranged getloadavg, putenv, and setenv in
stdlib.h and added unsetenv, added declaration of optreset to unistd.h.
2006-06-07 14:36:35 +00:00
Philip Homburg
eaf9e4cff8 Make sure that line editing is disabled when the shell is not connected to a
tty.
2006-05-29 13:20:28 +00:00
Philip Homburg
43d9263589 Parsing of '-OT' and '-OS' failed in acd.descr. 2006-05-29 12:29:25 +00:00
Philip Homburg
5f19e53afb Install /usr/lib/descr from the source tree. 2006-05-29 12:25:44 +00:00
Philip Homburg
7aa4c9ec2f New version of ash. From FreeBSD 5.4 via Minix-vmd. 2006-05-23 12:59:34 +00:00
Philip Homburg
3ea083b8d4 Actually remove allocmem and freemem sources from the library. 2006-05-19 12:45:55 +00:00
Philip Homburg
e9aabcf2f8 Disabled building rescue driver (no longer needed). Moved allocmem from
library to the memory driver. Always put output from within TTY directly on
the console. Removed second include of driver.h from tty.c. Made tty_inrepcode
bigger. First step to move PM and FS calls that are not regular (API)
system calls out of callnr.h (renumbered them, and removed them from the
table.c files). Imported the Minix-vmd uname implementation. This provides
a more stable ABI than the current implementation. Added a bit of security
checking. Unfortunately not nearly enough to get a secure system. Fixed a
bug related to the sizes of the programs in the image (in PM patch_mem_chunks).
2006-05-19 12:19:37 +00:00
Philip Homburg
c3cf4ef460 Fixed off by one error in backoff code. Limit backoff to 1 second for
disk drivers.
2006-05-15 12:08:43 +00:00
Philip Homburg
c9ff3994f1 Unpause requests (to FS) can be generated in parallel to other requests. 2006-05-15 12:06:19 +00:00
Philip Homburg
f0186f4179 Do not unmap a driver when the driver dies (it interferes with restarting
disk drivers). Fixed accounting for REVIVING/reviving.
2006-05-15 11:43:06 +00:00
Philip Homburg
ae92cc208d The new service command managed to escape. 2006-05-11 15:30:56 +00:00
Philip Homburg
14b7a72ba3 Init need more space (the results of removing the special case for init in
adjust in PM). Better flags dump in IS.
2006-05-11 15:00:46 +00:00
Philip Homburg
e4967b06bb Special code for restarting disk drivers (-c flag in service). 2006-05-11 14:58:33 +00:00
Philip Homburg
773844a816 New interface between PM and FS. 2006-05-11 14:57:23 +00:00
Philip Homburg
94717cb74c Pass -c flags to service for disk device drivers. 2006-05-11 14:53:20 +00:00
Philip Homburg
aeb6630868 Ignore SIGHUP in floppy driver. 2006-05-11 14:52:40 +00:00
Philip Homburg
15b8fe54a8 Better initialization of the memory map of processes that are part of the
image. Removed NO_MAP flag.
2006-05-11 14:49:46 +00:00
Philip Homburg
71917d6383 Changes for restarting disk drivers and new interface between PM and FS. 2006-05-11 14:47:31 +00:00
Ben Gras
5a8315cf5b call cons_stop() before sys_abort() to not break tty on shutdown 2006-05-11 14:01:44 +00:00
Philip Homburg
5a3d6ac67f Balance curly braces. 2006-05-10 15:39:52 +00:00
Ben Gras
244786ae34 Fix for service formatting bug reported by Jaap Weel <weel@ugcs.caltech.edu> 2006-05-08 22:04:05 +00:00
Ben Gras
461a4fafb1 Added fchmod() and fchown() 2006-04-18 11:26:04 +00:00
Ben Gras
b1e5779b1c *** empty log message *** 2006-04-13 18:12:33 +00:00
Ben Gras
3aedf32a8a *** empty log message *** 2006-04-13 18:07:42 +00:00
1135 changed files with 121509 additions and 73311 deletions

View File

@@ -1369,6 +1369,9 @@ void boot_device(char *devname)
void ctty(char *line)
{
if (line == nil) {
serial_init(-1);
} else
if (between('0', line[0], '3') && line[1] == 0) {
serial_init(line[0] - '0');
} else {
@@ -1793,6 +1796,7 @@ void execute(void)
case R_HELP: help(); ok= 1; break;
case R_EXIT: exit(0);
case R_OFF: off(); ok= 1; break;
case R_CTTY: ctty(nil); ok= 1; break;
}
/* Command to check bootparams: */

View File

@@ -854,6 +854,9 @@ restore_video: ! To restore the video mode on exit
_serial_init:
mov bx, sp
mov dx, 2(bx) ! Line number
mov line, #0
test dx, dx ! Off if line number < 0
js 0f
push ds
xor ax, ax
mov ds, ax ! Vector and BIOS data segment

View File

@@ -45,7 +45,7 @@ static int block_size = 0;
/* Data about the different processes. */
#define PROCESS_MAX 16 /* Must match the space in kernel/mpx.x */
#define KERNEL 0 /* The first process is the kernel. */
#define KERNEL_IDX 0 /* The first process is the kernel. */
#define FS 2 /* The third must be fs. */
struct process { /* Per-process memory adresses. */
@@ -194,7 +194,7 @@ void patch_sizes(void)
/* Patch text and data sizes of the processes into kernel data space.
*/
doff= process[KERNEL].data + P_SIZ_OFF;
doff= process[KERNEL_IDX].data + P_SIZ_OFF;
for (i= 0; i < n_procs; i++) {
procp= &process[i];
@@ -445,7 +445,7 @@ void exec_image(char *image)
}
/* Get the click shift from the kernel text segment. */
if (i == KERNEL) {
if (i == KERNEL_IDX) {
if (!get_clickshift(vsec, &hdr)) return;
addr= align(addr, click_size);
}
@@ -504,7 +504,7 @@ void exec_image(char *image)
if (!get_segment(&vsec, &a_data, &addr, limit)) return;
/* Make space for bss and stack unless... */
if (i != KERNEL && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
printf("%07lx %07lx %8ld %8ld %8ld",
procp->cs, procp->ds,
@@ -554,7 +554,7 @@ void exec_image(char *image)
}
/* Check the kernel magic number. */
if (get_word(process[KERNEL].data + MAGIC_OFF) != KERNEL_D_MAGIC) {
if (get_word(process[KERNEL_IDX].data + MAGIC_OFF) != KERNEL_D_MAGIC) {
printf("Kernel magic number is incorrect\n");
errno= 0;
return;
@@ -592,8 +592,8 @@ void exec_image(char *image)
(void) dev_close();
/* Minix. */
minix(process[KERNEL].entry, process[KERNEL].cs,
process[KERNEL].ds, params, sizeof(params), aout);
minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
process[KERNEL_IDX].ds, params, sizeof(params), aout);
if (!(k_flags & K_BRET)) {
extern u32_t reboot_code;

View File

@@ -14,11 +14,11 @@
#include <minix/config.h>
#include <minix/const.h>
#include <minix/type.h>
#include <servers/fs/const.h>
#include <servers/fs/type.h>
#include <servers/fs/buf.h>
#include <servers/fs/super.h>
#include <servers/fs/inode.h>
#include <servers/mfs/const.h>
#include <servers/mfs/type.h>
#include <servers/mfs/buf.h>
#include <servers/mfs/super.h>
#include <servers/mfs/inode.h>
#include "rawfs.h"
void readblock(off_t blockno, char *buf, int);

View File

@@ -2,8 +2,9 @@
MAKE = exec make -$(MAKEFLAGS)
BZIP2=bzip2-1.0.3
FLEX=flex-2.5.4
SMALLPROGRAMS=`arch` aal advent ash autil awk bc byacc cawf cron de dhcpd dis88 elle elvis ftp ftpd200 httpd ibm indent m4 make mdb mined patch pax ps reboot rlogind scripts sh simple syslogd talk talkd telnet telnetd urlget yap zmodem
SMALLPROGRAMS=`arch` aal advent ash autil awk bc byacc cawf cron de dhcpd dis88 elle elvis ftp101 ftpd200 ibm indent m4 make mdb mined patch pax profile ps reboot rlogind scripts sh simple syslogd talk talkd telnet telnetd urlget yap zoneinfo
usage:
@echo "Usage: make all # Compile all commands" >&2
@@ -16,20 +17,28 @@ usage:
@echo " "
@echo "big compiles the commands the require large compiler sizes."
@echo "small compiles the rest. all compiles all."
@false
all: small big
all: big small
install: biginstall smallinstall
install: big biginstall small smallinstall
big:
binsizes big
cd zmodem && make
cd $(BZIP2) && /bin/sh build build
binsizes normal
biginstall: big
binsizes big
cd zmodem && make install
cd $(BZIP2) && make install
cd $(FLEX) && sh build
binsizes normal
clean::
cd $(BZIP2) && make clean
cd zmodem && make clean
if [ -f $(FLEX)/Makefile ]; then cd $(FLEX) && make distclean ; fi
for p in $(SMALLPROGRAMS); do ( cd $$p && make clean ); done
small::

View File

@@ -1,36 +1,56 @@
# Makefile for ash.
SRCS= builtins.c cd.c dirent.c error.c eval.c exec.c expand.c input.c \
SRCS= alias.c builtins.c cd.c error.c eval.c exec.c expand.c histedit.c \
input.c \
jobs.c mail.c main.c memalloc.c miscbltin.c mystring.c nodes.c \
options.c parser.c redir.c show.c signames.c syntax.c trap.c \
options.c parser.c redir.c setmode.c show.c signames.c syntax.c \
trap.c \
output.c var.c
OBJS= builtins.o cd.o dirent.o error.o eval.o exec.o expand.o input.o \
OBJS= alias.o builtins.o cd.o error.o eval.o exec.o expand.o histedit.o \
input.o \
jobs.o mail.o main.o memalloc.o miscbltin.o mystring.o nodes.o \
options.o parser.o redir.o show.o signames.o syntax.o trap.o \
options.o parser.o redir.o setmode.o show.o signames.o syntax.o \
trap.o \
output.o var.o init.o \
bltin/echo.o bltin/expr.o bltin/operators.o bltin/regexp.o
bltin/echo.o bltin/expr.o bltin/operators.o bltin/regexp.o \
arith.o arith_lex.o
#
# Set READLINE in shell.h and add -ledit to LIBS if you want to use the
# editline package by Simmule Turner and Rich Salz. (The big, bloated
# and GPL contaminated FSF readline should work too.)
#
CPPFLAGS= -DSHELL -I. -D_MINIX -D_POSIX_SOURCE
CFLAGS= -wo -i $(CPPFLAGS)
LIBS= -ledit
CC = exec cc
LEX=flex
YACC=/usr/bin/yacc
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
# Enable this line to disable command line editing
#EDIT=-DNO_HISTORY
# Enable this line to use the editline library instead of libedit
EDIT=-DEDITLINE
EDITLIB=-ledit
FLEXLIB=-lfl
# Enable this line if your system does not have a <paths.h>
NO_PATHS_H=-DNO_PATHS_H
# Enable this if you don't want job control
NO_JOBS=-DJOBS=0
MKB_NO_JOBS=-j
CPPFLAGS= -DSHELL -I. -D_MINIX $(EDIT) $(NO_PATHS_H) $(NO_JOBS)
CFLAGS= $(OPT) $(CPPFLAGS)
LIBS= $(EDITLIB) $(FLEXLIB)
CLEANFILES= $(OBJS) \
builtins.c builtins.h init.c mkinit mknodes mksignames mksyntax \
nodes.c nodes.h signames.c signames.h syntax.c syntax.h token.def \
arith.c arith_y.h arith_lex.c builtins.c builtins.h init.c \
mkinit mknodes mksignames mksyntax \
nodes.c nodes.h signames.c signames.h syntax.c syntax.h token.h \
bltin/operators.h bltin/operators.c
all: sh
sh: $(OBJS)
$(CC) $(CFLAGS) -o sh $(OBJS) $(LIBS)
install -S 100k sh
$(CC) $(CFLAGS) -fnone -o sh $(OBJS) $(LIBS)
install -S 136k sh
install: /usr/bin/ash /usr/bin/sh /bin/sh /bin/bigsh
@@ -44,7 +64,7 @@ install: /usr/bin/ash /usr/bin/sh /bin/sh /bin/bigsh
install -lcs $? $@
/bin/bigsh: /usr/bin/ash
install -S 1500000 -lcs $? $@
install -S 6600k -lcs $? $@
clean:
rm -f $(CLEANFILES) sh core
@@ -54,11 +74,18 @@ parser.o: token.def
token.def: mktokens
sh mktokens
builtins.c builtins.h: builtins.table shell.h
sh mkbuiltins shell.h builtins.table
arith.c: arith.y
$(YACC) -d $?
mv y.tab.c $@
mv y.tab.h arith_y.h
init.o: mkinit $(SRCS)
./mkinit '$(CC) -c $(CFLAGS) init.c' $(SRCS)
arith_lex.c: arith_lex.l
builtins.c builtins.h: builtins.def shell.h
sh mkbuiltins $(MKB_NO_JOBS) . shell.h builtins.def
init.c: mkinit $(SRCS)
./mkinit $(SRCS)
mkinit: mkinit.c
$(CC) $(CFLAGS) mkinit.c -o $@
@@ -81,20 +108,8 @@ syntax.c syntax.h: mksyntax
mksyntax: mksyntax.c parser.h
$(CC) $(CFLAGS) mksyntax.c -o $@
bltin/operators.h: bltin/mkexpr bltin/binary_op bltin/unary_op
cd bltin && sh mkexpr
bltin/echo.o: bltin/echo.c
cd bltin && $(CC) -I.. $(CFLAGS) -c echo.c
bltin/expr.o: bltin/expr.c
cd bltin && $(CC) -I.. $(CFLAGS) -c expr.c
bltin/operators.o: bltin/operators.c
cd bltin && $(CC) -I.. $(CFLAGS) -c operators.c
bltin/regexp.o: bltin/regexp.c
cd bltin && $(CC) -I.. $(CFLAGS) -c regexp.c
bltin/operators.h: bltin/mkexpr bltin/unary_op bltin/binary_op
cd bltin && sh mkexpr unary_op binary_op
# Dependencies you say? This will have to do.
$(OBJS): error.h eval.h exec.h expand.h init.h input.h \
@@ -103,3 +118,6 @@ $(OBJS): error.h eval.h exec.h expand.h init.h input.h \
builtins.h nodes.h signames.h syntax.h
bltin/expr.o bltin/operators.o: bltin/operators.h
#
# $PchId: Makefile,v 1.4 2006/05/22 12:40:46 philip Exp $

View File

@@ -1,4 +1,13 @@
# @(#)TOUR 5.1 (Berkeley) 3/7/91
# @(#)TOUR 8.1 (Berkeley) 5/31/93
# $FreeBSD: src/bin/sh/TOUR,v 1.6 1999/08/27 23:15:07 peter Exp $
NOTE -- This is the original TOUR paper distributed with ash and
does not represent the current state of the shell. It is provided anyway
since it provides helpful information for how the shell is structured,
but be warned that things have changed -- the current shell is
still under development.
================================================================
A Tour through Ash
@@ -20,7 +29,7 @@ programs is:
mknodes nodetypes nodes.h nodes.c
mksignames - signames.h signames.c
mksyntax - syntax.h syntax.c
mktokens - token.def
mktokens - token.h
bltin/mkexpr unary_op binary_op operators.h operators.c
There are undoubtedly too many of these. Mkinit searches all the
@@ -346,3 +355,6 @@ cause the preprocessor can't handle functions with a variable
number of arguments. Defining DEBUG also causes the shell to
generate a core dump if it is sent a quit signal. The tracing
code is in show.c.
#
# $PchId: TOUR,v 1.3 2006/03/31 11:33:46 philip Exp $

265
commands/ash/alias.c Normal file
View File

@@ -0,0 +1,265 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/alias.c,v 1.18 2004/04/06 20:06:51 markm Exp $");
*/
#include <stdlib.h>
#include "shell.h"
#include "input.h"
#include "output.h"
#include "error.h"
#include "memalloc.h"
#include "mystring.h"
#include "alias.h"
#include "options.h" /* XXX for argptr (should remove?) */
#include "builtins.h"
#define ATABSIZE 39
STATIC struct alias *atab[ATABSIZE];
STATIC void setalias(char *, char *);
STATIC int unalias(char *);
STATIC struct alias **hashalias(char *);
STATIC
void
setalias(char *name, char *val)
{
struct alias *ap, **app;
app = hashalias(name);
for (ap = *app; ap; ap = ap->next) {
if (equal(name, ap->name)) {
INTOFF;
ckfree(ap->val);
ap->val = savestr(val);
INTON;
return;
}
}
/* not found */
INTOFF;
ap = ckmalloc(sizeof (struct alias));
ap->name = savestr(name);
/*
* XXX - HACK: in order that the parser will not finish reading the
* alias value off the input before processing the next alias, we
* dummy up an extra space at the end of the alias. This is a crock
* and should be re-thought. The idea (if you feel inclined to help)
* is to avoid alias recursions. The mechanism used is: when
* expanding an alias, the value of the alias is pushed back on the
* input as a string and a pointer to the alias is stored with the
* string. The alias is marked as being in use. When the input
* routine finishes reading the string, it marks the alias not
* in use. The problem is synchronization with the parser. Since
* it reads ahead, the alias is marked not in use before the
* resulting token(s) is next checked for further alias sub. The
* H A C K is that we add a little fluff after the alias value
* so that the string will not be exhausted. This is a good
* idea ------- ***NOT***
*/
#ifdef notyet
ap->val = savestr(val);
#else /* hack */
{
int len = strlen(val);
ap->val = ckmalloc(len + 2);
memcpy(ap->val, val, len);
ap->val[len] = ' '; /* fluff */
ap->val[len+1] = '\0';
}
#endif
ap->flag = 0;
ap->next = *app;
*app = ap;
INTON;
}
STATIC int
unalias(char *name)
{
struct alias *ap, **app;
app = hashalias(name);
for (ap = *app; ap; app = &(ap->next), ap = ap->next) {
if (equal(name, ap->name)) {
/*
* if the alias is currently in use (i.e. its
* buffer is being used by the input routine) we
* just null out the name instead of freeing it.
* We could clear it out later, but this situation
* is so rare that it hardly seems worth it.
*/
if (ap->flag & ALIASINUSE)
*ap->name = '\0';
else {
INTOFF;
*app = ap->next;
ckfree(ap->name);
ckfree(ap->val);
ckfree(ap);
INTON;
}
return (0);
}
}
return (1);
}
#ifdef mkinit
INCLUDE "alias.h"
SHELLPROC {
rmaliases();
}
#endif
void
rmaliases(void)
{
struct alias *ap, *tmp;
int i;
INTOFF;
for (i = 0; i < ATABSIZE; i++) {
ap = atab[i];
atab[i] = NULL;
while (ap) {
ckfree(ap->name);
ckfree(ap->val);
tmp = ap;
ap = ap->next;
ckfree(tmp);
}
}
INTON;
}
struct alias *
lookupalias(char *name, int check)
{
struct alias *ap = *hashalias(name);
for (; ap; ap = ap->next) {
if (equal(name, ap->name)) {
if (check && (ap->flag & ALIASINUSE))
return (NULL);
return (ap);
}
}
return (NULL);
}
/*
* TODO - sort output
*/
int
aliascmd(int argc, char **argv)
{
char *n, *v;
int ret = 0;
struct alias *ap;
if (argc == 1) {
int i;
for (i = 0; i < ATABSIZE; i++)
for (ap = atab[i]; ap; ap = ap->next) {
if (*ap->name != '\0') {
out1fmt("alias %s=", ap->name);
out1qstr(ap->val);
out1c('\n');
}
}
return (0);
}
while ((n = *++argv) != NULL) {
if ((v = strchr(n+1, '=')) == NULL) /* n+1: funny ksh stuff */
if ((ap = lookupalias(n, 0)) == NULL) {
outfmt(out2, "alias: %s not found\n", n);
ret = 1;
} else {
out1fmt("alias %s=", n);
out1qstr(ap->val);
out1c('\n');
}
else {
*v++ = '\0';
setalias(n, v);
}
}
return (ret);
}
int
unaliascmd(int argc __unused, char **argv __unused)
{
int i;
while ((i = nextopt("a")) != '\0') {
if (i == 'a') {
rmaliases();
return (0);
}
}
for (i = 0; *argptr; argptr++)
i = unalias(*argptr);
return (i);
}
STATIC struct alias **
hashalias(char *p)
{
unsigned int hashval;
hashval = *p << 4;
while (*p)
hashval+= *p++;
return &atab[hashval % ATABSIZE];
}
/*
* $PchId: alias.c,v 1.5 2006/05/22 12:41:12 philip Exp $
*/

52
commands/ash/alias.h Normal file
View File

@@ -0,0 +1,52 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)alias.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/alias.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#define ALIASINUSE 1
struct alias {
struct alias *next;
char *name;
char *val;
int flag;
};
struct alias *lookupalias(char *, int);
int aliascmd(int, char **);
int unaliascmd(int, char **);
void rmaliases(void);
/*
* $PchId: alias.h,v 1.4 2006/03/31 11:30:54 philip Exp $
*/

39
commands/ash/arith.h Normal file
View File

@@ -0,0 +1,39 @@
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)arith.h 1.1 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/arith.h,v 1.9 2004/04/06 20:06:51 markm Exp $
*/
int arith(char *);
int arith_assign(char *, arith_t);
int expcmd(int, char **);
/*
* $PchId: arith.h,v 1.3 2006/03/31 11:25:25 philip Exp $
*/

366
commands/ash/arith.y Normal file
View File

@@ -0,0 +1,366 @@
%{
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/arith.y,v 1.19 2004/05/24 10:11:31 stefanf Exp $");
*/
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "shell.h"
#include "arith.h"
#include "arith_lex.h"
#include "var.h"
%}
%union {
arith_t l_value;
char* s_value;
}
%token <l_value> ARITH_NUM ARITH_LPAREN ARITH_RPAREN
%token <s_value> ARITH_VAR
%type <l_value> expr
%right ARITH_ASSIGN
%right ARITH_ADDASSIGN ARITH_SUBASSIGN
%right ARITH_MULASSIGN ARITH_DIVASSIGN ARITH_REMASSIGN
%right ARITH_RSHASSIGN ARITH_LSHASSIGN
%right ARITH_BANDASSIGN ARITH_BXORASSIGN ARITH_BORASSIGN
%left ARITH_OR
%left ARITH_AND
%left ARITH_BOR
%left ARITH_BXOR
%left ARITH_BAND
%left ARITH_EQ ARITH_NE
%left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
%left ARITH_LSHIFT ARITH_RSHIFT
%left ARITH_ADD ARITH_SUB
%left ARITH_MUL ARITH_DIV ARITH_REM
%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
%%
exp:
expr
{ return ($1); }
;
expr:
ARITH_LPAREN expr ARITH_RPAREN
{ $$ = $2; } |
expr ARITH_OR expr
{ $$ = $1 ? $1 : $3 ? $3 : 0; } |
expr ARITH_AND expr
{ $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } |
expr ARITH_BOR expr
{ $$ = $1 | $3; } |
expr ARITH_BXOR expr
{ $$ = $1 ^ $3; } |
expr ARITH_BAND expr
{ $$ = $1 & $3; } |
expr ARITH_EQ expr
{ $$ = $1 == $3; } |
expr ARITH_GT expr
{ $$ = $1 > $3; } |
expr ARITH_GE expr
{ $$ = $1 >= $3; } |
expr ARITH_LT expr
{ $$ = $1 < $3; } |
expr ARITH_LE expr
{ $$ = $1 <= $3; } |
expr ARITH_NE expr
{ $$ = $1 != $3; } |
expr ARITH_LSHIFT expr
{ $$ = $1 << $3; } |
expr ARITH_RSHIFT expr
{ $$ = $1 >> $3; } |
expr ARITH_ADD expr
{ $$ = $1 + $3; } |
expr ARITH_SUB expr
{ $$ = $1 - $3; } |
expr ARITH_MUL expr
{ $$ = $1 * $3; } |
expr ARITH_DIV expr
{
if ($3 == 0)
yyerror("division by zero");
$$ = $1 / $3;
} |
expr ARITH_REM expr
{
if ($3 == 0)
yyerror("division by zero");
$$ = $1 % $3;
} |
ARITH_NOT expr
{ $$ = !($2); } |
ARITH_BNOT expr
{ $$ = ~($2); } |
ARITH_SUB expr %prec ARITH_UNARYMINUS
{ $$ = -($2); } |
ARITH_ADD expr %prec ARITH_UNARYPLUS
{ $$ = $2; } |
ARITH_NUM |
ARITH_VAR
{
char *p;
arith_t arith_val;
char *str_val;
if (lookupvar($1) == NULL)
setvarsafe($1, "0", 0);
str_val = lookupvar($1);
arith_val = strtoarith_t(str_val, &p, 0);
/*
* Conversion is successful only in case
* we've converted _all_ characters.
*/
if (*p != '\0')
yyerror("variable conversion error");
$$ = arith_val;
} |
ARITH_VAR ARITH_ASSIGN expr
{
if (arith_assign($1, $3) != 0)
yyerror("variable assignment error");
$$ = $3;
} |
ARITH_VAR ARITH_ADDASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) + $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_SUBASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) - $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_MULASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) * $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_DIVASSIGN expr
{
arith_t value;
if ($3 == 0)
yyerror("division by zero");
value = atoarith_t(lookupvar($1)) / $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_REMASSIGN expr
{
arith_t value;
if ($3 == 0)
yyerror("division by zero");
value = atoarith_t(lookupvar($1)) % $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_RSHASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) >> $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_LSHASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) << $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_BANDASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) & $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_BXORASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) ^ $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_BORASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) | $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} ;
%%
#include "error.h"
#include "output.h"
#include "memalloc.h"
#include "builtins.h"
#define lstrlen(var) (3 + (2 + CHAR_BIT * sizeof((var))) / 3)
char *arith_buf, *arith_startbuf;
int yylex(void);
int yyparse(void);
int
arith_assign(char *name, arith_t value)
{
char *str;
int ret;
str = (char *)ckmalloc(lstrlen(value));
sprintf(str, ARITH_FORMAT_STR, value);
ret = setvarsafe(name, str, 0);
free(str);
return ret;
}
int
arith(char *s)
{
long result;
arith_buf = arith_startbuf = s;
INTOFF;
result = yyparse();
arith_lex_reset(); /* Reprime lex. */
INTON;
return result;
}
void
yyerror(char *s)
{
yyerrok;
yyclearin;
arith_lex_reset(); /* Reprime lex. */
error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
}
/*
* The exp(1) builtin.
*/
int
expcmd(int argc, char **argv)
{
char *p;
char *concat;
char **ap;
long i;
if (argc > 1) {
p = argv[1];
if (argc > 2) {
/*
* Concatenate arguments.
*/
STARTSTACKSTR(concat);
ap = argv + 2;
for (;;) {
while (*p)
STPUTC(*p++, concat);
if ((p = *ap++) == NULL)
break;
STPUTC(' ', concat);
}
STPUTC('\0', concat);
p = grabstackstr(concat);
}
} else
p = "";
i = arith(p);
out1fmt("%ld\n", i);
return !i;
}
/*************************/
#ifdef TEST_ARITH
#include <stdio.h>
main(int argc, char *argv[])
{
printf("%d\n", exp(argv[1]));
}
error(char *s)
{
fprintf(stderr, "exp: %s\n", s);
exit(1);
}
#endif
/*
* $PchId: arith.y,v 1.6 2006/05/22 12:41:47 philip Exp $
*/

12
commands/ash/arith_lex.h Normal file
View File

@@ -0,0 +1,12 @@
/*
arith_lex.h
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
int yylex(void);
void arith_lex_reset(void);
/*
* $PchId: arith_lex.h,v 1.1 2001/05/18 19:57:55 philip Exp $
*/

138
commands/ash/arith_lex.l Normal file
View File

@@ -0,0 +1,138 @@
%{
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/arith_lex.l,v 1.22 2004/04/06 20:06:51 markm Exp $");
*/
#include <string.h>
#include "shell.h"
#include "arith_lex.h"
#include "arith_y.h"
#include "error.h"
#include "memalloc.h"
#include "var.h"
extern char *arith_buf, *arith_startbuf;
#undef YY_INPUT
#define YY_INPUT(buf,result,max) \
result = (*buf = *arith_buf++) ? 1 : YY_NULL;
#define YY_NO_UNPUT
%}
%%
[ \t\n] { ; }
0x[a-fA-F0-9]+ {
yylval.l_value = strtoarith_t(yytext, NULL, 16);
return ARITH_NUM;
}
0[0-7]+ {
yylval.l_value = strtoarith_t(yytext, NULL, 8);
return ARITH_NUM;
}
[0-9]+ {
yylval.l_value = strtoarith_t(yytext, NULL, 10);
return ARITH_NUM;
}
[A-Za-z][A-Za-z0-9_]* {
/*
* If variable doesn't exist, we should initialize
* it to zero.
*/
char *temp;
if (lookupvar(yytext) == NULL)
setvarsafe(yytext, "0", 0);
temp = (char *)ckmalloc(strlen(yytext) + 1);
yylval.s_value = strcpy(temp, yytext);
return ARITH_VAR;
}
"(" { return ARITH_LPAREN; }
")" { return ARITH_RPAREN; }
"||" { return ARITH_OR; }
"&&" { return ARITH_AND; }
"|" { return ARITH_BOR; }
"^" { return ARITH_BXOR; }
"&" { return ARITH_BAND; }
"==" { return ARITH_EQ; }
"!=" { return ARITH_NE; }
">" { return ARITH_GT; }
">=" { return ARITH_GE; }
"<" { return ARITH_LT; }
"<=" { return ARITH_LE; }
"<<" { return ARITH_LSHIFT; }
">>" { return ARITH_RSHIFT; }
"*" { return ARITH_MUL; }
"/" { return ARITH_DIV; }
"%" { return ARITH_REM; }
"+" { return ARITH_ADD; }
"-" { return ARITH_SUB; }
"~" { return ARITH_BNOT; }
"!" { return ARITH_NOT; }
"=" { return ARITH_ASSIGN; }
"+=" { return ARITH_ADDASSIGN; }
"-=" { return ARITH_SUBASSIGN; }
"*=" { return ARITH_MULASSIGN; }
"/=" { return ARITH_DIVASSIGN; }
"%=" { return ARITH_REMASSIGN; }
">>=" { return ARITH_RSHASSIGN; }
"<<=" { return ARITH_LSHASSIGN; }
"&=" { return ARITH_BANDASSIGN; }
"^=" { return ARITH_BXORASSIGN; }
"|=" { return ARITH_BORASSIGN; }
. {
error("arith: syntax error: \"%s\"\n", arith_startbuf);
}
%%
void
arith_lex_reset(void)
{
YY_NEW_FILE;
}
/*
* $PchId: arith_lex.l,v 1.5 2006/04/10 14:35:29 philip Exp $
*/

View File

@@ -1,26 +1,78 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bltin.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/bltin/bltin.h,v 1.13 2004/04/06 20:06:53 markm Exp $
*/
/*
* This file is included by programs which are optionally built into the
* shell. If SHELL is defined, we try to map the standard UNIX library
* routines to ash routines using defines.
*
* Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
* This file is part of ash, which is distributed under the terms specified
* by the Ash General Public License. See the file named LICENSE.
*/
#include "../shell.h"
#include "../mystring.h"
#ifdef SHELL
#include "builtins.h"
#include "../output.h"
#undef stdout
#define stdout out1
#undef stderr
#define stderr out2
#define printf out1fmt
#undef putc
#define putc(c, file) outc(c, file)
#undef putchar
#define putchar(c) out1c(c)
#define fprintf outfmt
#define fputs outstr
#define fflush flushout
#define INITARGS(argv)
#define warnx1(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a); \
error("%s", buf); \
}
#define warnx2(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a, b); \
error("%s", buf); \
}
#define warnx3(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a, b, c); \
error("%s", buf); \
}
#else
#undef NULL
#include <stdio.h>
@@ -28,13 +80,12 @@
#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else
#endif
#ifdef __STDC__
pointer stalloc(int);
void error(char *, ...);
#else
pointer stalloc();
void error();
#endif
void error(const char *, ...);
extern char *commandname;
/*
* $PchId: bltin.h,v 1.4 2006/03/29 11:39:00 philip Exp $
*/

View File

@@ -1,74 +1,126 @@
/*
* Echo command.
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
* This file is part of ash, which is distributed under the terms specified
* by the Ash General Public License. See the file named LICENSE.
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)echo.c 8.2 (Berkeley) 5/4/95
*/
#define main echocmd
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/bltin/echo.c,v 1.14 2004/04/06 20:06:53 markm Exp $");
*/
/*
* Echo command.
*/
#ifdef __minix
#define MINIX
#endif
#include "bltin.h"
#ifndef MINIX
/* #define eflag 1 */
#else
#undef eflag
main(argc, argv) char **argv; {
register char **ap;
register char *p;
register char c;
int count;
int nflag = 0;
#ifndef eflag
int eflag = 0;
#endif
ap = argv;
if (argc)
ap++;
if ((p = *ap) != NULL) {
if (equal(p, "--")) {
ap++;
}
if (equal(p, "-n")) {
nflag++;
ap++;
} else if (equal(p, "-e")) {
int
echocmd(argc, argv)
int argc;
char **argv;
{
char **ap;
char *p;
char c;
int count;
int nflag = 0;
#ifndef eflag
eflag++;
int eflag = 0;
#endif
ap++;
}
}
while ((p = *ap++) != NULL) {
while ((c = *p++) != '\0') {
if (c == '\\' && eflag) {
switch (*p++) {
case 'b': c = '\b'; break;
case 'c': return 0; /* exit */
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\\': break; /* c = '\\' */
case '0':
c = 0;
count = 3;
while (--count >= 0 && (unsigned)(*p - '0') < 8)
c = (c << 3) + (*p++ - '0');
break;
default:
p--;
break;
ap = argv;
if (argc)
ap++;
if ((p = *ap) != NULL) {
#ifdef MINIX
if (equal(p, "--")) {
ap++;
}
#endif
if (equal(p, "-n")) {
nflag++;
ap++;
} else if (equal(p, "-e")) {
#ifndef eflag
eflag++;
#endif
ap++;
}
}
while ((p = *ap++) != NULL) {
while ((c = *p++) != '\0') {
if (c == '\\' && eflag) {
switch (*p++) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'c': return 0; /* exit */
case 'e': c = '\033'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\\': break; /* c = '\\' */
case '0':
c = 0;
count = 3;
while (--count >= 0 && (unsigned)(*p - '0') < 8)
c = (c << 3) + (*p++ - '0');
break;
default:
p--;
break;
}
}
}
putchar(c);
}
if (*ap)
putchar(' ');
}
if (! nflag)
putchar('\n');
return 0;
putchar(c);
}
if (*ap)
putchar(' ');
}
if (! nflag)
putchar('\n');
return 0;
}
/*
* $PchId: echo.c,v 1.5 2006/05/23 12:05:56 philip Exp $
*/

View File

@@ -7,17 +7,14 @@
*/
#define main exprcmd
#include "bltin.h"
#include "operators.h"
#include <regex.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef S_ISLNK
#define lstat stat
#define S_ISLNK(mode) (0)
#endif
#define STACKSIZE 12
#define NESTINCR 16
@@ -50,7 +47,6 @@ struct operator {
struct filestat {
int op; /* OP_FILE or OP_LFILE */
char *name; /* name of file */
int rcode; /* return code from stat */
struct stat stat; /* status info on file */
@@ -63,24 +59,18 @@ extern short number_parens; /* number of \( \) pairs */
#ifdef __STDC__
int expr_is_false(struct value *);
void expr_operator(int, struct value *, struct filestat *);
int lookup_op(char *, char *const*);
char *re_compile(char *); /* defined in regexp.c */
int re_match(char *, char *); /* defined in regexp.c */
long atol(const char *);
static int expr_is_false(struct value *);
static void expr_operator(int, struct value *, struct filestat *);
static int lookup_op(char *, char *const*);
#else
int expr_is_false();
void expr_operator();
int lookup_op();
char *re_compile(); /* defined in regexp.c */
int re_match(); /* defined in regexp.c */
long atol();
static int expr_is_false();
static void expr_operator();
static int lookup_op();
#endif
main(argc, argv) char **argv; {
exprcmd(argc, argv) char **argv; {
char **ap;
char *opname;
char c;
@@ -146,6 +136,13 @@ overflow: error("Expression too complex");
continue;
} else {
if (opname[0] == '\'') {
for (p = opname ; *++p != '\0' ; );
if (--p > opname && *p == '\'') {
*p = '\0';
opname++;
}
}
valsp->type = STRING;
valsp->u.string = opname;
valsp++;
@@ -193,19 +190,11 @@ overflow: error("Expression too complex");
valsp->u.string = "";
}
valsp->type = STRING;
if (c >= OP_FILE
&& (fs.op != c
|| fs.name == NULL
if (c == OP_FILE
&& (fs.name == NULL
|| ! equal(fs.name, valsp->u.string))) {
fs.op = c;
fs.name = valsp->u.string;
if (c == OP_FILE) {
fs.rcode = stat(valsp->u.string,
&fs.stat);
} else {
fs.rcode = lstat(valsp->u.string,
&fs.stat);
}
fs.rcode = stat(valsp->u.string, &fs.stat);
}
}
if (binary < FIRST_BINARY_OP)
@@ -250,7 +239,7 @@ done:
}
int
static int
expr_is_false(val)
struct value *val;
{
@@ -274,14 +263,16 @@ expr_is_false(val)
* to stat, to avoid repeated stat calls on the same file.
*/
void
static void
expr_operator(op, sp, fs)
int op;
struct value *sp;
struct filestat *fs;
{
int i;
int i, r;
struct stat st1, st2;
regex_t pat;
regmatch_t rm[2];
switch (op) {
case NOT:
@@ -343,16 +334,16 @@ filebit:
if (fs->stat.st_mode & i && fs->rcode >= 0)
goto true;
goto false;
case ISSLINK:
if (lstat(fs->name, &st1) == -1)
goto false;
if (S_ISLNK(st1.st_mode))
goto true;
goto false;
case ISSIZE:
sp->u.num = fs->rcode >= 0? fs->stat.st_size : 0L;
sp->type = INTEGER;
break;
case ISLINK1:
case ISLINK2:
if (S_ISLNK(fs->stat.st_mode) && fs->rcode >= 0)
goto true;
fs->op = OP_FILE; /* not a symlink, so expect a -d or so next */
goto false;
case NEWER:
if (stat(sp->u.string, &st1) != 0) {
sp->u.num = 0;
@@ -439,19 +430,21 @@ filebit:
break;
case MATCHPAT:
{
char *pat;
pat = re_compile((sp + 1)->u.string);
if (re_match(pat, sp->u.string)) {
if (number_parens > 0) {
sp->u.string = match_begin[1];
sp->u.string[match_length[1]] = '\0';
r = regcomp(&pat, (sp + 1)->u.string, 0);
if (r)
error("Bad regular expression");
if (regexec(&pat, sp->u.string, 2, rm, 0) == 0 &&
rm[0].rm_so == 0)
{
if (pat.re_nsub > 0) {
sp->u.string[rm[1].rm_eo] = '\0';
sp->u.string = sp->u.string+rm[1].rm_so;
} else {
sp->u.num = match_length[0];
sp->u.num = rm[0].rm_eo;
sp->type = INTEGER;
}
} else {
if (number_parens > 0) {
if (pat.re_nsub > 0) {
sp->u.string[0] = '\0';
} else {
sp->u.num = 0;
@@ -464,7 +457,7 @@ filebit:
}
int
static int
lookup_op(name, table)
char *name;
char *const*table;

View File

@@ -5,21 +5,28 @@
# All calls to awk removed, because Minix bawk is deficient. (kjb)
if [ $# -ne 2 ]
then
echo "Usage: $0 <unary_op> <binary_op>" >&2
exit 1
fi
unary_op="$1"
binary_op="$2"
exec > operators.h
i=0
sed -e '/^[^#]/!d' unary_op binary_op | while read line
sed -e '/^[^#]/!d' "$unary_op" "$binary_op" | while read line
do
set -$- $line
echo "#define $1 $i"
i=`expr $i + 1`
done
echo
echo "#define FIRST_BINARY_OP" `sed -e '/^[^#]/!d' unary_op | wc -l`
echo "#define FIRST_BINARY_OP" `sed -e '/^[^#]/!d' "$unary_op" | wc -l`
echo '
#define OP_INT 1 /* arguments to operator are integer */
#define OP_STRING 2 /* arguments to operator are string */
#define OP_FILE 3 /* argument is a file name */
#define OP_LFILE 4 /* argument is a file name of a symlink? */
extern char *const unary_op[];
extern char *const binary_op[];
@@ -31,14 +38,15 @@ echo '/*
* Operators used in the expr/test command.
*/
#include "../shell.h"
#include <stddef.h>
#include "shell.h"
#include "operators.h"
char *const unary_op[] = {'
sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* \([^ ][^ ]*\).*/ "\1",/
' unary_op
' "$unary_op"
echo ' NULL
};
@@ -46,7 +54,7 @@ char *const binary_op[] = {'
sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* \([^ ][^ ]*\).*/ "\1",/
' binary_op
' "$binary_op"
echo ' NULL
};
@@ -54,7 +62,7 @@ const char op_priority[] = {'
sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* [^ ][^ ]* \([^ ][^ ]*\).*/ \1,/
' unary_op binary_op
' "$unary_op" "$binary_op"
echo '};
const char op_argflag[] = {'
@@ -62,5 +70,5 @@ sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* [^ ][^ ]* [^ ][^ ]*$/& 0/
s/^[^ ][^ ]* [^ ][^ ]* [^ ][^ ]* \([^ ][^ ]*\)/ \1,/
' unary_op binary_op
' "$unary_op" "$binary_op"
echo '};'

View File

@@ -0,0 +1,8 @@
/*
myregexp.h
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
char *re_compile(char *pattern);
int re_match(char *pattern, char *string);

View File

@@ -8,7 +8,9 @@
*/
#include "bltin.h"
#include "myregexp.h"
#include <stdlib.h>
#define RE_END 0 /* end of regular expression */
#define RE_LITERAL 1 /* normal character follows */
@@ -27,7 +29,7 @@
char *match_begin[10];
short match_length[10];
short number_parens;
static int match();
static int match(char *pattern, char *string);
@@ -48,7 +50,6 @@ re_compile(pattern)
char stack[10];
int paren_num;
int i;
char *malloc();
p = pattern;
if (*p == '^')
@@ -176,6 +177,7 @@ out:
int
re_match(pattern, string)
char *pattern;
char *string;
@@ -246,7 +248,7 @@ ccl:
p++;
}
p++;
if (found == negate || c == 0)
if (found == negate)
goto bad;
break;
case RE_LP:

View File

@@ -16,9 +16,8 @@ ISFIFO -p 12 OP_FILE
ISSETUID -u 12 OP_FILE
ISSETGID -g 12 OP_FILE
ISSTICKY -k 12 OP_FILE
ISSLINK -h 12 OP_FILE
ISSIZE -s 12 OP_FILE
ISLINK1 -h 12 OP_LFILE
ISLINK2 -L 12 OP_LFILE
ISTTY -t 12 OP_INT
NULSTR -z 12 OP_STRING
STRLEN -n 12 OP_STRING

View File

@@ -1,3 +0,0 @@
#!/bin/sh
make clean
make && make install

21
commands/ash/builtins.table → commands/ash/builtins Executable file → Normal file
View File

@@ -1,7 +1,7 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -34,19 +34,21 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)builtins 5.1 (Berkeley) 3/7/91
# @(#)builtins 8.1 (Berkeley) 5/31/93
#
# This file lists all the builtin commands. The first column is the name
# of a C routine. The -j flag, if present, specifies that this command
# is to be excluded from systems without job control. The rest of the line
# specifies the command name or names used to run the command. The entry
# for nullcmd, which is run when the user does not specify a command, must
# for bltincmd, which is run when the user does not specify a command, must
# come first.
#
# Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
# This file is part of ash, which is distributed under the terms specified
# by the Ash General Public License. See the file named LICENSE.
#
# NOTE: bltincmd must come first!
bltincmd command
#alloccmd alloc
@@ -59,17 +61,19 @@ echocmd echo
evalcmd eval
execcmd exec
exitcmd exit
expcmd exp let
exportcmd export readonly
exprcmd expr test [
#exprcmd expr test [
histcmd fc
fgcmd -j fg
getoptscmd getopts
hashcmd hash
jobidcmd jobid
jobscmd jobs
#lccmd lc
#linecmd line
localcmd local
#nlechocmd nlecho
printfcmd printf
pwdcmd pwd
readcmd read
returncmd return
@@ -77,7 +81,10 @@ setcmd set
setvarcmd setvar
shiftcmd shift
trapcmd trap
truecmd : true false
truecmd : true
umaskcmd umask
unaliascmd unalias
unsetcmd unset
waitcmd wait
#foocmd foo
aliascmd alias

94
commands/ash/builtins.def Normal file
View File

@@ -0,0 +1,94 @@
#!/bin/sh -
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)builtins.def 8.4 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/builtins.def,v 1.14 2004/04/06 20:06:51 markm Exp $
#
# This file lists all the builtin commands. The first column is the name
# of a C routine. The -j flag, if present, specifies that this command
# is to be excluded from systems without job control, and the -h flag,
# if present specifies that this command is to be excluded from systems
# based on the NO_HISTORY compile-time symbol. The rest of the line
# specifies the command name or names used to run the command. The entry
# for bltincmd, which is run when the user does not specify a command, must
# come first.
#
# NOTE: bltincmd must come first!
bltincmd builtin
commandcmd command
#alloccmd alloc
bgcmd -j bg
breakcmd break continue
#catfcmd catf
cdcmd cd chdir
dotcmd .
echocmd echo
evalcmd eval
execcmd exec
exitcmd exit
expcmd exp let
exportcmd export readonly
exprcmd expr test [
falsecmd false
histcmd -h fc
fgcmd -j fg
getoptscmd getopts
hashcmd hash
jobidcmd jobid
jobscmd jobs
#linecmd line
localcmd local
#nlechocmd nlecho
#printfcmd printf
pwdcmd pwd
readcmd read
returncmd return
setcmd set
setvarcmd setvar
shiftcmd shift
trapcmd trap
truecmd : true
typecmd type
umaskcmd umask
unaliascmd unalias
unsetcmd unset
waitcmd wait
#foocmd foo
aliascmd alias
ulimitcmd ulimit
bindcmd bind
wordexpcmd wordexp
#
# $PchId: builtins.def,v 1.5 2006/03/31 10:50:57 philip Exp $

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,22 @@
*/
#ifndef lint
static char sccsid[] = "@(#)cd.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/cd.c,v 1.34 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
/*
* The cd and pwd commands.
@@ -50,115 +60,124 @@ static char sccsid[] = "@(#)cd.c 5.2 (Berkeley) 3/13/91";
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "exec.h"
#include "redir.h"
#include "mystring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "builtins.h"
#include "show.h"
#include "cd.h"
#ifdef __STDC__
STATIC int cdlogical(char *);
STATIC int cdphysical(char *);
STATIC int docd(char *, int, int);
STATIC void updatepwd(char *);
STATIC void getpwd(void);
STATIC char *getcomponent(void);
#else
STATIC int docd();
STATIC void updatepwd();
STATIC void getpwd();
STATIC char *getcomponent();
#endif
STATIC int updatepwd(char *);
char *curdir; /* current working directory */
STATIC char *curdir = NULL; /* current working directory */
STATIC char *prevdir; /* previous working directory */
STATIC char *cdcomppath;
#if UDIR || TILDE
extern int didudir; /* set if /u/logname or ~logname expanded */
#endif
int
cdcmd(argc, argv) char **argv; {
cdcmd(int argc, char **argv)
{
char *dest;
char *path;
char *p;
struct stat statb;
char *padvance();
int tohome= 0;
int ch, phys, print = 0;
nextopt(nullstr);
if ((dest = *argptr) == NULL) {
if ((dest = bltinlookup("HOME", 1)) == NULL)
error("HOME not set");
tohome = 1;
optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
phys = Pflag;
while ((ch = getopt(argc, argv, "LP")) != -1) {
switch (ch) {
case 'L':
phys = 0;
break;
case 'P':
phys = 1;
break;
default:
error("unknown option: -%c", optopt);
break;
}
}
argc -= optind;
argv += optind;
if (argc > 1)
error("too many arguments");
if ((dest = *argv) == NULL && (dest = bltinlookup("HOME", 1)) == NULL)
error("HOME not set");
if (*dest == '\0')
dest = ".";
if (dest[0] == '-' && dest[1] == '\0') {
dest = prevdir ? prevdir : curdir;
if (dest)
print = 1;
else
dest = ".";
}
if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL)
path = nullstr;
while ((p = padvance(&path, dest)) != NULL) {
if (stat(p, &statb) >= 0
&& (statb.st_mode & S_IFMT) == S_IFDIR
&& docd(p, strcmp(p, dest), tohome) >= 0)
return 0;
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
if (!print) {
/*
* XXX - rethink
*/
if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
p += 2;
print = strcmp(p, dest);
}
if (docd(p, print, phys) >= 0)
return 0;
}
}
error("can't cd to %s", dest);
/*NOTREACHED*/
return 0;
}
/*
* Actually do the chdir. If the name refers to symbolic links, we
* compute the actual directory name before doing the cd. In an
* interactive shell, print the directory name if "print" is nonzero
* or if the name refers to a symbolic link. We also print the name
* if "/u/logname" was expanded in it, since this is similar to a
* symbolic link. (The check for this breaks if the user gives the
* cd command some additional, unused arguments.)
* Actually change the directory. In an interactive shell, print the
* directory name if "print" is nonzero.
*/
#if SYMLINKS == 0
STATIC int
docd(dest, print, tohome)
char *dest;
{
#if UDIR || TILDE
if (didudir)
print = 1;
#endif
INTOFF;
if (chdir(dest) < 0) {
INTON;
return -1;
}
updatepwd(dest);
INTON;
if (print && iflag)
out1fmt("%s\n", stackblock());
docd(char *dest, int print, int phys)
{
TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, phys));
/* If logical cd fails, fall back to physical. */
if ((phys || cdlogical(dest) < 0) && cdphysical(dest) < 0)
return (-1);
if (print && iflag && curdir)
out1fmt("%s\n", curdir);
return 0;
}
#else
STATIC int
docd(dest, print, tohome)
char *dest;
{
register char *p;
register char *q;
char *symlink;
cdlogical(char *dest)
{
char *p;
char *q;
char *component;
struct stat statb;
int first;
int i;
int badstat;
TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, tohome));
#if UDIR || TILDE
if (didudir)
print = 1;
#endif
top:
cdcomppath = dest;
/*
* Check each component of the path. If we find a symlink or
* something we can't stat, clear curdir to force a getcwd()
* next time we get the value of the current directory.
*/
badstat = 0;
cdcomppath = stalloc(strlen(dest) + 1);
scopy(dest, cdcomppath);
STARTSTACKSTR(p);
if (*dest == '/') {
STPUTC('/', p);
@@ -166,7 +185,7 @@ top:
}
first = 1;
while ((q = getcomponent()) != NULL) {
if (q[0] == '\0' || q[0] == '.' && q[1] == '\0')
if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
continue;
if (! first)
STPUTC('/', p);
@@ -177,71 +196,42 @@ top:
if (equal(component, ".."))
continue;
STACKSTRNUL(p);
if (lstat(stackblock(), &statb) < 0)
error("lstat %s failed", stackblock());
if ((statb.st_mode & S_IFMT) != S_IFLNK)
continue;
/* Hit a symbolic link. We have to start all over again. */
print = 1;
STPUTC('\0', p);
symlink = grabstackstr(p);
i = (int)statb.st_size + 2; /* 2 for '/' and '\0' */
if (cdcomppath != NULL)
i += strlen(cdcomppath);
p = stalloc(i);
if (readlink(symlink, p, (int)statb.st_size) < 0) {
error("readlink %s failed", stackblock());
if (lstat(stackblock(), &statb) < 0) {
badstat = 1;
break;
}
if (cdcomppath != NULL) {
p[(int)statb.st_size] = '/';
scopy(cdcomppath, p + (int)statb.st_size + 1);
} else {
p[(int)statb.st_size] = '\0';
}
if (p[0] != '/') { /* relative path name */
char *r;
q = r = symlink;
while (*q) {
if (*q++ == '/')
r = q;
}
*r = '\0';
dest = stalloc(strlen(symlink) + strlen(p) + 1);
scopy(symlink, dest);
strcat(dest, p);
} else {
dest = p;
}
goto top;
}
STPUTC('\0', p);
p = grabstackstr(p);
INTOFF;
/* The empty string is not a legal argument to chdir on a POSIX 1003.1
* system. */
if (p[0] != '\0' && chdir(p) < 0) {
if (updatepwd(badstat ? NULL : dest) < 0 || chdir(curdir) < 0) {
INTON;
return -1;
return (-1);
}
updatepwd(p);
INTON;
if (print && !tohome && iflag)
out1fmt("%s\n", p);
return 0;
return (0);
}
#endif /* SYMLINKS */
STATIC int
cdphysical(char *dest)
{
INTOFF;
if (chdir(dest) < 0 || updatepwd(NULL) < 0) {
INTON;
return (-1);
}
INTON;
return (0);
}
/*
* Get the next component of the path name pointed to by cdcomppath.
* This routine overwrites the string pointed to by cdcomppath.
*/
STATIC char *
getcomponent() {
register char *p;
getcomponent(void)
{
char *p;
char *start;
if ((p = cdcomppath) == NULL)
@@ -259,29 +249,43 @@ getcomponent() {
}
/*
* Update curdir (the name of the current directory) in response to a
* cd command. We also call hashcd to let the routines in exec.c know
* that the current directory has changed.
*/
void hashcd();
STATIC void
updatepwd(dir)
char *dir;
{
STATIC int
updatepwd(char *dir)
{
char *new;
char *p;
hashcd(); /* update command hash table */
/*
* If our argument is NULL, we don't know the current directory
* any more because we traversed a symbolic link or something
* we couldn't stat().
*/
if (dir == NULL || curdir == NULL) {
if (prevdir)
ckfree(prevdir);
INTOFF;
prevdir = curdir;
curdir = NULL;
if (getpwd() == NULL) {
INTON;
return (-1);
}
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
INTON;
return (0);
}
cdcomppath = stalloc(strlen(dir) + 1);
scopy(dir, cdcomppath);
STARTSTACKSTR(new);
if (*dir != '/') {
if (curdir == NULL)
return;
p = curdir;
while (*p)
STPUTC(*p++, new);
@@ -300,73 +304,87 @@ updatepwd(dir)
if (new == stackblock())
STPUTC('/', new);
STACKSTRNUL(new);
if (curdir)
ckfree(curdir);
INTOFF;
if (prevdir)
ckfree(prevdir);
prevdir = curdir;
curdir = savestr(stackblock());
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
INTON;
return (0);
}
int
pwdcmd(argc, argv) char **argv; {
getpwd();
out1str(curdir);
out1c('\n');
pwdcmd(int argc, char **argv)
{
char buf[PATH_MAX];
int ch, phys;
optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
phys = Pflag;
while ((ch = getopt(argc, argv, "LP")) != -1) {
switch (ch) {
case 'L':
phys = 0;
break;
case 'P':
phys = 1;
break;
default:
error("unknown option: -%c", optopt);
break;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
error("too many arguments");
if (!phys && getpwd()) {
out1str(curdir);
out1c('\n');
} else {
if (getcwd(buf, sizeof(buf)) == NULL)
error(".: %s", strerror(errno));
out1str(buf);
out1c('\n');
}
return 0;
}
/*
* Run /bin/pwd to find out what the current directory is. We suppress
* interrupts throughout most of this, but the user can still break out
* of it by killing the pwd program. If we already know the current
* Find out what the current directory is. If we already know the current
* directory, this routine returns immediately.
*/
#define MAXPWD 256
STATIC void
getpwd() {
char buf[MAXPWD];
char *p;
int i;
int status;
struct job *jp;
int pip[2];
char *
getpwd(void)
{
char buf[PATH_MAX];
if (curdir)
return;
INTOFF;
if (pipe(pip) < 0)
error("Pipe call failed");
jp = makejob((union node *)NULL, 1);
if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) {
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
close(pip[1]);
return curdir;
if (getcwd(buf, sizeof(buf)) == NULL) {
char *pwd = getenv("PWD");
struct stat stdot, stpwd;
if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
curdir = savestr(pwd);
return curdir;
}
execl("/bin/pwd", "pwd", (char *)0);
error("Cannot exec /bin/pwd");
return NULL;
}
close(pip[1]);
pip[1] = -1;
p = buf;
while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0
|| i == -1 && errno == EINTR) {
if (i > 0)
p += i;
}
close(pip[0]);
pip[0] = -1;
status = waitforjob(jp);
if (status != 0)
error((char *)0);
if (i < 0 || p == buf || p[-1] != '\n')
error("pwd command failed");
p[-1] = '\0';
curdir = savestr(buf);
INTON;
return curdir;
}
/*
* $PchId: cd.c,v 1.6 2006/05/22 12:42:03 philip Exp $
*/

38
commands/ash/cd.h Normal file
View File

@@ -0,0 +1,38 @@
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/bin/sh/cd.h,v 1.7 2004/04/06 20:06:51 markm Exp $
*/
char *getpwd(void);
int cdcmd (int, char **);
int pwdcmd(int, char **);
/*
* $PchId: cd.h,v 1.3 2006/03/31 09:59:04 philip Exp $
*/

354
commands/ash/complete.c Normal file
View File

@@ -0,0 +1,354 @@
/*
complete.c
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "myhistedit.h"
#include "shell.h"
#include "complete.h"
#include "error.h"
#include "expand.h"
#include "nodes.h"
#include "memalloc.h"
static char **getlist(EditLine *el, int *baselen, int *isdir);
static char **getlist_tilde(char *prefix);
static int vstrcmp(const void *v1, const void *v2);
static void print_list(char **list);
static int install_extra(EditLine *el, char **list, int baselen, int isdir);
unsigned char complete(EditLine *el, int ch)
{
struct stackmark mark;
const LineInfo *lf;
char **list;
int baselen, prefix, isdir;
/* Direct the cursor the the end of the word. */
for(;;)
{
lf = el_line(el);
if (lf->cursor < lf->lastchar &&
!isspace((unsigned char)*lf->cursor))
{
(*(char **)&lf->cursor)++; /* XXX */
}
else
break;
}
setstackmark(&mark);
list= getlist(el, &baselen, &isdir);
if (list)
{
prefix= install_extra(el, list, baselen, isdir);
el_push(el, "i");
}
popstackmark(&mark);
if (list)
return CC_REFRESH;
else
return CC_ERROR;
}
unsigned char complete_list(EditLine *el, int ch)
{
struct stackmark mark;
char **list;
setstackmark(&mark);
list= getlist(el, NULL, NULL);
if (list)
{
print_list(list);
re_goto_bottom(el);
}
popstackmark(&mark);
if (list)
{
return CC_REFRESH;
}
else
return CC_ERROR;
}
unsigned char complete_or_list(EditLine *el, int ch)
{
struct stackmark mark;
const LineInfo *lf;
char **list;
int baselen, prefix, isdir;
setstackmark(&mark);
list= getlist(el, &baselen, &isdir);
if (list)
{
prefix= install_extra(el, list, baselen, isdir);
if (prefix == baselen)
{
print_list(list);
re_goto_bottom(el);
}
}
popstackmark(&mark);
if (list)
return CC_REFRESH;
else
return CC_ERROR;
}
unsigned char complete_expand(EditLine *el, int ch)
{
printf("complete_expand\n");
return CC_ERROR;
}
static char **getlist(EditLine *el, int *baselen, int *isdir)
{
const LineInfo *lf;
const char *begin, *end;
char *dirnam, *basenam;
union node arg;
struct arglist arglist;
DIR *dir;
struct dirent *dirent;
int i, l, n;
char *p, **list;
struct strlist *slp, *nslp;
struct stat sb;
lf = el_line(el);
/* Try to find to begin and end of the word that we have to comple. */
begin= lf->cursor;
while (begin > lf->buffer && !isspace((unsigned char)begin[-1]))
begin--;
end= lf->cursor;
while (end < lf->lastchar && !isspace((unsigned char)end[0]))
end++;
*(const char **)&lf->cursor= end; /* XXX */
/* Copy the word to a string */
dirnam= stalloc(end-begin+1);
strncpy(dirnam, begin, end-begin);
dirnam[end-begin]= '\0';
/* Cut the word in two pieces: a path and a (partial) component. */
basenam= strrchr(dirnam, '/');
if (basenam)
{
basenam++;
p= stalloc(strlen(basenam) + 1);
strcpy(p, basenam);
*basenam= '\0';
basenam= p;
}
else
{
if (dirnam[0] == '~')
return getlist_tilde(dirnam);
basenam= dirnam;
dirnam= "./";
}
if (baselen)
*baselen= strlen(basenam);
arg.type= NARG;
arg.narg.next= NULL;
arg.narg.text= dirnam;
arg.narg.backquote= NULL;
arglist.list= NULL;
arglist.lastp= &arglist.list;
expandarg(&arg, &arglist, EXP_TILDE);
INTOFF;
list= NULL;
dir= opendir(arglist.list->text);
if (dir)
{
slp= NULL;
n= 0;
l= strlen(basenam);
while(dirent= readdir(dir))
{
if (strncmp(dirent->d_name, basenam, l) != 0)
continue;
if (l == 0 && dirent->d_name[0] == '.')
continue;
nslp= stalloc(sizeof(*nslp));
nslp->next= slp;
slp= nslp;
slp->text= stalloc(strlen(dirent->d_name)+1);
strcpy(slp->text, dirent->d_name);
n++;
if (n == 1 && isdir != NULL)
{
/* Try to findout whether this entry is a
* file or a directory.
*/
p= stalloc(strlen(arglist.list->text) +
strlen(dirent->d_name) + 1);
strcpy(p, arglist.list->text);
strcat(p, dirent->d_name);
if (stat(p, &sb) == -1)
printf("stat '%s' failed: %s\n",
p, strerror(errno));
if (stat(p, &sb) == 0 && S_ISDIR(sb.st_mode))
*isdir= 1;
else
*isdir= 0;
}
}
closedir(dir);
if (n != 0)
{
list= stalloc((n+1)*sizeof(*list));
for(i= 0; slp; i++, slp= slp->next)
list[i]= slp->text;
if (i != n)
error("complete'make_list: i != n");
list[i]= NULL;
qsort(list, n, sizeof(*list), vstrcmp);
}
}
INTON;
return list;
}
static char **getlist_tilde(char *prefix)
{
printf("should ~-complete '%s'\n", prefix);
return NULL;
}
static int vstrcmp(const void *v1, const void *v2)
{
return strcmp(*(char **)v1, *(char **)v2);
}
#define MAXCOLS 40
#define SEPWIDTH 4
static void print_list(char **list)
{
struct
{
int cols;
int start[MAXCOLS+1];
int width[MAXCOLS];
} best, next;
int e, i, j, l, n, o, cols, maxw, width;
int linewidth= 80;
/* Count the number of entries. */
for (n= 0; list[n]; n++)
; /* do nothing */
if (n == 0)
error("complete'print_list: n= 0");
/* Try to maximize the number of columns */
for (cols= 1; cols<= MAXCOLS; cols++)
{
next.cols= cols;
o= 0;
width= 0;
for(j= 0; j<cols; j++)
{
next.start[j]= o;
/* Number of entries in this column. */
e= (n-o)/(cols-j);
if ((n-o)%(cols-j))
e++;
maxw= 0;
for (i= 0; i<e; i++)
{
l= strlen(list[o+i]);
if (l < 6)
l= 6;
l += SEPWIDTH;
if (l > maxw)
maxw= l;
}
next.width[j]= maxw;
width += maxw;
o += e;
}
next.start[j]= o;
if (cols > 1 && width-SEPWIDTH>linewidth)
break;
best= next;
}
cols= best.cols;
e= best.start[1];
printf("\n");
for(i= 0; i<e; i++)
{
for (j= 0; j<cols; j++)
{
if (best.start[j]+i == best.start[j+1])
continue;
if (j < cols-1)
{
printf("%-*s", best.width[j],
list[best.start[j]+i]);
}
else
{
printf("%s", list[best.start[j]+i]);
}
}
if (i < e-1)
printf("\n");
}
fflush(stdout);
}
static int install_extra(EditLine *el, char **list, int baselen, int isdir)
{
int l;
char *p, **lp;
l= strlen(list[0]);
for (lp= &list[1]; *lp; lp++)
{
while(l>0)
{
if (strncmp(list[0], *lp, l) != 0)
l--;
else
break;
}
}
if (l > baselen || list[1] == NULL)
{
p= stalloc(l-baselen+2);
strncpy(p, list[0]+baselen, l-baselen);
if (list[1] == NULL)
{
p[l-baselen]= isdir ? '/' : ' ';
p[l-baselen+1]= '\0';
l++;
}
else
p[l-baselen]= '\0';
if (el_insertstr(el, p) == -1)
return -1;
}
return l;
}
/*
* $PchId: complete.c,v 1.2 2006/04/10 14:35:53 philip Exp $
*/

14
commands/ash/complete.h Normal file
View File

@@ -0,0 +1,14 @@
/*
complete.h
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
unsigned char complete(EditLine *el, int ch);
unsigned char complete_list(EditLine *el, int ch);
unsigned char complete_or_list(EditLine *el, int ch);
unsigned char complete_expand(EditLine *el, int ch);
/*
* $PchId: complete.h,v 1.1 2001/05/17 07:12:05 philip Exp $
*/

View File

@@ -1,194 +0,0 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)dirent.c 5.1 (Berkeley) 3/7/91";
#endif /* not lint */
#include "shell.h" /* definitions for pointer, NULL, DIRENT, and BSD */
#if ! DIRENT
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#ifndef S_ISDIR /* macro to test for directory file */
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#ifdef BSD
#ifdef __STDC__
int stat(char *, struct stat *);
#else
int stat();
#endif
/*
* The BSD opendir routine doesn't check that what is being opened is a
* directory, so we have to include the check in a wrapper routine.
*/
#undef opendir
DIR *
myopendir(dirname)
char *dirname; /* name of directory */
{
struct stat statb;
if (stat(dirname, &statb) != 0 || ! S_ISDIR(statb.st_mode)) {
errno = ENOTDIR;
return NULL; /* not a directory */
}
return opendir(dirname);
}
#else /* not BSD */
/*
* Dirent routines for old style file systems.
*/
#ifdef __STDC__
pointer malloc(unsigned);
void free(pointer);
int open(char *, int, ...);
int close(int);
int fstat(int, struct stat *);
#else
pointer malloc();
void free();
int open();
int close();
int fstat();
#endif
DIR *
opendir(dirname)
char *dirname; /* name of directory */
{
register DIR *dirp; /* -> malloc'ed storage */
register int fd; /* file descriptor for read */
struct stat statb; /* result of fstat() */
#ifdef O_NDELAY
fd = open(dirname, O_RDONLY|O_NDELAY);
#else
fd = open(dirname, O_RDONLY);
#endif
if (fd < 0)
return NULL; /* errno set by open() */
if (fstat(fd, &statb) != 0 || !S_ISDIR(statb.st_mode)) {
(void)close(fd);
errno = ENOTDIR;
return NULL; /* not a directory */
}
if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
(void)close(fd);
errno = ENOMEM;
return NULL; /* not enough memory */
}
dirp->dd_fd = fd;
dirp->dd_nleft = 0; /* refill needed */
return dirp;
}
int
closedir(dirp)
register DIR *dirp; /* stream from opendir() */
{
register int fd;
if (dirp == NULL) {
errno = EFAULT;
return -1; /* invalid pointer */
}
fd = dirp->dd_fd;
free((pointer)dirp);
return close(fd);
}
struct dirent *
readdir(dirp)
register DIR *dirp; /* stream from opendir() */
{
register struct direct *dp;
register char *p, *q;
register int i;
do {
if ((dirp->dd_nleft -= sizeof (struct direct)) < 0) {
if ((i = read(dirp->dd_fd,
(char *)dirp->dd_buf,
DIRBUFENT*sizeof(struct direct))) <= 0) {
if (i == 0)
errno = 0; /* unnecessary */
return NULL; /* EOF or error */
}
dirp->dd_loc = dirp->dd_buf;
dirp->dd_nleft = i - sizeof (struct direct);
}
dp = dirp->dd_loc++;
} while (dp->d_ino == 0);
dirp->dd_entry.d_ino = dp->d_ino;
/* now copy the name, nul terminating it */
p = dp->d_name;
q = dirp->dd_entry.d_name;
i = DIRSIZ;
while (--i >= 0 && *p != '\0')
*q++ = *p++;
*q = '\0';
return &dirp->dd_entry;
}
#endif /* BSD */
#endif /* DIRENT */

127
commands/ash/errmsg.c Normal file
View File

@@ -0,0 +1,127 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)errmsg.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
#include "shell.h"
#include "output.h"
#include "errmsg.h"
#include <errno.h>
#define ALL (E_OPEN|E_CREAT|E_EXEC)
struct errname {
short errcode; /* error number */
short action; /* operation which encountered the error */
char *msg; /* text describing the error */
};
STATIC const struct errname errormsg[] = {
EINTR, ALL, "interrupted",
EACCES, ALL, "permission denied",
EIO, ALL, "I/O error",
ENOENT, E_OPEN, "no such file",
ENOENT, E_CREAT, "directory nonexistent",
ENOENT, E_EXEC, "not found",
ENOTDIR, E_OPEN, "no such file",
ENOTDIR, E_CREAT, "directory nonexistent",
ENOTDIR, E_EXEC, "not found",
EISDIR, ALL, "is a directory",
/* EMFILE, ALL, "too many open files", */
ENFILE, ALL, "file table overflow",
ENOSPC, ALL, "file system full",
#ifdef EDQUOT
EDQUOT, ALL, "disk quota exceeded",
#endif
#ifdef ENOSR
ENOSR, ALL, "no streams resources",
#endif
ENXIO, ALL, "no such device or address",
EROFS, ALL, "read-only file system",
ETXTBSY, ALL, "text busy",
#ifdef SYSV
EAGAIN, E_EXEC, "not enough memory",
#endif
ENOMEM, ALL, "not enough memory",
#ifdef ENOLINK
ENOLINK, ALL, "remote access failed"
#endif
#ifdef EMULTIHOP
EMULTIHOP, ALL, "remote access failed",
#endif
#ifdef ECOMM
ECOMM, ALL, "remote access failed",
#endif
#ifdef ESTALE
ESTALE, ALL, "remote access failed",
#endif
#ifdef ETIMEDOUT
ETIMEDOUT, ALL, "remote access failed",
#endif
#ifdef ELOOP
ELOOP, ALL, "symbolic link loop",
#endif
E2BIG, E_EXEC, "argument list too long",
#ifdef ELIBACC
ELIBACC, E_EXEC, "shared library missing",
#endif
0, 0, NULL
};
/*
* Return a string describing an error. The returned string may be a
* pointer to a static buffer that will be overwritten on the next call.
* Action describes the operation that got the error.
*/
char *
errmsg(e, action) {
struct errname const *ep;
static char buf[12];
for (ep = errormsg ; ep->errcode ; ep++) {
if (ep->errcode == e && (ep->action & action) != 0)
return ep->msg;
}
fmtstr(buf, sizeof buf, "error %d", e);
return buf;
}

47
commands/ash/errmsg.h Normal file
View File

@@ -0,0 +1,47 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)errmsg.h 8.1 (Berkeley) 5/31/93
*/
#define E_OPEN 01
#define E_CREAT 02
#define E_EXEC 04
#ifdef __STDC__
char *errmsg(int, int);
#else
char *errmsg();
#endif

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,14 @@
*/
#ifndef lint
static char sccsid[] = "@(#)error.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/error.c,v 1.25 2004/04/06 20:06:51 markm Exp $");
*/
/*
* Errors and exceptions.
@@ -47,14 +49,14 @@ static char sccsid[] = "@(#)error.c 5.1 (Berkeley) 3/7/91";
#include "options.h"
#include "output.h"
#include "error.h"
#include <sys/types.h>
#include "nodes.h" /* show.h needs nodes.h */
#include "show.h"
#include "trap.h"
#include <signal.h>
#ifdef __STDC__
#include "stdarg.h"
#else
#include <varargs.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
/*
@@ -62,12 +64,14 @@ static char sccsid[] = "@(#)error.c 5.1 (Berkeley) 3/7/91";
*/
struct jmploc *handler;
int exception;
volatile int suppressint;
volatile int intpending;
volatile sig_atomic_t exception;
volatile sig_atomic_t suppressint;
volatile sig_atomic_t intpending;
char *commandname;
static void exverror(int, const char *, va_list) __printf0like(2, 0);
/*
* Called to raise an exception. Since C doesn't include exceptions, we
* just do a longjmp to the exception handler. The type of exception is
@@ -75,7 +79,8 @@ char *commandname;
*/
void
exraise(e) {
exraise(int e)
{
if (handler == NULL)
abort();
exception = e;
@@ -87,69 +92,63 @@ exraise(e) {
* Called from trap.c when a SIGINT is received. (If the user specifies
* that SIGINT is to be trapped or ignored using the trap builtin, then
* this routine is not called.) Suppressint is nonzero when interrupts
* are held using the INTOFF macro. The call to _exit is necessary because
* there is a short period after a fork before the signal handlers are
* set to the appropriate value for the child. (The test for iflag is
* just defensive programming.)
* are held using the INTOFF macro. If SIGINTs are not suppressed and
* the shell is not a root shell, then we want to be terminated if we
* get here, as if we were terminated directly by a SIGINT. Arrange for
* this here.
*/
void
onint() {
if (suppressint) {
onint(void)
{
sigset_t sigset;
/*
* The !in_dotrap here is safe. The only way we can arrive here
* with in_dotrap set is that a trap handler set SIGINT to SIG_DFL
* and killed itself.
*/
if (suppressint && !in_dotrap) {
intpending++;
return;
}
intpending = 0;
#ifdef BSD
sigsetmask(0);
sigemptyset(&sigset);
sigprocmask(SIG_SETMASK, &sigset, NULL);
/*
* This doesn't seem to be needed, since main() emits a newline.
*/
#if 0
if (tcgetpgrp(0) == getpid())
write(STDERR_FILENO, "\n", 1);
#endif
if (rootshell && iflag)
exraise(EXINT);
else
_exit(128 + SIGINT);
}
void
error2(a, b)
char *a, *b;
{
error("%s: %s", a, b);
else {
signal(SIGINT, SIG_DFL);
kill(getpid(), SIGINT);
}
}
/*
* Error is called to raise the error exception. If the first argument
* Exverror is called to raise the error exception. If the first argument
* is not NULL then error prints an error message using printf style
* formatting. It then raises the error exception.
*/
#ifdef __STDC__
void
error(char *msg, ...) {
#else
void
error(va_alist)
va_dcl
{
char *msg;
#endif
va_list ap;
static void
exverror(int cond, const char *msg, va_list ap)
{
CLEAR_PENDING_INT;
INTOFF;
#ifdef __STDC__
va_start(ap, msg);
#else
va_start(ap);
msg = va_arg(ap, char *);
#endif
#if DEBUG
if (msg)
TRACE(("error(\"%s\") pid=%d\n", msg, getpid()));
TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
else
TRACE(("error(NULL) pid=%d\n", getpid()));
TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
#endif
if (msg) {
if (commandname)
@@ -157,96 +156,30 @@ error(va_alist)
doformat(&errout, msg, ap);
out2c('\n');
}
va_end(ap);
flushall();
exraise(EXERROR);
exraise(cond);
}
#ifdef notdef /* These strange error messages only confuse. -- kjb */
/*
* Table of error messages.
*/
struct errname {
short errcode; /* error number */
short action; /* operation which encountered the error */
char *msg; /* text describing the error */
};
#define ALL (E_OPEN|E_CREAT|E_EXEC)
STATIC const struct errname errormsg[] = {
EINTR, ALL, "interrupted",
EACCES, ALL, "permission denied",
EIO, ALL, "I/O error",
ENOENT, E_OPEN, "no such file",
ENOENT, E_CREAT, "directory nonexistent",
ENOENT, E_EXEC, "not found",
ENOTDIR, E_OPEN, "no such file",
ENOTDIR, E_CREAT, "directory nonexistent",
ENOTDIR, E_EXEC, "not found",
ENOEXEC, ALL, "not an executable",
EISDIR, ALL, "is a directory",
/* EMFILE, ALL, "too many open files", */
ENFILE, ALL, "file table overflow",
ENOSPC, ALL, "file system full",
#ifdef EDQUOT
EDQUOT, ALL, "disk quota exceeded",
#endif
#ifdef ENOSR
ENOSR, ALL, "no streams resources",
#endif
ENXIO, ALL, "no such device or address",
EROFS, ALL, "read-only file system",
ETXTBSY, ALL, "text busy",
#ifdef SYSV
EAGAIN, E_EXEC, "not enough memory",
#endif
ENOMEM, ALL, "not enough memory",
#ifdef ENOLINK
ENOLINK, ALL, "remote access failed",
#endif
#ifdef EMULTIHOP
EMULTIHOP, ALL, "remote access failed",
#endif
#ifdef ECOMM
ECOMM, ALL, "remote access failed",
#endif
#ifdef ESTALE
ESTALE, ALL, "remote access failed",
#endif
#ifdef ETIMEDOUT
ETIMEDOUT, ALL, "remote access failed",
#endif
#ifdef ELOOP
ELOOP, ALL, "symbolic link loop",
#endif
E2BIG, E_EXEC, "argument list too long",
#ifdef ELIBACC
ELIBACC, E_EXEC, "shared library missing",
#endif
0, 0, NULL
};
/*
* Return a string describing an error. The returned string may be a
* pointer to a static buffer that will be overwritten on the next call.
* Action describes the operation that got the error.
*/
char *
errmsg(e, action) {
const struct errname *ep;
static char buf[12];
for (ep = errormsg ; ep->errcode ; ep++) {
if (ep->errcode == e && (ep->action & action) != 0)
return ep->msg;
}
fmtstr(buf, sizeof buf, "error %d", e);
return buf;
void
error(const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
exverror(EXERROR, msg, ap);
va_end(ap);
}
#endif
void
exerror(int cond, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
exverror(cond, msg, ap);
va_end(ap);
}
/*
* $PchId: error.c,v 1.5 2006/04/10 14:36:23 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,41 +29,35 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)error.h 5.1 (Berkeley) 3/7/91
* @(#)error.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/error.h,v 1.17 2004/04/06 20:06:51 markm Exp $
*/
/*
* Types of operations (passed to the errmsg routine).
*/
#define E_OPEN 01 /* opening a file */
#define E_CREAT 02 /* creating a file */
#define E_EXEC 04 /* executing a program */
/*
* We enclose jmp_buf in a structure so that we can declare pointers to
* jump locations. The global variable handler contains the location to
* jump to when an exception occurs, and the global variable exception
* contains a code identifying the exeception. To implement nested
* contains a code identifying the exception. To implement nested
* exception handlers, the user should save the value of handler on entry
* to an inner scope, set handler to point to a jmploc structure for the
* inner scope, and restore handler on exit from the scope.
*/
#include <setjmp.h>
#include <signal.h>
struct jmploc {
jmp_buf loc;
};
extern struct jmploc *handler;
extern int exception;
extern volatile sig_atomic_t exception;
/* exceptions */
#define EXINT 0 /* SIGINT received */
#define EXERROR 1 /* a generic error */
#define EXSHELLPROC 2 /* execute a shell procedure */
#define EXEXEC 3 /* command execution failed */
/*
@@ -77,32 +67,21 @@ extern int exception;
* more fun than worrying about efficiency and portability. :-))
*/
extern volatile int suppressint;
extern volatile int intpending;
extern char *commandname; /* name of command--printed on error */
extern volatile sig_atomic_t suppressint;
extern volatile sig_atomic_t intpending;
#define INTOFF suppressint++
#define INTON if (--suppressint == 0 && intpending) onint(); else
#define INTON { if (--suppressint == 0 && intpending) onint(); }
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
#define CLEAR_PENDING_INT intpending = 0
#define int_pending() intpending
#ifdef __STDC__
#define __printf0like(a,b)
void exraise(int);
void onint(void);
void error2(char *, char *);
void error(char *, ...);
char *errmsg(int, int);
#else
void exraise();
void onint();
void error2();
void error();
char *errmsg();
#endif
/* Errmsg uses confusingly different messages. Prefer strerror(). -- kjb */
#define errmsg(errno, action) strerror(errno)
void error(const char *, ...) __printf0like(1, 2);
void exerror(int, const char *, ...) __printf0like(2, 3);
/*
@@ -111,6 +90,12 @@ char *errmsg();
*/
#ifdef BSD
#ifndef __minix
#define setjmp(jmploc) _setjmp(jmploc)
#define longjmp(jmploc, val) _longjmp(jmploc, val)
#endif
#endif
/*
* $PchId: error.h,v 1.5 2006/04/10 14:36:43 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,23 @@
*/
#ifndef lint
static char sccsid[] = "@(#)eval.c 5.3 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/eval.c,v 1.42 2004/04/06 20:06:51 markm Exp $");
*/
#ifndef NO_PATHS_H
#include <paths.h>
#endif
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> /* For WIFSIGNALED(status) */
#include <errno.h>
/*
* Evaluate a command.
@@ -59,22 +70,21 @@ static char sccsid[] = "@(#)eval.c 5.3 (Berkeley) 4/12/91";
#include "var.h"
#include "memalloc.h"
#include "error.h"
#include "show.h"
#include "mystring.h"
#include <sys/types.h>
#include <signal.h>
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
#ifndef _PATH_STDPATH
#define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin:"
#endif
/* flags in argument to evaltree */
#define EV_EXIT 01 /* exit after evaluating tree */
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
#define EV_BACKCMD 04 /* command executing within back quotes */
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
#define SKIPFUNC 3
MKINIT int evalskip; /* set if we are skipping commands */
STATIC int skipcount; /* number of levels to skip */
MKINIT int loopnest; /* current loop nesting level */
@@ -87,7 +97,6 @@ int exitstatus; /* exit status of last command */
int oexitstatus; /* saved exit status */
#ifdef __STDC__
STATIC void evalloop(union node *);
STATIC void evalfor(union node *);
STATIC void evalcase(union node *, int);
@@ -96,17 +105,6 @@ STATIC void expredir(union node *);
STATIC void evalpipe(union node *);
STATIC void evalcommand(union node *, int, struct backcmd *);
STATIC void prehash(union node *);
#else
STATIC void evalloop();
STATIC void evalfor();
STATIC void evalcase();
STATIC void evalsubshell();
STATIC void expredir();
STATIC void evalpipe();
STATIC void evalcommand();
STATIC void prehash();
#endif
/*
@@ -130,11 +128,11 @@ SHELLPROC {
/*
* The eval commmand.
* The eval command.
*/
evalcmd(argc, argv)
char **argv;
int
evalcmd(int argc, char **argv)
{
char *p;
char *concat;
@@ -166,9 +164,8 @@ evalcmd(argc, argv)
*/
void
evalstring(s)
char *s;
{
evalstring(char *s)
{
union node *n;
struct stackmark smark;
@@ -190,14 +187,17 @@ evalstring(s)
*/
void
evaltree(n, flags)
union node *n;
{
evaltree(union node *n, int flags)
{
if (n == NULL) {
TRACE(("evaltree(NULL) called\n"));
return;
exitstatus = 0;
goto out;
}
TRACE(("evaltree(0x%x: %d) called\n", (int)n, n->type));
#if !defined(NO_HISTORY) && !defined(EDITLINE)
displayhist = 1; /* show history substitutions done with fc */
#endif
TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
switch (n->type) {
case NSEMI:
evaltree(n->nbinary.ch1, 0);
@@ -207,8 +207,9 @@ evaltree(n, flags)
break;
case NAND:
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip || exitstatus != 0)
if (evalskip || exitstatus != 0) {
goto out;
}
evaltree(n->nbinary.ch2, flags);
break;
case NOR:
@@ -230,19 +231,15 @@ evaltree(n, flags)
evalsubshell(n, flags);
break;
case NIF: {
int status = 0;
evaltree(n->nif.test, EV_TESTED);
if (evalskip)
goto out;
if (exitstatus == 0) {
if (exitstatus == 0)
evaltree(n->nif.ifpart, flags);
status = exitstatus;
} else if (n->nif.elsepart) {
else if (n->nif.elsepart)
evaltree(n->nif.elsepart, flags);
status = exitstatus;
}
exitstatus = status;
else
exitstatus = 0;
break;
}
case NWHILE:
@@ -259,6 +256,11 @@ evaltree(n, flags)
defun(n->narg.text, n->narg.next);
exitstatus = 0;
break;
case NNOT:
evaltree(n->nnot.com, EV_TESTED);
exitstatus = !exitstatus;
break;
case NPIPE:
evalpipe(n);
break;
@@ -273,18 +275,16 @@ evaltree(n, flags)
out:
if (pendingsigs)
dotrap();
if ((flags & EV_EXIT) || (eflag && exitstatus
&& !(flags & EV_TESTED) && (n->type == NCMD ||
n->type == NSUBSHELL))) {
if ((flags & EV_EXIT) || (eflag && exitstatus
&& !(flags & EV_TESTED) && (n->type == NCMD ||
n->type == NSUBSHELL)))
exitshell(exitstatus);
}
}
STATIC void
evalloop(n)
union node *n;
{
evalloop(union node *n)
{
int status;
loopnest++;
@@ -319,9 +319,8 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
STATIC void
evalfor(n)
union node *n;
{
evalfor(union node *n)
{
struct arglist arglist;
union node *argp;
struct strlist *sp;
@@ -331,7 +330,7 @@ evalfor(n)
arglist.lastp = &arglist.list;
for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
oexitstatus = exitstatus;
expandarg(argp, &arglist, 1);
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
if (evalskip)
goto out;
}
@@ -360,9 +359,8 @@ out:
STATIC void
evalcase(n, flags)
union node *n;
{
evalcase(union node *n, int flags)
{
union node *cp;
union node *patp;
struct arglist arglist;
@@ -370,8 +368,8 @@ evalcase(n, flags)
setstackmark(&smark);
arglist.lastp = &arglist.list;
oexitstatus = exitstatus;
expandarg(n->ncase.expr, &arglist, 0);
oexitstatus = exitstatus;
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
if (casematch(patp, arglist.list->text)) {
@@ -393,9 +391,8 @@ out:
*/
STATIC void
evalsubshell(n, flags)
union node *n;
{
evalsubshell(union node *n, int flags)
{
struct job *jp;
int backgnd = (n->type == NBACKGND);
@@ -409,7 +406,7 @@ evalsubshell(n, flags)
}
if (! backgnd) {
INTOFF;
exitstatus = waitforjob(jp);
exitstatus = waitforjob(jp, (int *)NULL);
INTON;
}
}
@@ -421,20 +418,30 @@ evalsubshell(n, flags)
*/
STATIC void
expredir(n)
union node *n;
{
register union node *redir;
expredir(union node *n)
{
union node *redir;
for (redir = n ; redir ; redir = redir->nfile.next) {
struct arglist fn;
fn.lastp = &fn.list;
oexitstatus = exitstatus;
if (redir->type == NFROM
|| redir->type == NTO
|| redir->type == NAPPEND) {
struct arglist fn;
fn.lastp = &fn.list;
expandarg(redir->nfile.fname, &fn, 0);
switch (redir->type) {
case NFROM:
case NTO:
case NFROMTO:
case NAPPEND:
case NCLOBBER:
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
redir->nfile.expfname = fn.list->text;
break;
case NFROMFD:
case NTOFD:
if (redir->ndup.vname) {
expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
fixredir(redir, fn.list->text, 1);
}
break;
}
}
}
@@ -449,16 +456,15 @@ expredir(n)
*/
STATIC void
evalpipe(n)
union node *n;
{
evalpipe(union node *n)
{
struct job *jp;
struct nodelist *lp;
int pipelen;
int prevfd;
int pip[2];
TRACE(("evalpipe(0x%x) called\n", (int)n));
TRACE(("evalpipe(0x%lx) called\n", (long)n));
pipelen = 0;
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
pipelen++;
@@ -471,21 +477,20 @@ evalpipe(n)
if (lp->next) {
if (pipe(pip) < 0) {
close(prevfd);
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
}
}
if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
INTON;
if (prevfd > 0) {
close(0);
copyfd(prevfd, 0);
dup2(prevfd, 0);
close(prevfd);
}
if (pip[1] >= 0) {
close(pip[0]);
if (!(prevfd >= 0 && pip[0] == 0))
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
dup2(pip[1], 1);
close(pip[1]);
}
}
@@ -499,7 +504,7 @@ evalpipe(n)
INTON;
if (n->npipe.backgnd == 0) {
INTOFF;
exitstatus = waitforjob(jp);
exitstatus = waitforjob(jp, (int *)NULL);
TRACE(("evalpipe: job done exit status %d\n", exitstatus));
INTON;
}
@@ -515,10 +520,8 @@ evalpipe(n)
*/
void
evalbackcmd(n, result)
union node *n;
struct backcmd *result;
{
evalbackcmd(union node *n, struct backcmd *result)
{
int pip[2];
struct job *jp;
struct stackmark smark; /* unnecessary */
@@ -529,21 +532,22 @@ evalbackcmd(n, result)
result->nleft = 0;
result->jp = NULL;
if (n == NULL) {
/* `` */
} else
exitstatus = 0;
goto out;
}
if (n->type == NCMD) {
exitstatus = oexitstatus;
exitstatus = oexitstatus;
evalcommand(n, EV_BACKCMD, result);
} else {
exitstatus = 0;
if (pipe(pip) < 0)
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
jp = makejob(n, 1);
if (forkshell(jp, n, FORK_NOJOB) == 0) {
FORCEINTON;
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
dup2(pip[1], 1);
close(pip[1]);
}
evaltree(n, EV_EXIT);
@@ -552,8 +556,9 @@ evalbackcmd(n, result)
result->fd = pip[0];
result->jp = jp;
}
out:
popstackmark(&smark);
TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n",
result->fd, result->buf, result->nleft, result->jp));
}
@@ -564,10 +569,8 @@ evalbackcmd(n, result)
*/
STATIC void
evalcommand(cmd, flags, backcmd)
union node *cmd;
struct backcmd *backcmd;
{
evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
{
struct stackmark smark;
union node *argp;
struct arglist arglist;
@@ -577,7 +580,6 @@ evalcommand(cmd, flags, backcmd)
char **envp;
int varflag;
struct strlist *sp;
register char *p;
int mode;
int pip[2];
struct cmdentry cmdentry;
@@ -589,27 +591,38 @@ evalcommand(cmd, flags, backcmd)
struct localvar *volatile savelocalvars;
volatile int e;
char *lastarg;
int realstatus;
int do_clearcmdentry;
#if __GNUC__
/* Avoid longjmp clobbering */
(void) &argv;
(void) &argc;
(void) &lastarg;
(void) &flags;
(void) &do_clearcmdentry;
#endif
/* First expand the arguments. */
TRACE(("evalcommand(0x%x, %d) called\n", (int)cmd, flags));
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
setstackmark(&smark);
arglist.lastp = &arglist.list;
varlist.lastp = &varlist.list;
varflag = 1;
oexitstatus = exitstatus;
do_clearcmdentry = 0;
oexitstatus = exitstatus;
exitstatus = 0;
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
p = argp->narg.text;
char *p = argp->narg.text;
if (varflag && is_name(*p)) {
do {
p++;
} while (is_in_name(*p));
if (*p == '=') {
expandarg(argp, &varlist, 0);
expandarg(argp, &varlist, EXP_VARTILDE);
continue;
}
}
expandarg(argp, &arglist, 1);
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
varflag = 0;
}
*arglist.lastp = NULL;
@@ -619,8 +632,11 @@ evalcommand(cmd, flags, backcmd)
for (sp = arglist.list ; sp ; sp = sp->next)
argc++;
argv = stalloc(sizeof (char *) * (argc + 1));
for (sp = arglist.list ; sp ; sp = sp->next)
for (sp = arglist.list ; sp ; sp = sp->next) {
TRACE(("evalcommand arg: %s\n", sp->text));
*argv++ = sp->text;
}
*argv = NULL;
lastarg = NULL;
if (iflag && funcnest == 0 && argc > 0)
@@ -628,7 +644,7 @@ evalcommand(cmd, flags, backcmd)
argv -= argc;
/* Print the command if xflag is set. */
if (xflag == 1) {
if (xflag) {
outc('+', &errout);
for (sp = varlist.list ; sp ; sp = sp->next) {
outc(' ', &errout);
@@ -647,11 +663,42 @@ evalcommand(cmd, flags, backcmd)
cmdentry.cmdtype = CMDBUILTIN;
cmdentry.u.index = BLTINCMD;
} else {
find_command(argv[0], &cmdentry, 1);
static const char PATH[] = "PATH=";
char *path = pathval();
/*
* Modify the command lookup path, if a PATH= assignment
* is present
*/
for (sp = varlist.list ; sp ; sp = sp->next)
if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
path = sp->text + sizeof(PATH) - 1;
/*
* On `PATH=... command`, we need to make
* sure that the command isn't using the
* non-updated hash table of the outer PATH
* setting and we need to make sure that
* the hash table isn't filled with items
* from the temporary setting.
*
* It would be better to forbit using and
* updating the table while this command
* runs, by the command finding mechanism
* is heavily integrated with hash handling,
* so we just delete the hash before and after
* the command runs. Partly deleting like
* changepatch() does doesn't seem worth the
* bookinging effort, since most such runs add
* directories in front of the new PATH.
*/
clearcmdentry(0);
do_clearcmdentry = 1;
}
find_command(argv[0], &cmdentry, 1, path);
if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
exitstatus = 2;
exitstatus = 127;
flushout(&errout);
popstackmark(&smark);
return;
}
/* implement the bltin builtin here */
@@ -662,9 +709,8 @@ evalcommand(cmd, flags, backcmd)
break;
if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
outfmt(&errout, "%s: not found\n", *argv);
exitstatus = 2;
exitstatus = 127;
flushout(&errout);
popstackmark(&smark);
return;
}
if (cmdentry.u.index != BLTINCMD)
@@ -675,17 +721,21 @@ evalcommand(cmd, flags, backcmd)
/* Fork off a child process if necessary. */
if (cmd->ncmd.backgnd
|| cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0
|| (flags & EV_BACKCMD) != 0
|| (cmdentry.cmdtype == CMDNORMAL
&& ((flags & EV_EXIT) == 0 || Tflag))
|| ((flags & EV_BACKCMD) != 0
&& (cmdentry.cmdtype != CMDBUILTIN
|| cmdentry.u.index == CDCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD)) {
|| cmdentry.u.index == EVALCMD))
|| (cmdentry.cmdtype == CMDBUILTIN &&
cmdentry.u.index == COMMANDCMD)) {
jp = makejob(cmd, 1);
mode = cmd->ncmd.backgnd;
if (flags & EV_BACKCMD) {
mode = FORK_NOJOB;
if (pipe(pip) < 0)
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
}
if (forkshell(jp, cmd, mode) != 0)
goto parent; /* at end of routine */
@@ -693,8 +743,7 @@ evalcommand(cmd, flags, backcmd)
FORCEINTON;
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
dup2(pip[1], 1);
close(pip[1]);
}
}
@@ -704,10 +753,13 @@ evalcommand(cmd, flags, backcmd)
/* This is the child process if a fork occurred. */
/* Execute the command. */
if (cmdentry.cmdtype == CMDFUNCTION) {
#if DEBUG
trputs("Shell function: "); trargs(argv);
#endif
redirect(cmd->ncmd.redirect, REDIR_PUSH);
saveparam = shellparam;
shellparam.malloc = 0;
shellparam.reset = 1;
shellparam.nparam = argc - 1;
shellparam.p = argv + 1;
shellparam.optnext = NULL;
@@ -752,7 +804,9 @@ evalcommand(cmd, flags, backcmd)
if (flags & EV_EXIT)
exitshell(exitstatus);
} else if (cmdentry.cmdtype == CMDBUILTIN) {
#if DEBUG
trputs("builtin command: "); trargs(argv);
#endif
mode = (cmdentry.u.index == EXECCMD)? 0 : REDIR_PUSH;
if (flags == EV_BACKCMD) {
memout.nleft = 0;
@@ -777,6 +831,7 @@ evalcommand(cmd, flags, backcmd)
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
flushall();
cmddone:
cmdenviron = NULL;
out1 = &output;
out2 = &errout;
freestdout();
@@ -788,10 +843,15 @@ cmddone:
}
handler = savehandler;
if (e != -1) {
if (e != EXERROR || cmdentry.u.index == BLTINCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD
|| cmdentry.u.index == EXECCMD)
if ((e != EXERROR && e != EXEXEC)
|| cmdentry.u.index == BLTINCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD
#ifndef NO_HISTORY
|| cmdentry.u.index == HISTCMD
#endif
|| cmdentry.u.index == EXECCMD
|| cmdentry.u.index == COMMANDCMD)
exraise(e);
FORCEINTON;
}
@@ -803,19 +863,15 @@ cmddone:
memout.buf = NULL;
}
} else {
#if DEBUG
trputs("normal command: "); trargs(argv);
#endif
clearredir();
redirect(cmd->ncmd.redirect, 0);
if (varlist.list) {
p = stalloc(strlen(pathval()) + 1);
scopy(pathval(), p);
} else {
p = pathval();
}
for (sp = varlist.list ; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
envp = environment();
shellexec(argv, envp, p, cmdentry.u.index);
shellexec(argv, envp, pathval(), cmdentry.u.index);
/*NOTREACHED*/
}
goto out;
@@ -823,8 +879,12 @@ cmddone:
parent: /* parent process gets here (if we forked) */
if (mode == 0) { /* argument to fork */
INTOFF;
exitstatus = waitforjob(jp);
exitstatus = waitforjob(jp, &realstatus);
INTON;
if (iflag && loopnest > 0 && WIFSIGNALED(realstatus)) {
evalskip = SKIPBREAK;
skipcount = loopnest;
}
} else if (mode == 2) {
backcmd->fd = pip[0];
close(pip[1]);
@@ -834,6 +894,8 @@ parent: /* parent process gets here (if we forked) */
out:
if (lastarg)
setvar("_", lastarg, 0);
if (do_clearcmdentry)
clearcmdentry(0);
popstackmark(&smark);
}
@@ -847,13 +909,14 @@ out:
*/
STATIC void
prehash(n)
union node *n;
{
prehash(union node *n)
{
struct cmdentry entry;
if (n->type == NCMD && goodname(n->ncmd.args->narg.text))
find_command(n->ncmd.args->narg.text, &entry, 0);
if (n->type == NCMD && n->ncmd.args)
if (goodname(n->ncmd.args->narg.text))
find_command(n->ncmd.args->narg.text, &entry, 0,
pathval());
}
@@ -868,8 +931,14 @@ prehash(n)
* specified variables.
*/
bltincmd(argc, argv) char **argv; {
int
bltincmd(int argc __unused, char **argv __unused)
{
listsetvar(cmdenviron);
/*
* Preserve exitstatus of a previous possible redirection
* as POSIX mandates
*/
return exitstatus;
}
@@ -885,12 +954,11 @@ bltincmd(argc, argv) char **argv; {
* in the standard shell so we don't make it one here.
*/
breakcmd(argc, argv) char **argv; {
int n;
int
breakcmd(int argc, char **argv)
{
int n = argc > 1 ? number(argv[1]) : 1;
n = 1;
if (argc > 1)
n = number(argv[1]);
if (n > loopnest)
n = loopnest;
if (n > 0) {
@@ -900,40 +968,108 @@ breakcmd(argc, argv) char **argv; {
return 0;
}
/*
* The `command' command.
*/
int
commandcmd(int argc, char **argv)
{
static char stdpath[] = _PATH_STDPATH;
struct jmploc loc, *old;
struct strlist *sp;
char *path;
int ch;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
path = pathval();
optind = optreset = 1;
opterr = 0;
while ((ch = getopt(argc, argv, "p")) != -1) {
switch (ch) {
case 'p':
path = stdpath;
break;
case '?':
default:
error("unknown option: -%c", optopt);
}
}
argc -= optind;
argv += optind;
if (argc != 0) {
old = handler;
handler = &loc;
if (setjmp(handler->loc) == 0)
shellexec(argv, environment(), path, 0);
handler = old;
if (exception == EXEXEC)
exit(exerrno);
exraise(exception);
}
/*
* Do nothing successfully if no command was specified;
* ksh also does this.
*/
exit(0);
}
/*
* The return command.
*/
returncmd(argc, argv) char **argv; {
int ret;
int
returncmd(int argc, char **argv)
{
int ret = argc > 1 ? number(argv[1]) : oexitstatus;
ret = oexitstatus;
if (argc > 1)
ret = number(argv[1]);
if (funcnest) {
evalskip = SKIPFUNC;
skipcount = 1;
} else {
/* skip the rest of the file */
evalskip = SKIPFILE;
skipcount = 1;
}
return ret;
}
truecmd(argc, argv) char **argv; {
return strcmp(argv[0], "false") == 0 ? 1 : 0;
int
falsecmd(int argc __unused, char **argv __unused)
{
return 1;
}
execcmd(argc, argv) char **argv; {
int
truecmd(int argc __unused, char **argv __unused)
{
return 0;
}
int
execcmd(int argc, char **argv)
{
if (argc > 1) {
struct strlist *sp;
iflag = 0; /* exit on error */
setinteractive(0);
#if JOBS
jflag = 0;
setjobctl(0);
#endif
mflag = 0;
optschanged();
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
shellexec(argv + 1, environment(), pathval(), 0);
}
return 0;
}
/*
* $PchId: eval.c,v 1.7 2006/04/10 14:46:14 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)eval.h 5.2 (Berkeley) 4/12/91
* @(#)eval.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/eval.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
extern char *commandname; /* currently executing command */
@@ -48,18 +45,30 @@ struct backcmd { /* result of evalbackcmd */
struct job *jp; /* job structure for command */
};
#ifdef __STDC__
int evalcmd(int, char **);
void evalstring(char *);
union node; /* BLETCH for ansi C */
void evaltree(union node *, int);
void evalbackcmd(union node *, struct backcmd *);
#else
void evalstring();
void evaltree();
void evalbackcmd();
#endif
int bltincmd(int, char **);
int breakcmd(int, char **);
int returncmd(int, char **);
int falsecmd(int, char **);
int truecmd(int, char **);
int execcmd(int, char **);
int commandcmd(int, char **);
/* in_function returns nonzero if we are currently evaluating a function */
#define in_function() funcnest
extern int funcnest;
extern int evalskip;
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
#define SKIPFUNC 3
#define SKIPFILE 4
/*
* $PchId: eval.h,v 1.3 2006/03/30 15:39:25 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,21 @@
*/
#ifndef lint
static char sccsid[] = "@(#)exec.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/exec.c,v 1.24.2.1 2004/09/30 04:41:55 des Exp $");
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
/*
* When commands are first encountered, they are entered in a hash table.
@@ -64,11 +73,9 @@ static char sccsid[] = "@(#)exec.c 5.2 (Berkeley) 3/13/91";
#include "error.h"
#include "init.h"
#include "mystring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include "show.h"
#include "jobs.h"
#include "alias.h"
#define CMDTABLESIZE 31 /* should be prime */
@@ -87,23 +94,14 @@ struct tblentry {
STATIC struct tblentry *cmdtable[CMDTABLESIZE];
STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */
int exerrno = 0; /* Last exec error */
#ifdef __STDC__
STATIC void tryexec(char *, char **, char **);
STATIC void execinterp(char **, char **);
STATIC void printentry(struct tblentry *);
STATIC void clearcmdentry(int);
STATIC void printentry(struct tblentry *, int);
STATIC struct tblentry *cmdlookup(char *, int);
STATIC void delete_cmd_entry(void);
#else
STATIC void tryexec();
STATIC void execinterp();
STATIC void printentry();
STATIC void clearcmdentry();
STATIC struct tblentry *cmdlookup();
STATIC void delete_cmd_entry();
#endif
STATIC void addcmdentry(char *, struct cmdentry *);
@@ -113,10 +111,8 @@ STATIC void delete_cmd_entry();
*/
void
shellexec(argv, envp, path, index)
char **argv, **envp;
char *path;
{
shellexec(char **argv, char **envp, char *path, int index)
{
char *cmdname;
int e;
@@ -134,40 +130,37 @@ shellexec(argv, envp, path, index)
stunalloc(cmdname);
}
}
error2(argv[0], errmsg(e, E_EXEC));
/* Map to POSIX errors */
switch (e) {
case EACCES:
exerrno = 126;
break;
case ENOENT:
exerrno = 127;
break;
default:
exerrno = 2;
break;
}
if (e == ENOENT || e == ENOTDIR)
exerror(EXEXEC, "%s: not found", argv[0]);
exerror(EXEXEC, "%s: %s", argv[0], strerror(e));
}
STATIC void
tryexec(cmd, argv, envp)
char *cmd;
char **argv;
char **envp;
{
tryexec(char *cmd, char **argv, char **envp)
{
int e;
char *p;
#ifdef SYSV
do {
execve(cmd, argv, envp);
} while (errno == EINTR);
#else
execve(cmd, argv, envp);
#endif
#if HASHBANG
#if !__minix_vmd
e = errno;
if (e == ENOEXEC) {
initshellproc();
setinputfile(cmd, 0);
commandname = arg0 = savestr(argv[0]);
#ifndef BSD
pgetc(); pungetc(); /* fill up input buffer */
p = parsenextc;
if (parsenleft > 2 && p[0] == '#' && p[1] == '!') {
argv[0] = cmd;
execinterp(argv, envp);
}
#endif
setparam(argv + 1);
exraise(EXSHELLPROC);
/*NOTREACHED*/
@@ -176,88 +169,6 @@ tryexec(cmd, argv, envp)
#endif
}
#if !defined(BSD) && HASHBANG
/*
* Execute an interpreter introduced by "#!", for systems where this
* feature has not been built into the kernel. If the interpreter is
* the shell, return (effectively ignoring the "#!"). If the execution
* of the interpreter fails, exit.
*
* This code peeks inside the input buffer in order to avoid actually
* reading any input. It would benefit from a rewrite.
*/
#define NEWARGS 5
STATIC void
execinterp(argv, envp)
char **argv, **envp;
{
int n;
char *inp;
char *outp;
char c;
char *p;
char **ap;
char *newargs[NEWARGS];
int i;
char **ap2;
char **new;
n = parsenleft - 2;
inp = parsenextc + 2;
ap = newargs;
for (;;) {
while (--n >= 0 && (*inp == ' ' || *inp == '\t'))
inp++;
if (n < 0)
goto bad;
if ((c = *inp++) == '\n')
break;
if (ap == &newargs[NEWARGS])
bad: error("Bad #! line");
STARTSTACKSTR(outp);
do {
STPUTC(c, outp);
} while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n');
STPUTC('\0', outp);
n++, inp--;
*ap++ = grabstackstr(outp);
}
#if !__minix
if (ap == newargs + 1) { /* if no args, maybe no exec is needed */
p = newargs[0];
for (;;) {
if (equal(p, "sh") || equal(p, "ash")) {
return;
}
while (*p != '/') {
if (*p == '\0')
goto break2;
p++;
}
p++;
}
break2:;
}
#endif
i = (char *)ap - (char *)newargs; /* size in bytes */
if (i == 0)
error("Bad #! line");
for (ap2 = argv ; *ap2++ != NULL ; );
new = ckmalloc(i + ((char *)ap2 - (char *)argv));
ap = newargs, ap2 = new;
while ((i -= sizeof (char **)) >= 0)
*ap2++ = *ap++;
ap = argv;
while (*ap2++ = *ap++);
shellexec(new, envp, pathval(), 0);
}
#endif
/*
* Do a path search. The variable path (passed by reference) should be
* set to the start of the path before the first call; padvance will update
@@ -271,11 +182,9 @@ break2:;
char *pathopt;
char *
padvance(path, name)
char **path;
char *name;
{
register char *p, *q;
padvance(char **path, char *name)
{
char *p, *q;
char *start;
int len;
@@ -288,7 +197,7 @@ padvance(path, name)
growstackblock();
q = stackblock();
if (p != start) {
bcopy(start, q, p - start);
memcpy(q, start, p - start);
q += p - start;
*q++ = '/';
}
@@ -310,7 +219,9 @@ padvance(path, name)
/*** Command hashing code ***/
hashcmd(argc, argv) char **argv; {
int
hashcmd(int argc __unused, char **argv __unused)
{
struct tblentry **pp;
struct tblentry *cmdp;
int c;
@@ -318,14 +229,6 @@ hashcmd(argc, argv) char **argv; {
struct cmdentry entry;
char *name;
if (argc <= 1) {
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
printentry(cmdp);
}
}
return 0;
}
verbose = 0;
while ((c = nextopt("rv")) != '\0') {
if (c == 'r') {
@@ -334,16 +237,28 @@ hashcmd(argc, argv) char **argv; {
verbose++;
}
}
if (*argptr == NULL) {
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (cmdp->cmdtype == CMDNORMAL)
printentry(cmdp, verbose);
}
}
return 0;
}
while ((name = *argptr) != NULL) {
if ((cmdp = cmdlookup(name, 0)) != NULL
&& (cmdp->cmdtype == CMDNORMAL
|| cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
delete_cmd_entry();
find_command(name, &entry, 1);
find_command(name, &entry, 1, pathval());
if (verbose) {
if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */
cmdp = cmdlookup(name, 0);
printentry(cmdp);
if (cmdp != NULL)
printentry(cmdp, verbose);
else
outfmt(&errout, "%s: not found\n", name);
}
flushall();
}
@@ -354,9 +269,8 @@ hashcmd(argc, argv) char **argv; {
STATIC void
printentry(cmdp)
struct tblentry *cmdp;
{
printentry(struct tblentry *cmdp, int verbose)
{
int index;
char *path;
char *name;
@@ -373,6 +287,14 @@ printentry(cmdp)
out1fmt("builtin %s", cmdp->cmdname);
} else if (cmdp->cmdtype == CMDFUNCTION) {
out1fmt("function %s", cmdp->cmdname);
if (verbose) {
INTOFF;
name = commandtext(cmdp->param.func);
out1c(' ');
out1str(name);
ckfree(name);
INTON;
}
#if DEBUG
} else {
error("internal error: cmdtype %d", cmdp->cmdtype);
@@ -391,14 +313,11 @@ printentry(cmdp)
*/
void
find_command(name, entry, printerr)
char *name;
struct cmdentry *entry;
{
find_command(char *name, struct cmdentry *entry, int printerr, char *path)
{
struct tblentry *cmdp;
int index;
int prev;
char *path;
char *fullname;
struct stat statb;
int e;
@@ -434,7 +353,6 @@ find_command(name, entry, printerr)
prev = cmdp->param.index;
}
path = pathval();
e = ENOENT;
index = -1;
loop:
@@ -464,17 +382,13 @@ loop:
TRACE(("searchexec \"%s\": no change\n", name));
goto success;
}
while (stat(fullname, &statb) < 0) {
#ifdef SYSV
if (errno == EINTR)
continue;
#endif
if (stat(fullname, &statb) < 0) {
if (errno != ENOENT && errno != ENOTDIR)
e = errno;
goto loop;
}
e = EACCES; /* if we fail, this will be the error */
if ((statb.st_mode & S_IFMT) != S_IFREG)
if (!S_ISREG(statb.st_mode))
goto loop;
if (pathopt) { /* this is a %func directory */
stalloc(strlen(fullname) + 1);
@@ -484,6 +398,7 @@ loop:
stunalloc(fullname);
goto success;
}
#ifdef notdef
if (statb.st_uid == geteuid()) {
if ((statb.st_mode & 0100) == 0)
goto loop;
@@ -491,23 +406,10 @@ loop:
if ((statb.st_mode & 010) == 0)
goto loop;
} else {
#if __minix_vmd || defined(BSD)
gid_t group_list[NGROUPS_MAX];
int ngroups, i;
ngroups = getgroups(NGROUPS_MAX, group_list);
for (i = 0; i < ngroups; i++) {
if (statb.st_gid == group_list[i]) break;
}
if (i < ngroups) {
if ((statb.st_mode & 010) == 0)
goto loop;
} else
#endif
if ((statb.st_mode & 01) == 0)
goto loop;
}
#endif
TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
INTOFF;
cmdp = cmdlookup(name, 1);
@@ -520,8 +422,12 @@ loop:
/* We failed. If there was an entry for this command, delete it */
if (cmdp)
delete_cmd_entry();
if (printerr)
outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
if (printerr) {
if (e == ENOENT || e == ENOTDIR)
outfmt(out2, "%s: not found\n", name);
else
outfmt(out2, "%s: %s\n", name, strerror(e));
}
entry->cmdtype = CMDUNKNOWN;
return;
@@ -538,10 +444,9 @@ success:
*/
int
find_builtin(name)
char *name;
{
const register struct builtincmd *bp;
find_builtin(char *name)
{
const struct builtincmd *bp;
for (bp = builtincmd ; bp->name ; bp++) {
if (*bp->name == *name && equal(bp->name, name))
@@ -558,14 +463,15 @@ find_builtin(name)
*/
void
hashcd() {
hashcd(void)
{
struct tblentry **pp;
struct tblentry *cmdp;
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (cmdp->cmdtype == CMDNORMAL
|| cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
cmdp->rehash = 1;
}
}
@@ -580,10 +486,9 @@ hashcd() {
*/
void
changepath(newval)
char *newval;
{
char *old, *new;
changepath(const char *newval)
{
const char *old, *new;
int index;
int firstchange;
int bltin;
@@ -596,8 +501,8 @@ changepath(newval)
for (;;) {
if (*old != *new) {
firstchange = index;
if (*old == '\0' && *new == ':'
|| *old == ':' && *new == '\0')
if ((*old == '\0' && *new == ':')
|| (*old == ':' && *new == '\0'))
firstchange++;
old = new; /* ignore subsequent differences */
}
@@ -624,8 +529,9 @@ changepath(newval)
* PATH which has changed.
*/
STATIC void
clearcmdentry(firstchange) {
void
clearcmdentry(int firstchange)
{
struct tblentry **tblp;
struct tblentry **pp;
struct tblentry *cmdp;
@@ -634,8 +540,10 @@ clearcmdentry(firstchange) {
for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
pp = tblp;
while ((cmdp = *pp) != NULL) {
if (cmdp->cmdtype == CMDNORMAL && cmdp->param.index >= firstchange
|| cmdp->cmdtype == CMDBUILTIN && builtinloc >= firstchange) {
if ((cmdp->cmdtype == CMDNORMAL &&
cmdp->param.index >= firstchange)
|| (cmdp->cmdtype == CMDBUILTIN &&
builtinloc >= firstchange)) {
*pp = cmdp->next;
ckfree(cmdp);
} else {
@@ -652,15 +560,15 @@ clearcmdentry(firstchange) {
*/
#ifdef mkinit
MKINIT void deletefuncs();
INCLUDE "exec.h"
SHELLPROC {
deletefuncs();
}
#endif
void
deletefuncs() {
deletefuncs(void)
{
struct tblentry **tblp;
struct tblentry **pp;
struct tblentry *cmdp;
@@ -691,15 +599,14 @@ deletefuncs() {
* entry.
*/
struct tblentry **lastcmdentry;
STATIC struct tblentry **lastcmdentry;
STATIC struct tblentry *
cmdlookup(name, add)
char *name;
{
cmdlookup(char *name, int add)
{
int hashval;
register char *p;
char *p;
struct tblentry *cmdp;
struct tblentry **pp;
@@ -728,13 +635,13 @@ cmdlookup(name, add)
return cmdp;
}
/*
* Delete the command entry returned on the last lookup.
*/
STATIC void
delete_cmd_entry() {
delete_cmd_entry(void)
{
struct tblentry *cmdp;
INTOFF;
@@ -746,35 +653,14 @@ delete_cmd_entry() {
#ifdef notdef
void
getcmdentry(name, entry)
char *name;
struct cmdentry *entry;
{
struct tblentry *cmdp = cmdlookup(name, 0);
if (cmdp) {
entry->u = cmdp->param;
entry->cmdtype = cmdp->cmdtype;
} else {
entry->cmdtype = CMDUNKNOWN;
entry->u.index = 0;
}
}
#endif
/*
* Add a new command entry, replacing any existing command entry for
* the same name.
*/
void
addcmdentry(name, entry)
char *name;
struct cmdentry *entry;
{
static void
addcmdentry(char *name, struct cmdentry *entry)
{
struct tblentry *cmdp;
INTOFF;
@@ -793,10 +679,8 @@ addcmdentry(name, entry)
*/
void
defun(name, func)
char *name;
union node *func;
{
defun(char *name, union node *func)
{
struct cmdentry entry;
INTOFF;
@@ -811,14 +695,98 @@ defun(name, func)
* Delete a function if it exists.
*/
void
unsetfunc(name)
char *name;
{
int
unsetfunc(char *name)
{
struct tblentry *cmdp;
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
freefunc(cmdp->param.func);
delete_cmd_entry();
return (0);
}
return (0);
}
/*
* Locate and print what a word is...
*/
int
typecmd(int argc, char **argv)
{
struct cmdentry entry;
struct tblentry *cmdp;
char **pp;
struct alias *ap;
int i;
int error = 0;
extern char *const parsekwd[];
for (i = 1; i < argc; i++) {
out1str(argv[i]);
/* First look at the keywords */
for (pp = (char **)parsekwd; *pp; pp++)
if (**pp == *argv[i] && equal(*pp, argv[i]))
break;
if (*pp) {
out1str(" is a shell keyword\n");
continue;
}
/* Then look at the aliases */
if ((ap = lookupalias(argv[i], 1)) != NULL) {
out1fmt(" is an alias for %s\n", ap->val);
continue;
}
/* Then check if it is a tracked alias */
if ((cmdp = cmdlookup(argv[i], 0)) != NULL) {
entry.cmdtype = cmdp->cmdtype;
entry.u = cmdp->param;
}
else {
/* Finally use brute force */
find_command(argv[i], &entry, 0, pathval());
}
switch (entry.cmdtype) {
case CMDNORMAL: {
if (strchr(argv[i], '/') == NULL) {
char *path = pathval(), *name;
int j = entry.u.index;
do {
name = padvance(&path, argv[i]);
stunalloc(name);
} while (--j >= 0);
out1fmt(" is%s %s\n",
cmdp ? " a tracked alias for" : "", name);
} else {
if (access(argv[i], X_OK) == 0)
out1fmt(" is %s\n", argv[i]);
else
out1fmt(": %s\n", strerror(errno));
}
break;
}
case CMDFUNCTION:
out1str(" is a shell function\n");
break;
case CMDBUILTIN:
out1str(" is a shell builtin\n");
break;
default:
out1str(": not found\n");
error |= 127;
break;
}
}
return error;
}
/*
* $PchId: exec.c,v 1.6 2006/04/10 14:47:03 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)exec.h 5.1 (Berkeley) 3/7/91
* @(#)exec.h 8.3 (Berkeley) 6/8/95
* $FreeBSD: src/bin/sh/exec.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
/* values of cmdtype */
@@ -53,23 +50,21 @@ struct cmdentry {
extern char *pathopt; /* set by padvance */
extern int exerrno; /* last exec error */
#ifdef __STDC__
void shellexec(char **, char **, char *, int);
char *padvance(char **, char *);
void find_command(char *, struct cmdentry *, int);
int hashcmd(int, char **);
void find_command(char *, struct cmdentry *, int, char *);
int find_builtin(char *);
void hashcd(void);
void changepath(char *);
void changepath(const char *);
void deletefuncs(void);
void defun(char *, union node *);
void unsetfunc(char *);
#else
void shellexec();
char *padvance();
void find_command();
int find_builtin();
void hashcd();
void changepath();
void defun();
void unsetfunc();
#endif
int unsetfunc(char *);
int typecmd(int, char **);
void clearcmdentry(int);
/*
* $PchId: exec.h,v 1.5 2006/04/10 14:47:34 philip Exp $
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)expand.h 5.1 (Berkeley) 3/7/91
* @(#)expand.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/expand.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
struct strlist {
@@ -47,17 +44,24 @@ struct arglist {
struct strlist **lastp;
};
#ifdef __STDC__
/*
* expandarg() flags
*/
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
union node;
void expandarg(union node *, struct arglist *, int);
void expandhere(union node *, int);
int patmatch(char *, char *);
void expandarg(union node *, struct arglist *, int);
int patmatch(char *, char *, int);
void rmescapes(char *);
int casematch(union node *, char *);
#else
void expandarg();
void expandhere();
int patmatch();
void rmescapes();
int casematch();
#endif
int wordexpcmd(int, char **);
/*
* $PchId: expand.h,v 1.4 2006/03/30 14:50:52 philip Exp $
*/

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)cmv 5.1 (Berkeley) 3/7/91
# @(#)cmv 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/cmv,v 1.7 2004/04/06 20:06:53 markm Exp $
# Conditional move--don't replace an existing file.
@@ -47,3 +44,6 @@ cmv() {
fi
/bin/mv "$1" "$2"
}
#
# $PchId: cmv,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)dirs 5.1 (Berkeley) 3/7/91
# @(#)dirs 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/dirs,v 1.7 2004/04/06 20:06:53 markm Exp $
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
@@ -71,3 +68,6 @@ dirs () {
echo "`pwd` $DSTACK"
return 0
}
#
# $PchId: dirs,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)kill 5.1 (Berkeley) 3/7/91
# @(#)kill 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/kill,v 1.7 2004/04/06 20:06:53 markm Exp $
# Convert job names to process ids and then run /bin/kill.
@@ -47,3 +44,6 @@ kill() {
done
/bin/kill $args
}
#
# $PchId: kill,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,11 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)login 5.1 (Berkeley) 3/7/91
# @(#)login 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/login,v 1.7 2004/04/06 20:06:53 markm Exp $
# replaces the login builtin in the BSD shell
login () exec login "$@"
#
# $PchId: login,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,6 +28,10 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)newgrp 5.1 (Berkeley) 3/7/91
# @(#)newgrp 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/newgrp,v 1.7 2004/04/06 20:06:53 markm Exp $
newgrp() exec newgrp "$@"
#
# $PchId: newgrp,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)popd 5.1 (Berkeley) 3/7/91
# @(#)popd 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/popd,v 1.7 2004/04/06 20:06:53 markm Exp $
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
@@ -71,3 +68,6 @@ dirs () {
echo "`pwd` $DSTACK"
return 0
}
#
# $PchId: popd,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)pushd 5.1 (Berkeley) 3/7/91
# @(#)pushd 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/pushd,v 1.7 2004/04/06 20:06:53 markm Exp $
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
@@ -71,3 +68,6 @@ dirs () {
echo "`pwd` $DSTACK"
return 0
}
#
# $PchId: pushd,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,10 +28,14 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)suspend 5.1 (Berkeley) 3/7/91
# @(#)suspend 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/suspend,v 1.7 2004/04/06 20:06:53 markm Exp $
suspend() {
local -
set +j
kill -TSTP 0
}
#
# $PchId: suspend,v 1.2 2006/03/29 10:43:18 philip Exp $

533
commands/ash/histedit.c Normal file
View File

@@ -0,0 +1,533 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/histedit.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include <limits.h>
#ifndef NO_PATHS_H
#include <paths.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*
* Editline and history functions (and glue).
*/
#include "shell.h"
#include "parser.h"
#include "var.h"
#include "options.h"
#include "main.h"
#include "output.h"
#include "mystring.h"
#include "builtins.h"
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#include "complete.h"
#include "error.h"
#include "eval.h"
#include "memalloc.h"
#define MAXHISTLOOPS 4 /* max recursions through fc */
#define DEFEDITOR "ed" /* default editor *should* be $EDITOR */
History *hist; /* history cookie */
EditLine *el; /* editline cookie */
int displayhist;
static FILE *el_in, *el_out, *el_err;
STATIC char *fc_replace(const char *, char *, char *);
STATIC int not_fcnumber(char *);
STATIC int str_to_event(char *, int);
/*
* Set history and editing status. Called whenever the status may
* have changed (figures out what to do).
*/
void
histedit(void)
{
#define editing (Eflag || Vflag)
if (iflag) {
if (!hist) {
/*
* turn history on
*/
INTOFF;
hist = history_init();
INTON;
if (hist != NULL)
sethistsize(histsizeval());
else
out2str("sh: can't initialize history\n");
}
if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
/*
* turn editing on
*/
INTOFF;
if (el_in == NULL)
el_in = fdopen(0, "r");
if (el_err == NULL)
el_err = fdopen(1, "w");
if (el_out == NULL)
el_out = fdopen(2, "w");
if (el_in == NULL || el_err == NULL || el_out == NULL)
goto bad;
el = el_init(arg0, el_in, el_out, el_err);
if (el != NULL) {
if (hist)
el_set(el, EL_HIST, history, hist);
el_set(el, EL_PROMPT, getprompt);
} else {
bad:
out2str("sh: can't initialize editing\n");
}
INTON;
} else if (!editing && el) {
INTOFF;
el_end(el);
el = NULL;
INTON;
}
if (el) {
if (Vflag)
el_set(el, EL_EDITOR, "vi");
else if (Eflag)
el_set(el, EL_EDITOR, "emacs");
el_set(el, EL_ADDFN, "ed-do-complete",
"Complete Argument", complete);
el_set(el, EL_ADDFN, "ed-list-complete",
"List Argument Completions", complete_list);
el_set(el, EL_ADDFN, "ed-maybe-complete",
"Complete Argument Or List Completions",
complete_or_list);
el_set(el, EL_ADDFN, "ed-expand",
"Expand Completions", complete_expand);
el_set(el, EL_BIND, "^I", "ed-maybe-complete", NULL);
el_set(el, EL_BIND, "-a", "=", "ed-list-complete",
NULL);
el_set(el, EL_BIND, "-a", "\\\\", "ed-do-complete",
NULL);
el_set(el, EL_BIND, "-a", "*", "ed-expand",
NULL);
el_source(el, NULL);
}
} else {
INTOFF;
if (el) { /* no editing if not interactive */
el_end(el);
el = NULL;
}
if (hist) {
history_end(hist);
hist = NULL;
}
INTON;
}
}
void
sethistsize(hs)
const char *hs;
{
int histsize;
HistEvent he;
if (hist != NULL) {
if (hs == NULL || *hs == '\0' ||
(histsize = atoi(hs)) < 0)
histsize = 100;
history(hist, &he, H_EVENT, histsize);
}
}
int
histcmd(int argc, char **argv)
{
int ch;
char *editor = NULL;
HistEvent he;
int lflg = 0, nflg = 0, rflg = 0, sflg = 0;
int i, retval;
char *firststr, *laststr;
int first, last, direction;
char *pat = NULL, *repl;
static int active = 0;
struct jmploc jmploc;
struct jmploc *volatile savehandler;
char editfile[PATH_MAX];
FILE *efp;
int oldhistnum;
#ifdef __GNUC__
/* Avoid longjmp clobbering */
(void) &editor;
(void) &lflg;
(void) &nflg;
(void) &rflg;
(void) &sflg;
(void) &firststr;
(void) &laststr;
(void) &pat;
(void) &repl;
(void) &efp;
(void) &argc;
(void) &argv;
#endif
if (hist == NULL)
error("history not active");
if (argc == 1)
error("missing history argument");
optreset = 1; optind = 1; /* initialize getopt */
opterr = 0;
while (not_fcnumber(argv[optind]) &&
(ch = getopt(argc, argv, ":e:lnrs")) != -1)
switch ((char)ch) {
case 'e':
editor = optarg;
break;
case 'l':
lflg = 1;
break;
case 'n':
nflg = 1;
break;
case 'r':
rflg = 1;
break;
case 's':
sflg = 1;
break;
case ':':
error("option -%c expects argument", optopt);
case '?':
default:
error("unknown option: -%c", optopt);
}
argc -= optind, argv += optind;
/*
* If executing...
*/
if (lflg == 0 || editor || sflg) {
lflg = 0; /* ignore */
editfile[0] = '\0';
/*
* Catch interrupts to reset active counter and
* cleanup temp files.
*/
if (setjmp(jmploc.loc)) {
active = 0;
if (*editfile)
unlink(editfile);
handler = savehandler;
longjmp(handler->loc, 1);
}
savehandler = handler;
handler = &jmploc;
if (++active > MAXHISTLOOPS) {
active = 0;
displayhist = 0;
error("called recursively too many times");
}
/*
* Set editor.
*/
if (sflg == 0) {
if (editor == NULL &&
(editor = bltinlookup("FCEDIT", 1)) == NULL &&
(editor = bltinlookup("EDITOR", 1)) == NULL)
editor = DEFEDITOR;
if (editor[0] == '-' && editor[1] == '\0') {
sflg = 1; /* no edit */
editor = NULL;
}
}
}
/*
* If executing, parse [old=new] now
*/
if (lflg == 0 && argc > 0 &&
((repl = strchr(argv[0], '=')) != NULL)) {
pat = argv[0];
*repl++ = '\0';
argc--, argv++;
}
/*
* determine [first] and [last]
*/
switch (argc) {
case 0:
firststr = lflg ? "-16" : "-1";
laststr = "-1";
break;
case 1:
firststr = argv[0];
laststr = lflg ? "-1" : argv[0];
break;
case 2:
firststr = argv[0];
laststr = argv[1];
break;
default:
error("too many args");
}
/*
* Turn into event numbers.
*/
first = str_to_event(firststr, 0);
last = str_to_event(laststr, 1);
if (rflg) {
i = last;
last = first;
first = i;
}
/*
* XXX - this should not depend on the event numbers
* always increasing. Add sequence numbers or offset
* to the history element in next (diskbased) release.
*/
direction = first < last ? H_PREV : H_NEXT;
/*
* If editing, grab a temp file.
*/
if (editor) {
int fd;
INTOFF; /* easier */
sprintf(editfile, "%s/_shXXXXXX", _PATH_TMP);
if ((fd = mkstemp(editfile)) < 0)
error("can't create temporary file %s", editfile);
if ((efp = fdopen(fd, "w")) == NULL) {
close(fd);
error("can't allocate stdio buffer for temp");
}
}
/*
* Loop through selected history events. If listing or executing,
* do it now. Otherwise, put into temp file and call the editor
* after.
*
* The history interface needs rethinking, as the following
* convolutions will demonstrate.
*/
history(hist, &he, H_FIRST);
retval = history(hist, &he, H_NEXT_EVENT, first);
for (;retval != -1; retval = history(hist, &he, direction)) {
if (lflg) {
if (!nflg)
out1fmt("%5d ", he.num);
out1str(he.str);
} else {
char *s = pat ?
fc_replace(he.str, pat, repl) : (char *)he.str;
if (sflg) {
if (displayhist) {
out2str(s);
}
evalstring(s);
if (displayhist && hist) {
/*
* XXX what about recursive and
* relative histnums.
*/
oldhistnum = he.num;
history(hist, &he, H_ENTER, s);
/*
* XXX H_ENTER moves the internal
* cursor, set it back to the current
* entry.
*/
retval = history(hist, &he,
H_NEXT_EVENT, oldhistnum);
}
} else
fputs(s, efp);
}
/*
* At end? (if we were to loose last, we'd sure be
* messed up).
*/
if (he.num == last)
break;
}
if (editor) {
char *editcmd;
fclose(efp);
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
sprintf(editcmd, "%s %s", editor, editfile);
evalstring(editcmd); /* XXX - should use no JC command */
INTON;
readcmdfile(editfile); /* XXX - should read back - quick tst */
unlink(editfile);
}
if (lflg == 0 && active > 0)
--active;
if (displayhist)
displayhist = 0;
return 0;
}
STATIC char *
fc_replace(const char *s, char *p, char *r)
{
char *dest;
int plen = strlen(p);
STARTSTACKSTR(dest);
while (*s) {
if (*s == *p && strncmp(s, p, plen) == 0) {
while (*r)
STPUTC(*r++, dest);
s += plen;
*p = '\0'; /* so no more matches */
} else
STPUTC(*s++, dest);
}
STACKSTRNUL(dest);
dest = grabstackstr(dest);
return (dest);
}
STATIC int
not_fcnumber(char *s)
{
if (s == NULL)
return (0);
if (*s == '-')
s++;
return (!is_number(s));
}
STATIC int
str_to_event(char *str, int last)
{
HistEvent he;
char *s = str;
int relative = 0;
int i, retval;
retval = history(hist, &he, H_FIRST);
switch (*s) {
case '-':
relative = 1;
/*FALLTHROUGH*/
case '+':
s++;
}
if (is_number(s)) {
i = atoi(s);
if (relative) {
while (retval != -1 && i--) {
retval = history(hist, &he, H_NEXT);
}
if (retval == -1)
retval = history(hist, &he, H_LAST);
} else {
retval = history(hist, &he, H_NEXT_EVENT, i);
if (retval == -1) {
/*
* the notion of first and last is
* backwards to that of the history package
*/
retval = history(hist, &he, last ? H_FIRST : H_LAST);
}
}
if (retval == -1)
error("history number %s not found (internal error)",
str);
} else {
/*
* pattern
*/
retval = history(hist, &he, H_PREV_STR, str);
if (retval == -1)
error("history pattern not found: %s", str);
}
return (he.num);
}
int
bindcmd(int argc, char **argv)
{
if (el == NULL)
error("line editing is disabled");
return (el_parse(el, argc, argv));
}
#else
#include "error.h"
int
histcmd(int argc, char **argv)
{
error("not compiled with history support");
/*NOTREACHED*/
return (0);
}
int
bindcmd(int argc, char **argv)
{
error("not compiled with line editing support");
return (0);
}
#endif /* !NO_HISTORY && !EDITLINE */
/*
* $PchId: histedit.c,v 1.6 2006/04/10 14:52:58 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,15 +29,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)init.h 5.1 (Berkeley) 3/7/91
* @(#)init.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/init.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#ifdef __STDC__
void init(void);
void reset(void);
void initshellproc(void);
#else
void init();
void reset();
void initshellproc();
#endif
/*
* $PchId: init.h,v 1.3 2006/03/30 14:31:06 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,26 +31,62 @@
*/
#ifndef lint
static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 7/1/91";
#if 0
static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/input.c,v 1.22 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <stdio.h> /* defines BUFSIZ */
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*
* This file implements the input routines used by the parser.
*/
#include <sys/types.h>
#include <stdio.h> /* defines BUFSIZ */
#include "shell.h"
#include <fcntl.h>
#include <errno.h>
#include "redir.h"
#include "syntax.h"
#include "input.h"
#include "output.h"
#include "options.h"
#include "memalloc.h"
#include "error.h"
#include "alias.h"
#include "parser.h"
#ifdef EDITLINE
#ifdef __minix_vmd
#include <readline/readline.h>
#else
/* What about other systems? */
char *readline(char *prompt);
#endif
#else
#include "myhistedit.h"
#endif
#include "redir.h"
#include "trap.h"
static void popstring(void);
#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
MKINIT
struct strpush {
struct strpush *prev; /* preceding string on stack */
char *prevstring;
int prevnleft;
int prevlleft;
struct alias *ap; /* if push was associated with an alias */
};
/*
* The parsefile structure pointed to by the global variable parsefile
@@ -63,36 +95,34 @@ static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 7/1/91";
MKINIT
struct parsefile {
struct parsefile *prev; /* preceding file on stack */
int linno; /* current line */
int fd; /* file descriptor (or -1 if string) */
int nleft; /* number of chars left in buffer */
int nleft; /* number of chars left in this line */
int lleft; /* number of lines left in this buffer */
char *nextc; /* next char in buffer */
struct parsefile *prev; /* preceding file on stack */
char *buf; /* input buffer */
struct strpush *strpush; /* for pushing strings at this level */
struct strpush basestrpush; /* so pushing one is fast */
};
int plinno = 1; /* input line number */
MKINIT int parsenleft; /* copy of parsefile->nleft */
MKINIT int parselleft; /* copy of parsefile->lleft */
char *parsenextc; /* copy of parsefile->nextc */
MKINIT struct parsefile basepf; /* top level input file */
char basebuf[BUFSIZ]; /* buffer for top level input file */
struct parsefile *parsefile = &basepf; /* current input file */
char *pushedstring; /* copy of parsenextc when text pushed back */
int pushednleft; /* copy of parsenleft when text pushed back */
STATIC struct parsefile *parsefile = &basepf; /* current input file */
int init_editline = 0; /* editline library initialized? */
int whichprompt; /* -1 == PSE, 1 == PS1, 2 == PS2 */
#if READLINE
char *readline __P((const char *prompt));
char *r_use_prompt = NULL; /* the prompt to use with readline */
#ifndef EDITLINE
EditLine *el; /* cookie for editline package */
#endif
#ifdef __STDC__
STATIC void pushfile(void);
#else
STATIC void pushfile();
#endif
static int preadfd(void);
#ifdef mkinit
INCLUDE "input.h"
@@ -106,7 +136,7 @@ INIT {
RESET {
if (exception != EXSHELLPROC)
parsenleft = 0; /* clear input buffer */
parselleft = parsenleft = 0; /* clear input buffer */
popallfiles();
}
@@ -121,10 +151,9 @@ SHELLPROC {
*/
char *
pfgets(line, len)
char *line;
{
register char *p = line;
pfgets(char *line, int len)
{
char *p = line;
int nleft = len;
int c;
@@ -151,64 +180,74 @@ pfgets(line, len)
*/
int
pgetc() {
pgetc(void)
{
return pgetc_macro();
}
/*
* Refill the input buffer and return the next input character:
*
* 1) If a string was pushed back on the input, switch back to the regular
* buffer.
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
* from a string so we can't refill the buffer, return EOF.
* 3) Call read to read in the characters.
* 4) Delete all nul characters from the buffer.
*/
static int
preadfd(void)
{
int nr;
parsenextc = parsefile->buf;
int
preadbuffer() {
register char *p, *q;
register int i;
if (pushedstring) {
parsenextc = pushedstring;
pushedstring = NULL;
parsenleft = pushednleft;
if (--parsenleft >= 0)
return *parsenextc++;
#if !defined(NO_HISTORY) && !defined(EDITLINE)
if (el != NULL && gotwinch) {
gotwinch = 0;
el_resize(el);
}
if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
return PEOF;
flushout(&output);
flushout(&errout);
#if READLINE
/* Use the readline() call if a prompt is to be printed (interactive). */
if (r_use_prompt != NULL) {
char *prompt;
char *line;
p = parsenextc = parsefile->buf;
prompt = r_use_prompt;
r_use_prompt = NULL;
if ((line = readline(prompt)) == NULL) {
parsenleft = EOF_NLEFT;
return PEOF;
}
strcpy(p, line);
free(line);
i = strlen(p);
p[i++] = '\n';
} else {
#endif
retry:
p = parsenextc = parsefile->buf;
i = read(parsefile->fd, p, BUFSIZ);
if (i <= 0) {
if (i < 0) {
#ifndef NO_HISTORY
#ifdef EDITLINE
if (parsefile->fd == 0 && editable) {
static const char *rl_cp= NULL;
static size_t rl_off= 0;
if (!rl_cp)
{
rl_cp = readline(getprompt(NULL));
if (rl_cp == NULL)
nr = 0;
}
if (rl_cp)
{
nr= strlen(rl_cp+rl_off);
if (nr >= BUFSIZ-1)
{
nr= BUFSIZ-1;
(void) memcpy(parsenextc, rl_cp+rl_off, nr);
rl_off += nr;
}
else
{
(void) memcpy(parsenextc, rl_cp+rl_off, nr);
parsenextc[nr++]= '\n';
free(rl_cp);
rl_cp= NULL;
rl_off= 0;
}
}
} else
#else /* !EDITLINE */
if (parsefile->fd == 0 && el) {
const char *rl_cp;
rl_cp = el_gets(el, &nr);
if (rl_cp == NULL)
nr = 0;
else {
/* XXX - BUFSIZE should redesign so not necessary */
(void) strcpy(parsenextc, rl_cp);
}
} else
#endif /* !EDITLINE */
#endif
nr = read(parsefile->fd, parsenextc, BUFSIZ - 1);
if (nr <= 0) {
if (nr < 0) {
if (errno == EINTR)
goto retry;
#ifdef EWOULDBLOCK
@@ -222,35 +261,106 @@ retry:
}
}
}
#endif
#endif /* EWOULDBLOCK */
}
parsenleft = EOF_NLEFT;
return PEOF;
nr = -1;
}
#if READLINE
}
#endif
parsenleft = i - 1;
/* delete nul characters */
for (;;) {
if (*p++ == '\0')
break;
if (--i <= 0)
return *parsenextc++; /* no nul characters */
}
q = p - 1;
while (--i > 0) {
if (*p != '\0')
*q++ = *p;
p++;
}
if (q == parsefile->buf)
goto retry; /* buffer contained nothing but nuls */
parsenleft = q - parsefile->buf - 1;
return *parsenextc++;
return nr;
}
/*
* Refill the input buffer and return the next input character:
*
* 1) If a string was pushed back on the input, pop it;
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
* from a string so we can't refill the buffer, return EOF.
* 3) If there is more in this buffer, use it else call read to fill it.
* 4) Process input up to the next newline, deleting nul characters.
*/
int
preadbuffer(void)
{
char *p, *q;
int more;
int something;
char savec;
if (parsefile->strpush) {
popstring();
if (--parsenleft >= 0)
return (*parsenextc++);
}
if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
return PEOF;
flushout(&output);
flushout(&errout);
again:
if (parselleft <= 0) {
if ((parselleft = preadfd()) == -1) {
parselleft = parsenleft = EOF_NLEFT;
return PEOF;
}
}
q = p = parsenextc;
/* delete nul characters */
something = 0;
for (more = 1; more;) {
switch (*p) {
case '\0':
p++; /* Skip nul */
goto check;
case '\t':
case ' ':
break;
case '\n':
parsenleft = q - parsenextc;
more = 0; /* Stop processing here */
break;
default:
something = 1;
break;
}
*q++ = *p++;
check:
if (--parselleft <= 0) {
parsenleft = q - parsenextc - 1;
if (parsenleft < 0)
goto again;
*q = '\0';
more = 0;
}
}
savec = *q;
*q = '\0';
#if !defined(NO_HISTORY) && !defined(EDITLINE)
if (parsefile->fd == 0 && hist && something) {
HistEvent he;
INTOFF;
history(hist, &he, whichprompt == 1 ? H_ENTER : H_ADD,
parsenextc);
INTON;
}
#endif
if (vflag) {
out2str(parsenextc);
flushout(out2);
}
*q = savec;
return *parsenextc++;
}
/*
* Undo the last call to pgetc. Only one character may be pushed back.
@@ -258,28 +368,57 @@ retry:
*/
void
pungetc() {
pungetc(void)
{
parsenleft++;
parsenextc--;
}
/*
* Push a string back onto the input. This code doesn't work if the user
* tries to push back more than one string at once.
* Push a string back onto the input at this current parsefile level.
* We handle aliases this way.
*/
void
ppushback(string, length)
char *string;
{
pushedstring = parsenextc;
pushednleft = parsenleft;
parsenextc = string;
parsenleft = length;
pushstring(char *s, int len, void *ap)
{
struct strpush *sp;
INTOFF;
/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
if (parsefile->strpush) {
sp = ckmalloc(sizeof (struct strpush));
sp->prev = parsefile->strpush;
parsefile->strpush = sp;
} else
sp = parsefile->strpush = &(parsefile->basestrpush);
sp->prevstring = parsenextc;
sp->prevnleft = parsenleft;
sp->prevlleft = parselleft;
sp->ap = (struct alias *)ap;
if (ap)
((struct alias *)ap)->flag |= ALIASINUSE;
parsenextc = s;
parsenleft = len;
INTON;
}
static void
popstring(void)
{
struct strpush *sp = parsefile->strpush;
INTOFF;
parsenextc = sp->prevstring;
parsenleft = sp->prevnleft;
parselleft = sp->prevlleft;
/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
if (sp->ap)
sp->ap->flag &= ~ALIASINUSE;
parsefile->strpush = sp->prev;
if (sp != &(parsefile->basestrpush))
ckfree(sp);
INTON;
}
/*
* Set the input to take input from a file. If push is set, push the
@@ -287,17 +426,16 @@ ppushback(string, length)
*/
void
setinputfile(fname, push)
char *fname;
{
setinputfile(char *fname, int push)
{
int fd;
int fd2;
INTOFF;
if ((fd = open(fname, O_RDONLY)) < 0)
error("Can't open %s", fname);
error("Can't open %s: %s", fname, strerror(errno));
if (fd < 10) {
fd2 = copyfd(fd, 10);
fd2 = fcntl(fd, F_DUPFD, 10);
close(fd);
if (fd2 < 0)
error("Out of file descriptors");
@@ -314,8 +452,9 @@ setinputfile(fname, push)
*/
void
setinputfd(fd, push) {
(void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
setinputfd(int fd, int push)
{
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
if (push) {
pushfile();
parsefile->buf = ckmalloc(BUFSIZ);
@@ -325,7 +464,7 @@ setinputfd(fd, push) {
parsefile->fd = fd;
if (parsefile->buf == NULL)
parsefile->buf = ckmalloc(BUFSIZ);
parsenleft = 0;
parselleft = parsenleft = 0;
plinno = 1;
}
@@ -335,14 +474,13 @@ setinputfd(fd, push) {
*/
void
setinputstring(string, push)
char *string;
{
setinputstring(char *string, int push)
{
INTOFF;
if (push)
pushfile();
parsenextc = string;
parsenleft = strlen(string);
parselleft = parsenleft = strlen(string);
parsefile->buf = NULL;
plinno = 1;
INTON;
@@ -356,21 +494,26 @@ setinputstring(string, push)
*/
STATIC void
pushfile() {
pushfile(void)
{
struct parsefile *pf;
parsefile->nleft = parsenleft;
parsefile->lleft = parselleft;
parsefile->nextc = parsenextc;
parsefile->linno = plinno;
pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
pf->prev = parsefile;
pf->fd = -1;
pf->strpush = NULL;
pf->basestrpush.prev = NULL;
parsefile = pf;
}
void
popfile() {
popfile(void)
{
struct parsefile *pf = parsefile;
INTOFF;
@@ -378,9 +521,12 @@ popfile() {
close(pf->fd);
if (pf->buf)
ckfree(pf->buf);
while (pf->strpush)
popstring();
parsefile = pf->prev;
ckfree(pf);
parsenleft = parsefile->nleft;
parselleft = parsefile->lleft;
parsenextc = parsefile->nextc;
plinno = parsefile->linno;
INTON;
@@ -392,7 +538,8 @@ popfile() {
*/
void
popallfiles() {
popallfiles(void)
{
while (parsefile != &basepf)
popfile();
}
@@ -405,10 +552,15 @@ popallfiles() {
*/
void
closescript() {
closescript(void)
{
popallfiles();
if (parsefile->fd > 0) {
close(parsefile->fd);
parsefile->fd = 0;
}
}
/*
* $PchId: input.c,v 1.7 2006/05/29 13:09:38 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)input.h 5.1 (Berkeley) 3/7/91
* @(#)input.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/input.h,v 1.9 2004/04/06 20:06:51 markm Exp $
*/
/* PEOF (the end of file marker) is defined in syntax.h */
@@ -46,39 +43,22 @@
extern int plinno;
extern int parsenleft; /* number of characters left in input buffer */
extern char *parsenextc; /* next character in input buffer */
extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */
#ifdef __STDC__
char *pfgets(char *, int);
int pgetc(void);
int preadbuffer(void);
void pungetc(void);
void ppushback(char *, int);
void pushstring(char *, int, void *);
void setinputfile(char *, int);
void setinputfd(int, int);
void setinputstring(char *, int);
void popfile(void);
void popallfiles(void);
void closescript(void);
#else
char *pfgets();
int pgetc();
int preadbuffer();
void pungetc();
void ppushback();
void setinputfile();
void setinputfd();
void setinputstring();
void popfile();
void popallfiles();
void closescript();
#endif
#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
#if READLINE
/* The variable "r_use_prompt" indicates the prompt to use with readline,
* *and* that readline may only be used if non-NULL.
/*
* $PchId: input.h,v 1.3 2006/03/30 13:49:37 philip Exp $
*/
extern char *r_use_prompt;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)jobs.h 5.1 (Berkeley) 3/7/91
* @(#)jobs.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/jobs.h,v 1.18 2004/04/06 20:06:51 markm Exp $
*/
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
@@ -41,6 +38,7 @@
#define FORK_BG 1
#define FORK_NOJOB 2
#include <signal.h> /* for sig_atomic_t */
/*
* A job structure contains information about a job. A job is either a
@@ -51,7 +49,7 @@
struct procstat {
pid_t pid; /* process id */
short status; /* status flags (defined above) */
int status; /* status flags (defined above) */
char *cmd; /* text of command being run */
};
@@ -64,33 +62,41 @@ struct procstat {
struct job {
struct procstat ps0; /* status of process */
struct procstat *ps; /* status or processes when more than one */
pid_t nprocs; /* number of processes */
short nprocs; /* number of processes */
pid_t pgrp; /* process group of this job */
char state; /* true if job is finished */
char used; /* true if this entry is in used */
char changed; /* true if status has changed */
char foreground; /* true if running in the foreground */
#if JOBS
char jobctl; /* job running under job control */
struct job *next; /* job used after this one */
#endif
};
extern pid_t backgndpid; /* pid of last background process */
extern int job_warning; /* user was warned about stopped jobs */
extern int in_waitcmd; /* are we in waitcmd()? */
extern int in_dowait; /* are we in dowait()? */
extern volatile sig_atomic_t breakwaitcmd; /* break wait to process traps? */
#ifdef __STDC__
void setjobctl(int);
void showjobs(int);
int fgcmd(int, char **);
int bgcmd(int, char **);
int jobscmd(int, char **);
void showjobs(int, int, int);
int waitcmd(int, char **);
int jobidcmd(int, char **);
struct job *makejob(union node *, int);
int forkshell(struct job *, union node *, int);
int waitforjob(struct job *);
#else
void setjobctl();
void showjobs();
struct job *makejob();
int forkshell();
int waitforjob();
#endif
pid_t forkshell(struct job *, union node *, int);
int waitforjob(struct job *, int *);
int stoppedjobs(void);
char *commandtext(union node *);
#if ! JOBS
#define setjobctl(on) /* do nothing */
#endif
/*
* $PchId: jobs.h,v 1.4 2006/03/30 12:07:24 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)machdep.h 5.1 (Berkeley) 3/7/91
* @(#)machdep.h 8.2 (Berkeley) 5/4/95
*/
/*
@@ -47,5 +47,9 @@ union align {
char *cp;
};
#define ALIGN(nbytes) ((nbytes) + sizeof(union align) - 1 &~ (sizeof(union align) - 1))
#define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
#endif
/*
* $PchId: machdep.h,v 1.2 2001/05/15 16:36:26 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,14 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mail.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/mail.c,v 1.13 2004/04/06 20:06:51 markm Exp $");
*/
/*
* Routines to check for mail. (Perhaps make part of main.c?)
@@ -48,8 +50,10 @@ static char sccsid[] = "@(#)mail.c 5.1 (Berkeley) 3/7/91";
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "mail.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#define MAXMBOXES 10
@@ -67,11 +71,12 @@ STATIC time_t mailtime[MAXMBOXES]; /* times of mailboxes */
*/
void
chkmail(silent) {
register int i;
chkmail(int silent)
{
int i;
char *mpath;
char *p;
register char *q;
char *q;
struct stackmark smark;
struct stat statb;
@@ -91,18 +96,28 @@ chkmail(silent) {
if (q[-1] != '/')
abort();
q[-1] = '\0'; /* delete trailing '/' */
#ifdef notdef /* this is what the System V shell claims to do (it lies) */
if (stat(p, &statb) < 0)
statb.st_mtime = 0;
if (!silent
&& statb.st_size > 0
&& statb.st_mtime > mailtime[i]
&& statb.st_mtime > statb.st_atime
) {
out2str(pathopt? pathopt : "You have mail");
if (statb.st_mtime > mailtime[i] && ! silent) {
out2str(pathopt? pathopt : "you have mail");
out2c('\n');
}
mailtime[i] = statb.st_mtime;
#else /* this is what it should do */
if (stat(p, &statb) < 0)
statb.st_size = 0;
if (statb.st_size > mailtime[i] && ! silent) {
out2str(pathopt? pathopt : "you have mail");
out2c('\n');
}
mailtime[i] = statb.st_size;
#endif
}
nmboxes = i;
popstackmark(&smark);
}
/*
* $PchId: mail.c,v 1.5 2006/05/22 12:02:37 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,11 +29,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mail.h 5.1 (Berkeley) 3/7/91
* @(#)mail.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/mail.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#ifdef __STDC__
void chkmail(int);
#else
void chkmail();
#endif
/*
* $PchId: mail.h,v 1.3 2006/03/30 11:53:44 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,18 +31,29 @@
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/28/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/main.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <locale.h>
#include <errno.h>
#include "shell.h"
#include "main.h"
#include "mail.h"
@@ -54,38 +61,26 @@ static char sccsid[] = "@(#)main.c 5.2 (Berkeley) 3/13/91";
#include "output.h"
#include "parser.h"
#include "nodes.h"
#include "expand.h"
#include "eval.h"
#include "jobs.h"
#include "input.h"
#include "trap.h"
#if ATTY
#include "var.h"
#endif
#include "show.h"
#include "memalloc.h"
#include "error.h"
#include "init.h"
#include "mystring.h"
#define PROFILE 0
#include "exec.h"
#include "cd.h"
#include "builtins.h"
int rootpid;
int rootshell;
STATIC union node *curcmd;
STATIC union node *prevcmd;
extern int errno;
#if PROFILE
short profile_buf[16384];
extern int etext();
#endif
#ifdef __STDC__
STATIC void read_profile(char *);
char *getenv(char *);
#else
STATIC void read_profile();
char *getenv();
#endif
STATIC char *find_dot_file(char *);
/*
* Main routine. We initialize things, parse the arguments, execute
@@ -95,16 +90,15 @@ char *getenv();
* is used to figure out how far we had gotten.
*/
main(argc, argv) char **argv; {
int
main(int argc, char *argv[])
{
struct jmploc jmploc;
struct stackmark smark;
volatile int state;
char *shinit, *home;
char *profile = NULL, *ashrc = NULL;
char *shinit;
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
(void) setlocale(LC_ALL, "");
state = 0;
if (setjmp(jmploc.loc)) {
/*
@@ -112,20 +106,32 @@ main(argc, argv) char **argv; {
* exception EXSHELLPROC to clean up before executing
* the shell procedure.
*/
if (exception == EXSHELLPROC) {
switch (exception) {
case EXSHELLPROC:
rootpid = getpid();
rootshell = 1;
minusc = NULL;
state = 3;
} else if (state == 0 || iflag == 0 || ! rootshell)
exitshell(2);
break;
case EXEXEC:
exitstatus = exerrno;
break;
case EXERROR:
exitstatus = 2;
break;
default:
break;
}
if (exception != EXSHELLPROC) {
if (state == 0 || iflag == 0 || ! rootshell)
exitshell(exitstatus);
}
reset();
#if ATTY
if (exception == EXINT
&& (! attyset() || equal(termval(), "emacs"))) {
#else
if (exception == EXINT) {
#endif
out2c('\n');
flushout(&errout);
}
@@ -150,57 +156,38 @@ main(argc, argv) char **argv; {
init();
setstackmark(&smark);
procargs(argc, argv);
if (eflag) eflag = 2; /* Truly enable [ex]flag after init. */
if (xflag) xflag = 2;
if (getpwd() == NULL && iflag)
out2str("sh: cannot determine working directory\n");
if (argv[0] && argv[0][0] == '-') {
state = 1;
read_profile("/etc/profile");
state1:
state = 2;
if ((home = getenv("HOME")) != NULL
&& (profile = (char *) malloc(strlen(home) + 10)) != NULL)
{
strcpy(profile, home);
strcat(profile, "/.profile");
read_profile(profile);
} else {
if (privileged == 0)
read_profile(".profile");
}
} else if ((sflag || minusc) && (shinit = getenv("SHINIT")) != NULL) {
state = 2;
evalstring(shinit);
else
read_profile("/etc/suid_profile");
}
state2:
if (profile != NULL) free(profile);
state = 3;
if (!argv[0] || argv[0][0] != '-') {
if ((home = getenv("HOME")) != NULL
&& (ashrc = (char *) malloc(strlen(home) + 8)) != NULL)
{
strcpy(ashrc, home);
strcat(ashrc, "/.ashrc");
read_profile(ashrc);
if (!privileged && iflag) {
if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
state = 3;
read_profile(shinit);
}
}
state3:
if (ashrc != NULL) free(ashrc);
if (eflag) eflag = 1; /* Init done, enable [ex]flag */
if (xflag) xflag = 1;
exitstatus = 0; /* Init shouldn't influence initial $? */
state = 4;
if (minusc) {
evalstring(minusc);
}
if (sflag || minusc == NULL) {
state4:
state4: /* XXX ??? - why isn't this before the "if" statement */
cmdloop(1);
}
#if PROFILE
monitor(0);
#endif
exitshell(exitstatus);
/*NOTREACHED*/
return 0;
}
@@ -210,52 +197,49 @@ state4:
*/
void
cmdloop(top) {
cmdloop(int top)
{
union node *n;
struct stackmark smark;
int inter;
int numeof;
int numeof = 0;
TRACE(("cmdloop(%d) called\n", top));
setstackmark(&smark);
numeof = 0;
for (;;) {
if (pendingsigs)
dotrap();
inter = 0;
if (iflag && top) {
inter++;
showjobs(1);
showjobs(1, 0, 0);
chkmail(0);
flushout(&output);
}
n = parsecmd(inter);
#if DEBUG
/* showtree(n); */
#endif
/* showtree(n); DEBUG */
if (n == NEOF) {
if (Iflag == 0 || numeof >= 50)
if (!top || numeof >= 50)
break;
out2str("\nUse \"exit\" to leave shell.\n");
if (!stoppedjobs()) {
if (!Iflag)
break;
out2str("\nUse \"exit\" to leave shell.\n");
}
numeof++;
} else if (n != NULL && nflag == 0) {
if (inter) {
INTOFF;
if (prevcmd)
freefunc(prevcmd);
prevcmd = curcmd;
curcmd = copyfunc(n);
INTON;
}
job_warning = (job_warning == 2) ? 1 : 0;
numeof = 0;
evaltree(n, 0);
#ifdef notdef
if (exitstatus) /*DEBUG*/
outfmt(&errout, "Exit status 0x%X\n", exitstatus);
#endif
}
popstackmark(&smark);
setstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
break;
}
}
popstackmark(&smark); /* unnecessary */
popstackmark(&smark);
}
@@ -265,9 +249,8 @@ cmdloop(top) {
*/
STATIC void
read_profile(name)
char *name;
{
read_profile(char *name)
{
int fd;
INTOFF;
@@ -287,32 +270,63 @@ read_profile(name)
*/
void
readcmdfile(name)
char *name;
{
readcmdfile(char *name)
{
int fd;
INTOFF;
if ((fd = open(name, O_RDONLY)) >= 0)
setinputfd(fd, 1);
else
error("Can't open %s", name);
error("Can't open %s: %s", name, strerror(errno));
INTON;
cmdloop(0);
popfile();
}
/*
* Take commands from a file. To be compatable we should do a path
* search for the file, but a path search doesn't make any sense.
* Take commands from a file. To be compatible we should do a path
* search for the file, which is necessary to find sub-commands.
*/
dotcmd(argc, argv) char **argv; {
STATIC char *
find_dot_file(char *basename)
{
static char localname[FILENAME_MAX+1];
char *fullname;
char *path = pathval();
struct stat statb;
/* don't try this for absolute or relative paths */
if( strchr(basename, '/'))
return basename;
while ((fullname = padvance(&path, basename)) != NULL) {
strcpy(localname, fullname);
stunalloc(fullname);
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode))
return localname;
}
return basename;
}
int
dotcmd(int argc, char **argv)
{
struct strlist *sp;
exitstatus = 0;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
if (argc >= 2) { /* That's what SVR2 does */
setinputfile(argv[1], 1);
commandname = argv[1];
char *fullname = find_dot_file(argv[1]);
setinputfile(fullname, 1);
commandname = fullname;
cmdloop(0);
popfile();
}
@@ -320,40 +334,22 @@ dotcmd(argc, argv) char **argv; {
}
exitcmd(argc, argv) char **argv; {
int
exitcmd(int argc, char **argv)
{
extern int oexitstatus;
if (stoppedjobs())
return 0;
if (argc > 1)
exitstatus = number(argv[1]);
else
exitstatus = oexitstatus;
exitshell(exitstatus);
/*NOTREACHED*/
return 0;
}
lccmd(argc, argv) char **argv; {
if (argc > 1) {
defun(argv[1], prevcmd);
return 0;
} else {
INTOFF;
freefunc(curcmd);
curcmd = prevcmd;
prevcmd = NULL;
INTON;
evaltree(curcmd, 0);
return exitstatus;
}
}
#ifdef notdef
/*
* Should never be called.
* $PchId: main.c,v 1.5 2006/05/22 12:03:02 philip Exp $
*/
void
exit(exitstatus) {
_exit(exitstatus);
}
#endif

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,16 +29,18 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)main.h 5.1 (Berkeley) 3/7/91
* @(#)main.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/main.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
extern int rootpid; /* pid of main shell */
extern int rootshell; /* true if we aren't a child of the main shell */
#ifdef __STDC__
void readcmdfile(char *);
void cmdloop(int);
#else
void readcmdfile();
void cmdloop();
#endif
int dotcmd(int, char **);
int exitcmd(int, char **);
/*
* $PchId: main.h,v 1.3 2006/03/30 11:43:59 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,24 +31,33 @@
*/
#ifndef lint
static char sccsid[] = "@(#)memalloc.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/memalloc.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include "shell.h"
#include "output.h"
#include "machdep.h"
#include "memalloc.h"
#include "error.h"
#include "machdep.h"
#include "mystring.h"
#include "expand.h"
#include <stdlib.h>
#include <unistd.h>
/*
* Like malloc, but returns an error when out of space.
*/
pointer
ckmalloc(nbytes) {
register pointer p;
pointer malloc();
ckmalloc(int nbytes)
{
pointer p;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
@@ -65,11 +70,8 @@ ckmalloc(nbytes) {
*/
pointer
ckrealloc(p, nbytes)
register pointer p;
{
pointer realloc();
ckrealloc(pointer p, int nbytes)
{
if ((p = realloc(p, nbytes)) == NULL)
error("Out of space");
return p;
@@ -81,10 +83,9 @@ ckrealloc(p, nbytes)
*/
char *
savestr(s)
char *s;
{
register char *p;
savestr(char *s)
{
char *p;
p = ckmalloc(strlen(s) + 1);
scopy(s, p);
@@ -97,47 +98,56 @@ savestr(s)
* to make this more efficient, and also to avoid all sorts of exception
* handling code to handle interrupts in the middle of a parse.
*
* The size 504 was chosen because the Ultrix malloc handles that size
* well.
* The size 496 was chosen because with 16-byte alignment the total size
* for the allocated block is 512.
*/
#define MINSIZE 504 /* minimum size of a block */
#define MINSIZE 496 /* minimum size of a block. */
struct stack_block {
struct stack_block *prev;
char space[MINSIZE];
/* Data follows */
};
#define SPACE(sp) ((char*)(sp) + ALIGN(sizeof(struct stack_block)))
struct stack_block stackbase;
struct stack_block *stackp = &stackbase;
char *stacknxt = stackbase.space;
int stacknleft = MINSIZE;
STATIC struct stack_block *stackp;
STATIC struct stackmark *markp;
char *stacknxt;
int stacknleft;
int sstrnleft;
int herefd = -1;
static void
stnewblock(int nbytes)
{
struct stack_block *sp;
int allocsize;
if (nbytes < MINSIZE)
nbytes = MINSIZE;
allocsize = ALIGN(sizeof(struct stack_block)) + ALIGN(nbytes);
INTOFF;
sp = ckmalloc(allocsize);
sp->prev = stackp;
stacknxt = SPACE(sp);
stacknleft = allocsize - (stacknxt - (char*)sp);
stackp = sp;
INTON;
}
pointer
stalloc(nbytes) {
register char *p;
stalloc(int nbytes)
{
char *p;
nbytes = ALIGN(nbytes);
if (nbytes > stacknleft) {
int blocksize;
struct stack_block *sp;
blocksize = nbytes;
if (blocksize < MINSIZE)
blocksize = MINSIZE;
INTOFF;
sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
sp->prev = stackp;
stacknxt = sp->space;
stacknleft = blocksize;
stackp = sp;
INTON;
}
if (nbytes > stacknleft)
stnewblock(nbytes);
p = stacknxt;
stacknxt += nbytes;
stacknleft -= nbytes;
@@ -146,11 +156,10 @@ stalloc(nbytes) {
void
stunalloc(p)
pointer p;
{
stunalloc(pointer p)
{
if (p == NULL) { /*DEBUG */
write(2, "stunalloc\n", 10);
write(STDERR_FILENO, "stunalloc\n", 10);
abort();
}
stacknleft += stacknxt - (char *)p;
@@ -160,22 +169,23 @@ stunalloc(p)
void
setstackmark(mark)
struct stackmark *mark;
{
setstackmark(struct stackmark *mark)
{
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
mark->marknext = markp;
markp = mark;
}
void
popstackmark(mark)
struct stackmark *mark;
{
popstackmark(struct stackmark *mark)
{
struct stack_block *sp;
INTOFF;
markp = mark->marknext;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
@@ -198,35 +208,56 @@ popstackmark(mark)
*/
void
growstackblock() {
growstackblock(void)
{
char *p;
int newlen = stacknleft * 2 + 100;
char *oldspace = stacknxt;
int oldlen = stacknleft;
int newlen;
char *oldspace;
int oldlen;
struct stack_block *sp;
struct stack_block *oldstackp;
struct stackmark *xmark;
if (stacknxt == stackp->space && stackp != &stackbase) {
newlen = (stacknleft == 0) ? MINSIZE : stacknleft * 2 + 100;
newlen = ALIGN(newlen);
oldspace = stacknxt;
oldlen = stacknleft;
if (stackp != NULL && stacknxt == SPACE(stackp)) {
INTOFF;
sp = stackp;
stackp = sp->prev;
sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
oldstackp = stackp;
stackp = oldstackp->prev;
sp = ckrealloc((pointer)oldstackp, newlen);
sp->prev = stackp;
stackp = sp;
stacknxt = sp->space;
stacknleft = newlen;
stacknxt = SPACE(sp);
stacknleft = newlen - (stacknxt - (char*)sp);
/*
* Stack marks pointing to the start of the old block
* must be relocated to point to the new block
*/
xmark = markp;
while (xmark != NULL && xmark->stackp == oldstackp) {
xmark->stackp = stackp;
xmark->stacknxt = stacknxt;
xmark->stacknleft = stacknleft;
xmark = xmark->marknext;
}
INTON;
} else {
p = stalloc(newlen);
bcopy(oldspace, p, oldlen);
stacknxt = p; /* free the space */
stacknleft += newlen; /* we just allocated */
if (oldlen != 0)
memcpy(p, oldspace, oldlen);
stunalloc(p);
}
}
void
grabstackblock(len) {
grabstackblock(int len)
{
len = ALIGN(len);
stacknxt += len;
stacknleft -= len;
@@ -254,8 +285,11 @@ grabstackblock(len) {
char *
growstackstr() {
int len = stackblocksize();
growstackstr(void)
{
int len;
len = stackblocksize();
if (herefd >= 0 && len >= 1024) {
xwrite(herefd, stackblock(), len);
sstrnleft = len - 1;
@@ -272,8 +306,11 @@ growstackstr() {
*/
char *
makestrspace() {
int len = stackblocksize() - sstrnleft;
makestrspace(void)
{
int len;
len = stackblocksize() - sstrnleft;
growstackblock();
sstrnleft = stackblocksize() - len;
return stackblock() + len;
@@ -282,11 +319,13 @@ makestrspace() {
void
ungrabstackstr(s, p)
char *s;
char *p;
{
ungrabstackstr(char *s, char *p)
{
stacknleft += stacknxt - s;
stacknxt = s;
sstrnleft = stacknleft - (p - s);
}
/*
* $PchId: memalloc.c,v 1.5 2006/05/22 12:03:26 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,13 +29,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)memalloc.h 5.1 (Berkeley) 3/7/91
* @(#)memalloc.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/memalloc.h,v 1.9 2004/04/06 20:06:51 markm Exp $
*/
struct stackmark {
struct stack_block *stackp;
char *stacknxt;
int stacknleft;
struct stackmark *marknext;
};
@@ -48,10 +46,8 @@ extern int stacknleft;
extern int sstrnleft;
extern int herefd;
#ifdef __STDC__
pointer ckmalloc(int);
pointer ckrealloc(pointer, int);
void free(pointer); /* defined in C library */
char *savestr(char *);
pointer stalloc(int);
void stunalloc(pointer);
@@ -62,21 +58,6 @@ void grabstackblock(int);
char *growstackstr(void);
char *makestrspace(void);
void ungrabstackstr(char *, char *);
#else
pointer ckmalloc();
pointer ckrealloc();
void free(); /* defined in C library */
char *savestr();
pointer stalloc();
void stunalloc();
void setstackmark();
void popstackmark();
void growstackblock();
void grabstackblock();
char *growstackstr();
char *makestrspace();
void ungrabstackstr();
#endif
@@ -84,7 +65,7 @@ void ungrabstackstr();
#define stackblocksize() stacknleft
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
#define CHECKSTRSPACE(n, p) if (sstrnleft < n) p = makestrspace(); else
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); }
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
#define STUNPUTC(p) (++sstrnleft, --p)
@@ -93,3 +74,7 @@ void ungrabstackstr();
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
#define ckfree(p) free((pointer)(p))
/*
* $PchId: memalloc.h,v 1.3 2006/03/30 11:39:41 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,13 +31,32 @@
*/
#ifndef lint
static char sccsid[] = "@(#)miscbltin.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/miscbltin.c,v 1.30 2004/04/06 20:06:51 markm Exp $");
*/
/*
* Miscelaneous builtins.
* Miscellaneous builtins.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/select.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include "shell.h"
#include "options.h"
#include "var.h"
@@ -49,38 +64,71 @@ static char sccsid[] = "@(#)miscbltin.c 5.2 (Berkeley) 3/13/91";
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "builtins.h"
#undef eflag
extern char **argptr; /* argument list for builtin command */
/*
* The read builtin. The -e option causes backslashes to escape the
* following character.
* The read builtin. The -r option causes backslashes to be treated like
* ordinary characters.
*
* This uses unbuffered input, which may be avoidable in some cases.
*/
readcmd(argc, argv) char **argv; {
int
readcmd(int argc __unused, char **argv __unused)
{
char **ap;
int backslash;
char c;
int eflag;
int rflag;
char *prompt;
char *ifs;
char *p;
int startword;
int status;
int i;
struct timeval tv;
char *tvptr;
#ifndef __minix_vmd
fd_set ifds;
#endif
struct termios told, tnew;
int tsaved;
eflag = 0;
rflag = 0;
prompt = NULL;
while ((i = nextopt("ep:")) != '\0') {
if (i == 'p')
prompt = optarg;
else
eflag = 1;
tv.tv_sec = -1;
tv.tv_usec = 0;
while ((i = nextopt("erp:t:")) != '\0') {
switch(i) {
case 'p':
prompt = shoptarg;
break;
case 'e':
break;
case 'r':
rflag = 1;
break;
case 't':
tv.tv_sec = strtol(shoptarg, &tvptr, 0);
if (tvptr == shoptarg)
error("timeout value");
switch(*tvptr) {
case 0:
case 's':
break;
case 'h':
tv.tv_sec *= 60;
/* FALLTHROUGH */
case 'm':
tv.tv_sec *= 60;
break;
default:
error("timeout unit");
}
break;
}
}
if (prompt && isatty(0)) {
out2str(prompt);
@@ -90,12 +138,45 @@ readcmd(argc, argv) char **argv; {
error("arg count");
if ((ifs = bltinlookup("IFS", 1)) == NULL)
ifs = nullstr;
if (tv.tv_sec >= 0) {
#ifdef __minix
abort();
#else
/*
* See if we can disable input processing; this will
* not give the desired result if we are in a pipeline
* and someone upstream is still in line-by-line mode.
*/
tsaved = 0;
if (tcgetattr(0, &told) == 0) {
memcpy(&tnew, &told, sizeof(told));
cfmakeraw(&tnew);
tcsetattr(0, TCSANOW, &tnew);
tsaved = 1;
}
/*
* Wait for something to become available.
*/
FD_ZERO(&ifds);
FD_SET(0, &ifds);
status = select(1, &ifds, NULL, NULL, &tv);
if (tsaved)
tcsetattr(0, TCSANOW, &told);
/*
* If there's nothing ready, return an error.
*/
if (status <= 0)
return(1);
#endif
}
status = 0;
startword = 1;
backslash = 0;
STARTSTACKSTR(p);
for (;;) {
if (read(0, &c, 1) != 1) {
if (read(STDIN_FILENO, &c, 1) != 1) {
status = 1;
break;
}
@@ -107,7 +188,7 @@ readcmd(argc, argv) char **argv; {
STPUTC(c, p);
continue;
}
if (eflag && c == '\\') {
if (!rflag && c == '\\') {
backslash++;
continue;
}
@@ -118,7 +199,7 @@ readcmd(argc, argv) char **argv; {
}
startword = 0;
if (backslash && c == '\\') {
if (read(0, &c, 1) != 1) {
if (read(STDIN_FILENO, &c, 1) != 1) {
status = 1;
break;
}
@@ -142,25 +223,274 @@ readcmd(argc, argv) char **argv; {
umaskcmd(argc, argv) char **argv; {
int
umaskcmd(int argc __unused, char **argv)
{
char *ap;
int mask;
char *p;
int i;
int symbolic_mode = 0;
if ((p = argv[1]) == NULL) {
INTOFF;
mask = umask(0);
umask(mask);
INTON;
out1fmt("%.4o\n", mask); /* %#o might be better */
while ((i = nextopt("S")) != '\0') {
symbolic_mode = 1;
}
INTOFF;
mask = umask(0);
umask(mask);
INTON;
if ((ap = *argptr) == NULL) {
if (symbolic_mode) {
char u[4], g[4], o[4];
i = 0;
if ((mask & S_IRUSR) == 0)
u[i++] = 'r';
if ((mask & S_IWUSR) == 0)
u[i++] = 'w';
if ((mask & S_IXUSR) == 0)
u[i++] = 'x';
u[i] = '\0';
i = 0;
if ((mask & S_IRGRP) == 0)
g[i++] = 'r';
if ((mask & S_IWGRP) == 0)
g[i++] = 'w';
if ((mask & S_IXGRP) == 0)
g[i++] = 'x';
g[i] = '\0';
i = 0;
if ((mask & S_IROTH) == 0)
o[i++] = 'r';
if ((mask & S_IWOTH) == 0)
o[i++] = 'w';
if ((mask & S_IXOTH) == 0)
o[i++] = 'x';
o[i] = '\0';
out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
} else {
out1fmt("%.4o\n", mask);
}
} else {
mask = 0;
do {
if ((unsigned)(i = *p - '0') >= 8)
error("Illegal number: %s", argv[1]);
mask = (mask << 3) + i;
} while (*++p != '\0');
umask(mask);
if (isdigit(*ap)) {
mask = 0;
do {
if (*ap >= '8' || *ap < '0')
error("Illegal number: %s", argv[1]);
mask = (mask << 3) + (*ap - '0');
} while (*++ap != '\0');
umask(mask);
} else {
void *set;
if ((set = setmode (ap)) == 0)
error("Illegal number: %s", ap);
mask = getmode (set, ~mask & 0777);
umask(~mask & 0777);
free(set);
}
}
return 0;
}
#ifdef __minix
struct rlimit
{
unsigned long rlim_cur; /* current (soft) limit */
unsigned long rlim_max; /* maximum value for rlim_cur */
};
#define RLIM_INFINITY (((unsigned long)1 << 31) - 1)
int getrlimit (int, struct rlimit *);
int setrlimit (int, const struct rlimit *);
int getrlimit(resource, rlp)
int resource;
struct rlimit *rlp;
{
errno= ENOSYS;
return -1;
}
int setrlimit(resource, rlp)
int resource;
const struct rlimit *rlp;
{
errno= ENOSYS;
return -1;
}
#endif
/*
* ulimit builtin
*
* This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
* Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
* ash by J.T. Conklin.
*
* Public domain.
*/
struct limits {
const char *name;
const char *units;
int cmd;
int factor; /* multiply by to get rlim_{cur,max} values */
char option;
};
static const struct limits limits[] = {
#ifdef RLIMIT_CPU
{ "cpu time", "seconds", RLIMIT_CPU, 1, 't' },
#endif
#ifdef RLIMIT_FSIZE
{ "file size", "512-blocks", RLIMIT_FSIZE, 512, 'f' },
#endif
#ifdef RLIMIT_DATA
{ "data seg size", "kbytes", RLIMIT_DATA, 1024, 'd' },
#endif
#ifdef RLIMIT_STACK
{ "stack size", "kbytes", RLIMIT_STACK, 1024, 's' },
#endif
#ifdef RLIMIT_CORE
{ "core file size", "512-blocks", RLIMIT_CORE, 512, 'c' },
#endif
#ifdef RLIMIT_RSS
{ "max memory size", "kbytes", RLIMIT_RSS, 1024, 'm' },
#endif
#ifdef RLIMIT_MEMLOCK
{ "locked memory", "kbytes", RLIMIT_MEMLOCK, 1024, 'l' },
#endif
#ifdef RLIMIT_NPROC
{ "max user processes", (char *)0, RLIMIT_NPROC, 1, 'u' },
#endif
#ifdef RLIMIT_NOFILE
{ "open files", (char *)0, RLIMIT_NOFILE, 1, 'n' },
#endif
#ifdef RLIMIT_VMEM
{ "virtual mem size", "kbytes", RLIMIT_VMEM, 1024, 'v' },
#endif
#ifdef RLIMIT_SWAP
{ "swap limit", "kbytes", RLIMIT_SWAP, 1024, 'w' },
#endif
#ifdef RLIMIT_SBSIZE
{ "sbsize", "bytes", RLIMIT_SBSIZE, 1, 'b' },
#endif
{ (char *) 0, (char *)0, 0, 0, '\0' }
};
int
ulimitcmd(int argc __unused, char **argv __unused)
{
int c;
intmax_t val = 0;
enum { SOFT = 0x1, HARD = 0x2 }
how = SOFT | HARD;
const struct limits *l;
int set, all = 0;
int optc, what;
struct rlimit limit;
what = 'f';
while ((optc = nextopt("HSatfdsmcnuvlb")) != '\0')
switch (optc) {
case 'H':
how = HARD;
break;
case 'S':
how = SOFT;
break;
case 'a':
all = 1;
break;
default:
what = optc;
}
for (l = limits; l->name && l->option != what; l++)
;
if (!l->name)
error("internal error (%c)", what);
set = *argptr ? 1 : 0;
if (set) {
char *p = *argptr;
if (all || argptr[1])
error("too many arguments");
if (strcmp(p, "unlimited") == 0)
val = RLIM_INFINITY;
else {
val = 0;
while ((c = *p++) >= '0' && c <= '9')
{
val = (val * 10) + (long)(c - '0');
if (val < 0)
break;
}
if (c)
error("bad number");
val *= l->factor;
}
}
if (all) {
for (l = limits; l->name; l++) {
char optbuf[40];
if (getrlimit(l->cmd, &limit) < 0)
error("can't get limit: %s", strerror(errno));
if (how & SOFT)
val = limit.rlim_cur;
else if (how & HARD)
val = limit.rlim_max;
if (l->units)
snprintf(optbuf, sizeof(optbuf),
"(%s, -%c) ", l->units, l->option);
else
snprintf(optbuf, sizeof(optbuf),
"(-%c) ", l->option);
out1fmt("%-18s %18s ", l->name, optbuf);
if (val == RLIM_INFINITY)
out1fmt("unlimited\n");
else
{
val /= l->factor;
out1fmt("%jd\n", (intmax_t)val);
}
}
return 0;
}
if (getrlimit(l->cmd, &limit) < 0)
error("can't get limit: %s", strerror(errno));
if (set) {
if (how & SOFT)
limit.rlim_cur = val;
if (how & HARD)
limit.rlim_max = val;
if (setrlimit(l->cmd, &limit) < 0)
error("bad limit: %s", strerror(errno));
} else {
if (how & SOFT)
val = limit.rlim_cur;
else if (how & HARD)
val = limit.rlim_max;
if (val == RLIM_INFINITY)
out1fmt("unlimited\n");
else
{
val /= l->factor;
out1fmt("%jd\n", (intmax_t)val);
}
}
return 0;
}
/*
* $PchId: miscbltin.c,v 1.7 2006/05/23 11:59:08 philip Exp $
*/

View File

@@ -1,7 +1,7 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -14,10 +14,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -34,90 +30,69 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mkbuiltins 5.2 (Berkeley) 3/8/91
# @(#)mkbuiltins 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/mkbuiltins,v 1.13 2004/04/06 20:06:51 markm Exp $
# All calls to awk removed, because Minix bawk is deficient. (kjb)
if [ $# != 2 ]
then
echo "USAGE: $0 shell.h builtins"
exit 1
#temp=`/usr/bin/mktemp -t ka`
temp=/tmp/mkb$$
havehist=1
if [ "X$1" = "X-h" ]; then
havehist=0
shift
fi
SHL=$1
BLTINS=$2
temp=/tmp/ka$$
exec > builtins.c
havejobs=0
if [ "X$1" = "X-j" ]; then
havejobs=0
shift
elif grep '^#define[ ]*JOBS[ ]*1' $2 > /dev/null
then havejobs=1
fi
objdir=$1
exec > ${objdir}/builtins.c
cat <<\!
/*
* This file was generated by the mkbuiltins program.
*/
#include <stdlib.h>
#include "shell.h"
#include "builtins.h"
!
if grep '^#define JOBS[ ]*1' $SHL > /dev/null
then
# Job control.
sed -e '/^#/d
s/ / /g
s/ #.*//
/^ *$/d
s/-j//' $BLTINS > $temp
else
# No job control.
sed -e '/^#/d
s/ / /g
s/ #.*//
/^ *$/d
/-j/d' $BLTINS > $temp
fi
sed -e 's/ .*//
s/\(.*\)/int \1();/' $temp
awk '/^[^#]/ {if(('$havejobs' || $2 != "-j") && ('$havehist' || $2 != "-h")) \
print $0}' $3 | sed 's/-[hj]//' > $temp
#awk '{ printf "int %s();\n", $1}' $temp
echo '
int (*const builtinfunc[])() = {'
sed -e 's/ .*//
s/\(.*\)/ \1,/' $temp
int (*const builtinfunc[]) (int, char **) = {'
awk '/^[^#]/ { printf "\t%s,\n", $1}' $temp
echo '};
const struct builtincmd builtincmd[] = {'
i=0
while read line
do
set -$- $line
shift
for fun
do
echo " \"$fun\", $i,"
done
i=`expr $i + 1`
done < $temp
echo ' NULL, 0
awk '{ for (i = 2 ; i <= NF ; i++) {
printf "\t{ \"%s\", %d },\n", $i, NR-1
}}' $temp
echo ' { NULL, 0 }
};'
exec > builtins.h
exec > ${objdir}/builtins.h
cat <<\!
/*
* This file was generated by the mkbuiltins program.
*/
#include <sys/cdefs.h>
!
i=0
tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ < $temp |
while read line
do
set -$- $line
echo "#define $1 $i"
i=`expr $i + 1`
done
awk '{ printf "#define %s %d\n", $1, NR-1}'
echo '
struct builtincmd {
char *name;
int code;
};
extern int (*const builtinfunc[])();
extern int (*const builtinfunc[]) (int, char **);
extern const struct builtincmd builtincmd[];'
awk '{ printf "int %s (int, char **);\n", $1 }' < $temp
rm -f $temp
#
# $PchId: mkbuiltins,v 1.6 2006/05/22 12:42:58 philip Exp $

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,43 +31,51 @@
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mkinit.c 5.3 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)mkinit.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/mkinit.c,v 1.17 2004/04/06 20:06:51 markm Exp $");
*/
/*
* This program scans all the source files for code to handle various
* special events and combines this code into one file. This (allegedly)
* improves the structure of the program since there is no need for
* anyone outside of a module to know that that module performs special
* operations on particular events. The command is executed iff init.c
* is actually changed.
* operations on particular events.
*
* Usage: mkinit command sourcefile...
* Usage: mkinit sourcefile...
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#ifdef __minix
#define __unused
#endif
/*
* OUTFILE is the name of the output file. Output is initially written
* to the file OUTTEMP, which is then moved to OUTFILE if OUTTEMP and
* OUTFILE are different.
* to the file OUTTEMP, which is then moved to OUTFILE.
*/
#define OUTFILE "init.c"
#define OUTTEMP "init.c.new"
#define OUTOBJ "init.o"
/*
@@ -89,7 +93,7 @@ struct text {
int nleft;
struct block *start;
struct block *last;
};
};
struct block {
struct block *next;
@@ -105,7 +109,7 @@ struct event {
char *name; /* name of event (e.g. INIT) */
char *routine; /* name of routine called on event */
char *comment; /* comment describing routine */
struct text code; /* code for handling event */
struct text code; /* code for handling event */
};
@@ -148,42 +152,35 @@ struct text decls; /* declarations */
int amiddecls; /* for formatting */
void readfile(), doevent(), doinclude(), dodecl(), output();
void addstr(), addchar(), writetext();
static void readfile(char *);
static int match(char *, char *);
static int gooddefine(char *);
static void doevent(struct event *, FILE *, char *);
static void doinclude(char *);
static void dodecl(char *, FILE *);
static void output(void);
static void addstr(char *, struct text *);
static void addchar(int, struct text *);
static void writetext(struct text *, FILE *);
static FILE *ckfopen(char *, char *);
static void *ckmalloc(int);
static char *savestr(char *);
static void error(char *);
#define equal(s1, s2) (strcmp(s1, s2) == 0)
FILE *ckfopen();
char *savestr();
void *ckmalloc __P((int));
void error();
main(argc, argv)
char **argv;
{
int
main(int argc __unused, char *argv[])
{
char **ap;
int fd;
char c;
if (argc < 2)
error("Usage: mkinit command file...");
header_files[0] = "\"shell.h\"";
header_files[1] = "\"mystring.h\"";
for (ap = argv + 2 ; *ap ; ap++)
for (ap = argv + 1 ; *ap ; ap++)
readfile(*ap);
output();
if (file_changed()) {
unlink(OUTFILE);
link(OUTTEMP, OUTFILE);
unlink(OUTTEMP);
} else {
unlink(OUTTEMP);
if (touch(OUTOBJ))
exit(0); /* no compilation necessary */
}
printf("%s\n", argv[1]);
execl("/bin/sh", "sh", "-c", argv[1], (char *)0);
error("Can't exec shell");
rename(OUTTEMP, OUTFILE);
exit(0);
}
@@ -191,10 +188,9 @@ main(argc, argv)
* Parse an input file.
*/
void
readfile(fname)
char *fname;
{
static void
readfile(char *fname)
{
FILE *fp;
char line[1024];
struct event *ep;
@@ -215,19 +211,31 @@ readfile(fname)
doinclude(line);
if (line[0] == 'M' && match("MKINIT", line))
dodecl(line, fp);
if (line[0] == '#' && gooddefine(line))
if (line[0] == '#' && gooddefine(line)) {
char *cp;
char line2[1024];
static const char undef[] = "#undef ";
strcpy(line2, line);
memcpy(line2, undef, sizeof(undef) - 1);
cp = line2 + sizeof(undef) - 1;
while(*cp && (*cp == ' ' || *cp == '\t'))
cp++;
while(*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
cp++;
*cp++ = '\n'; *cp = '\0';
addstr(line2, &defines);
addstr(line, &defines);
}
}
fclose(fp);
}
int
match(name, line)
char *name;
char *line;
{
register char *p, *q;
static int
match(char *name, char *line)
{
char *p, *q;
p = name, q = line;
while (*p) {
@@ -240,11 +248,10 @@ match(name, line)
}
int
gooddefine(line)
char *line;
{
register char *p;
static int
gooddefine(char *line)
{
char *p;
if (! match("#define", line))
return 0; /* not a define */
@@ -264,12 +271,9 @@ gooddefine(line)
}
void
doevent(ep, fp, fname)
register struct event *ep;
FILE *fp;
char *fname;
{
static void
doevent(struct event *ep, FILE *fp, char *fname)
{
char line[1024];
int indent;
char *p;
@@ -304,13 +308,12 @@ doevent(ep, fp, fname)
}
void
doinclude(line)
char *line;
{
register char *p;
static void
doinclude(char *line)
{
char *p;
char *name;
register char **pp;
char **pp;
for (p = line ; *p != '"' && *p != '<' && *p != '\0' ; p++);
if (*p == '\0')
@@ -329,13 +332,11 @@ doinclude(line)
}
void
dodecl(line1, fp)
char *line1;
FILE *fp;
{
static void
dodecl(char *line1, FILE *fp)
{
char line[1024];
register char *p, *q;
char *p, *q;
if (strcmp(line1, "MKINIT\n") == 0) { /* start of struct/union decl */
addchar('\n', &decls);
@@ -350,7 +351,8 @@ dodecl(line1, fp)
if (! amiddecls)
addchar('\n', &decls);
q = NULL;
for (p = line1 + 6 ; *p != '=' && *p != '/' ; p++);
for (p = line1 + 6 ; *p && strchr("=/\n", *p) == NULL; p++)
continue;
if (*p == '=') { /* eliminate initialization */
for (q = p ; *q && *q != ';' ; q++);
if (*q == '\0')
@@ -375,8 +377,9 @@ dodecl(line1, fp)
* Write the output to the file OUTTEMP.
*/
void
output() {
static void
output(void)
{
FILE *fp;
char **pp;
struct event *ep;
@@ -392,7 +395,7 @@ output() {
for (ep = event ; ep->name ; ep++) {
fputs("\n\n\n", fp);
fputs(ep->comment, fp);
fprintf(fp, "\nvoid\n%s() {\n", ep->routine);
fprintf(fp, "\nvoid\n%s(void) {\n", ep->routine);
writetext(&ep->code, fp);
fprintf(fp, "}\n");
}
@@ -400,62 +403,15 @@ output() {
}
/*
* Return true if the new output file is different from the old one.
*/
int
file_changed() {
register FILE *f1, *f2;
register int c;
if ((f1 = fopen(OUTFILE, "r")) == NULL
|| (f2 = fopen(OUTTEMP, "r")) == NULL)
return 1;
while ((c = getc(f1)) == getc(f2)) {
if (c == EOF)
return 0;
}
return 1;
}
/*
* Touch a file. Returns 0 on failure, 1 on success.
*/
int
touch(file)
char *file;
{
int fd;
char c;
if ((fd = open(file, O_RDWR)) < 0)
return 0;
if (read(fd, &c, 1) != 1) {
close(fd);
return 0;
}
lseek(fd, 0L, 0);
write(fd, &c, 1);
close(fd);
return 1;
}
/*
* A text structure is simply a block of text that is kept in memory.
* Addstr appends a string to the text struct, and addchar appends a single
* character.
*/
void
addstr(s, text)
register char *s;
register struct text *text;
{
static void
addstr(char *s, struct text *text)
{
while (*s) {
if (--text->nleft < 0)
addchar(*s++, text);
@@ -465,10 +421,9 @@ addstr(s, text)
}
void
addchar(c, text)
register struct text *text;
{
static void
addchar(int c, struct text *text)
{
struct block *bp;
if (--text->nleft < 0) {
@@ -487,11 +442,9 @@ addchar(c, text)
/*
* Write the contents of a text structure to a file.
*/
void
writetext(text, fp)
struct text *text;
FILE *fp;
{
static void
writetext(struct text *text, FILE *fp)
{
struct block *bp;
if (text->start != NULL) {
@@ -501,47 +454,47 @@ writetext(text, fp)
}
}
FILE *
ckfopen(file, mode)
char *file;
char *mode;
{
static FILE *
ckfopen(char *file, char *mode)
{
FILE *fp;
if ((fp = fopen(file, mode)) == NULL) {
fprintf(stderr, "Can't open %s\n", file);
fprintf(stderr, "Can't open %s: %s\n", file, strerror(errno));
exit(2);
}
return fp;
}
void *
ckmalloc(nbytes) {
register char *p;
char *malloc();
static void *
ckmalloc(int nbytes)
{
char *p;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
return p;
}
char *
savestr(s)
char *s;
{
register char *p;
static char *
savestr(char *s)
{
char *p;
p = ckmalloc(strlen(s) + 1);
strcpy(p, s);
return p;
}
void
error(msg)
char *msg;
{
static void
error(char *msg)
{
if (curfile != NULL)
fprintf(stderr, "%s:%d: ", curfile, linno);
fprintf(stderr, "%s\n", msg);
exit(2);
}
/*
* $PchId: mkinit.c,v 1.6 2006/05/22 12:16:50 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -34,15 +30,20 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mknodes.c 5.1 (Berkeley) 3/7/91";
static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95";
#endif /* not lint */
#endif
/*
__FBSDID("$FreeBSD: src/bin/sh/mknodes.c,v 1.17 2004/04/06 20:06:51 markm Exp $");
*/
/*
* This program reads the nodetypes file and nodes.c.pat file. It generates
@@ -50,7 +51,10 @@ static char sccsid[] = "@(#)mknodes.c 5.1 (Berkeley) 3/7/91";
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#define MAXTYPES 50 /* max number of node types */
#define MAXFIELDS 20 /* max fields in a structure */
@@ -80,31 +84,42 @@ struct str { /* struct representing a node structure */
};
int ntypes; /* number of node types */
char *nodename[MAXTYPES]; /* names of the nodes */
struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
int nstr; /* number of structures */
struct str str[MAXTYPES]; /* the structures */
struct str *curstr; /* current structure */
static int ntypes; /* number of node types */
static char *nodename[MAXTYPES]; /* names of the nodes */
static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
static int nstr; /* number of structures */
static struct str str[MAXTYPES]; /* the structures */
static struct str *curstr; /* current structure */
static FILE *infp;
static char line[1024];
static int linno;
static char *linep;
#ifndef __printf0like
#define __printf0like(a,b)
#endif
static void parsenode(void);
static void parsefield(void);
static void output(char *);
static void outsizes(FILE *);
static void outfunc(FILE *, int);
static void indent(int, FILE *);
static int nextfield(char *);
static void skipbl(void);
static int readline(void);
static void error(const char *, ...) __printf0like(1, 2);
static char *savestr(const char *);
FILE *infp = stdin;
char line[1024];
int linno;
char *linep;
char *savestr();
#define equal(s1, s2) (strcmp(s1, s2) == 0)
main(argc, argv)
char **argv;
{
int
main(int argc, char *argv[])
{
if (argc != 3)
error("usage: mknodes file\n");
error("usage: mknodes file");
infp = stdin;
if ((infp = fopen(argv[1], "r")) == NULL)
error("Can't open %s", argv[1]);
error("Can't open %s: %s", argv[1], strerror(errno));
while (readline()) {
if (line[0] == ' ' || line[0] == '\t')
parsefield();
@@ -112,12 +127,14 @@ main(argc, argv)
parsenode();
}
output(argv[2]);
return 0;
exit(0);
}
parsenode() {
static void
parsenode(void)
{
char name[BUFLEN];
char tag[BUFLEN];
struct str *sp;
@@ -131,7 +148,7 @@ parsenode() {
error("Garbage at end of line");
nodename[ntypes] = savestr(name);
for (sp = str ; sp < str + nstr ; sp++) {
if (equal(sp->tag, tag))
if (strcmp(sp->tag, tag) == 0)
break;
}
if (sp >= str + nstr) {
@@ -145,7 +162,9 @@ parsenode() {
}
parsefield() {
static void
parsefield(void)
{
char name[BUFLEN];
char type[BUFLEN];
char decl[2 * BUFLEN];
@@ -159,21 +178,21 @@ parsefield() {
error("No field type");
fp = &curstr->field[curstr->nfields];
fp->name = savestr(name);
if (equal(type, "nodeptr")) {
if (strcmp(type, "nodeptr") == 0) {
fp->type = T_NODE;
sprintf(decl, "union node *%s", name);
} else if (equal(type, "nodelist")) {
} else if (strcmp(type, "nodelist") == 0) {
fp->type = T_NODELIST;
sprintf(decl, "struct nodelist *%s", name);
} else if (equal(type, "string")) {
} else if (strcmp(type, "string") == 0) {
fp->type = T_STRING;
sprintf(decl, "char *%s", name);
} else if (equal(type, "int")) {
} else if (strcmp(type, "int") == 0) {
fp->type = T_INT;
sprintf(decl, "int %s", name);
} else if (equal(type, "other")) {
} else if (strcmp(type, "other") == 0) {
fp->type = T_OTHER;
} else if (equal(type, "temp")) {
} else if (strcmp(type, "temp") == 0) {
fp->type = T_TEMP;
} else {
error("Unknown type %s", type);
@@ -196,9 +215,9 @@ char writer[] = "\
*/\n\
\n";
output(file)
char *file;
{
static void
output(char *file)
{
FILE *hfile;
FILE *cfile;
FILE *patfile;
@@ -208,9 +227,9 @@ output(file)
char *p;
if ((patfile = fopen(file, "r")) == NULL)
error("Can't open %s", file);
error("Can't open %s: %s", file, strerror(errno));
if ((hfile = fopen("nodes.h", "w")) == NULL)
error("Can't create nodes.h");
error("Can't create nodes.h: %s", strerror(errno));
if ((cfile = fopen("nodes.c", "w")) == NULL)
error("Can't create nodes.c");
fputs(writer, hfile);
@@ -234,22 +253,17 @@ output(file)
fputs("\tstruct nodelist *next;\n", hfile);
fputs("\tunion node *n;\n", hfile);
fputs("};\n\n\n", hfile);
fputs("#ifdef __STDC__\n", hfile);
fputs("union node *copyfunc(union node *);\n", hfile);
fputs("void freefunc(union node *);\n", hfile);
fputs("#else\n", hfile);
fputs("union node *copyfunc();\n", hfile);
fputs("void freefunc();\n", hfile);
fputs("#endif\n", hfile);
fputs(writer, cfile);
while (fgets(line, sizeof line, patfile) != NULL) {
for (p = line ; *p == ' ' || *p == '\t' ; p++);
if (equal(p, "%SIZES\n"))
if (strcmp(p, "%SIZES\n") == 0)
outsizes(cfile);
else if (equal(p, "%CALCSIZE\n"))
else if (strcmp(p, "%CALCSIZE\n") == 0)
outfunc(cfile, 1);
else if (equal(p, "%COPY\n"))
else if (strcmp(p, "%COPY\n") == 0)
outfunc(cfile, 0);
else
fputs(line, cfile);
@@ -258,9 +272,9 @@ output(file)
outsizes(cfile)
FILE *cfile;
{
static void
outsizes(FILE *cfile)
{
int i;
fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes);
@@ -271,9 +285,9 @@ outsizes(cfile)
}
outfunc(cfile, calcsize)
FILE *cfile;
{
static void
outfunc(FILE *cfile, int calcsize)
{
struct str *sp;
struct field *fp;
int i;
@@ -287,8 +301,7 @@ outfunc(cfile, calcsize)
fputs(" funcblocksize += nodesize[n->type];\n", cfile);
else {
fputs(" new = funcblock;\n", cfile);
fputs(" *(char **)&funcblock += nodesize[n->type];\n",
cfile);
fputs(" funcblock = (char *)funcblock + nodesize[n->type];\n", cfile);
}
fputs(" switch (n->type) {\n", cfile);
for (sp = str ; sp < &str[nstr] ; sp++) {
@@ -351,9 +364,9 @@ outfunc(cfile, calcsize)
}
indent(amount, fp)
FILE *fp;
{
static void
indent(int amount, FILE *fp)
{
while (amount >= 8) {
putc('\t', fp);
amount -= 8;
@@ -364,11 +377,10 @@ indent(amount, fp)
}
int
nextfield(buf)
char *buf;
{
register char *p, *q;
static int
nextfield(char *buf)
{
char *p, *q;
p = linep;
while (*p == ' ' || *p == '\t')
@@ -382,15 +394,18 @@ nextfield(buf)
}
skipbl() {
static void
skipbl(void)
{
while (*linep == ' ' || *linep == '\t')
linep++;
}
int
readline() {
register char *p;
static int
readline(void)
{
char *p;
if (fgets(line, 1024, infp) == NULL)
return 0;
@@ -407,26 +422,34 @@ readline() {
error(msg, a1, a2, a3, a4, a5, a6)
char *msg;
{
fprintf(stderr, "line %d: ", linno);
fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
putc('\n', stderr);
static void
error(const char *msg, ...)
{
va_list va;
va_start(va, msg);
(void) fprintf(stderr, "line %d: ", linno);
(void) vfprintf(stderr, msg, va);
(void) fputc('\n', stderr);
va_end(va);
exit(2);
}
char *
savestr(s)
char *s;
{
register char *p;
char *malloc();
static char *
savestr(const char *s)
{
char *p;
if ((p = malloc(strlen(s) + 1)) == NULL)
error("Out of space");
strcpy(p, s);
(void) strcpy(p, s);
return p;
}
/*
* $PchId: mknodes.c,v 1.6 2006/05/23 12:05:14 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -35,23 +35,23 @@
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mksignames.c 5.1 (Berkeley) 3/7/91";
static char sccsid[] = "@(#)mksignames.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
/*
* This program generates the signames.h and signames.c files.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char *argv[]);
struct sig {
int signo; /* signal number */
@@ -198,3 +198,7 @@ main(argc, argv) char **argv; {
fprintf(cfile, "};\n");
exit(0);
}
/*
* $PchId: mksignames.c,v 1.2 2001/05/14 19:22:26 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -34,23 +30,33 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mksyntax.c 5.2 (Berkeley) 3/8/91";
static char sccsid[] = "@(#)mksyntax.c 8.2 (Berkeley) 5/4/95";
#endif /* not lint */
#endif
/*
__FBSDID("$FreeBSD: src/bin/sh/mksyntax.c,v 1.23 2004/04/06 20:06:51 markm Exp $");
*/
/*
* This program creates syntax.h and syntax.c.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"
#ifdef __minix
#define __unused
#endif
struct synclass {
char *name;
@@ -59,19 +65,21 @@ struct synclass {
/* Syntax classes */
struct synclass synclass[] = {
"CWORD", "character is nothing special",
"CNL", "newline character",
"CBACK", "a backslash character",
"CSQUOTE", "single quote",
"CDQUOTE", "double quote",
"CENDQUOTE", "a terminating quote",
"CBQUOTE", "backwards single quote",
"CVAR", "a dollar sign",
"CENDVAR", "a '}' character",
"CEOF", "end of file",
"CCTL", "like CWORD, except it must be escaped",
"CSPCL", "these terminate a word",
NULL, NULL
{ "CWORD", "character is nothing special" },
{ "CNL", "newline character" },
{ "CBACK", "a backslash character" },
{ "CSQUOTE", "single quote" },
{ "CDQUOTE", "double quote" },
{ "CENDQUOTE", "a terminating quote" },
{ "CBQUOTE", "backwards single quote" },
{ "CVAR", "a dollar sign" },
{ "CENDVAR", "a '}' character" },
{ "CLP", "a left paren in arithmetic" },
{ "CRP", "a right paren in arithmetic" },
{ "CEOF", "end of file" },
{ "CCTL", "like CWORD, except it must be escaped" },
{ "CSPCL", "these terminate a word" },
{ NULL, NULL }
};
@@ -80,31 +88,39 @@ struct synclass synclass[] = {
* you may have to change the definition of the is_in_name macro.
*/
struct synclass is_entry[] = {
"ISDIGIT", "a digit",
"ISUPPER", "an upper case letter",
"ISLOWER", "a lower case letter",
"ISUNDER", "an underscore",
"ISSPECL", "the name of a special parameter",
NULL, NULL,
{ "ISDIGIT", "a digit" },
{ "ISUPPER", "an upper case letter" },
{ "ISLOWER", "a lower case letter" },
{ "ISUNDER", "an underscore" },
{ "ISSPECL", "the name of a special parameter" },
{ NULL, NULL }
};
char writer[] = "\
static char writer[] = "\
/*\n\
* This file was generated by the mksyntax program.\n\
*/\n\
\n";
FILE *cfile;
FILE *hfile;
char *syntax[513];
int base;
int size; /* number of values which a char variable can have */
int nbits; /* number of bits in a character */
int digit_contig; /* true if digits are contiguous */
static FILE *cfile;
static FILE *hfile;
static char *syntax[513];
static int base;
static int size; /* number of values which a char variable can have */
static int nbits; /* number of bits in a character */
static int digit_contig;/* true if digits are contiguous */
static void filltable(char *);
static void init(void);
static void add(char *, char *);
static void print(char *);
static void output_type_macros(void);
static void digit_convert(void);
main() {
int
main(int argc __unused, char **argv __unused)
{
char c;
char d;
int sign;
@@ -136,7 +152,9 @@ main() {
if (d == c)
break;
}
#if 0
printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
#endif
if (nbits > 9) {
fputs("Characters can't have more than 9 bits\n", stderr);
exit(2);
@@ -151,14 +169,14 @@ main() {
digit_contig = 0;
}
fputs("#include <sys/cdefs.h>\n", hfile);
fputs("#include <ctype.h>\n", hfile);
/* Generate the #define statements in the header file */
fputs("/* Syntax classes */\n", hfile);
for (i = 0 ; synclass[i].name ; i++) {
sprintf(buf, "#define %s %d", synclass[i].name, i);
fputs(buf, hfile);
for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07)
putc('\t', hfile);
fprintf(hfile, "/* %s */\n", synclass[i].comment);
}
@@ -167,7 +185,7 @@ main() {
for (i = 0 ; is_entry[i].name ; i++) {
sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i);
fputs(buf, hfile);
for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07)
putc('\t', hfile);
fprintf(hfile, "/* %s */\n", is_entry[i].comment);
}
@@ -178,6 +196,7 @@ main() {
fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile);
fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile);
putc('\n', hfile);
output_type_macros(); /* is_digit, etc. */
putc('\n', hfile);
@@ -204,14 +223,28 @@ main() {
add("`", "CBQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
add("!*?[=", "CCTL");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
print("dqsyntax");
init();
fputs("\n/* syntax table used when in single quotes */\n", cfile);
add("\n", "CNL");
add("'", "CENDQUOTE");
add("!*?[=", "CCTL");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
print("sqsyntax");
init();
fputs("\n/* syntax table used when in arithmetic */\n", cfile);
add("\n", "CNL");
add("\\", "CBACK");
add("`", "CBQUOTE");
add("'", "CSQUOTE");
add("\"", "CDQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
add("(", "CLP");
add(")", "CRP");
print("arisyntax");
filltable("0");
fputs("\n/* character classification table */\n", cfile);
add("0123456789", "ISDIGIT");
@@ -231,9 +264,9 @@ main() {
* Clear the syntax table.
*/
filltable(dftval)
char *dftval;
{
static void
filltable(char *dftval)
{
int i;
for (i = 0 ; i < size ; i++)
@@ -245,7 +278,9 @@ filltable(dftval)
* Initialize the syntax table with default values.
*/
init() {
static void
init(void)
{
filltable("CWORD");
syntax[0] = "CEOF";
syntax[base + CTLESC] = "CCTL";
@@ -253,6 +288,9 @@ init() {
syntax[base + CTLENDVAR] = "CCTL";
syntax[base + CTLBACKQ] = "CCTL";
syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
syntax[base + CTLARI] = "CCTL";
syntax[base + CTLENDARI] = "CCTL";
syntax[base + CTLQUOTEMARK] = "CCTL";
}
@@ -260,9 +298,9 @@ init() {
* Add entries to the syntax table.
*/
add(p, type)
char *p, *type;
{
static void
add(char *p, char *type)
{
while (*p)
syntax[*p++ + base] = type;
}
@@ -273,9 +311,9 @@ add(p, type)
* Output the syntax table.
*/
print(name)
char *name;
{
static void
print(char *name)
{
int i;
int col;
@@ -306,16 +344,18 @@ print(name)
* contiguous, we can test for them quickly.
*/
char *macro[] = {
static char *macro[] = {
"#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)",
"#define is_alpha(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER))",
"#define is_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER))",
"#define is_in_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))",
"#define is_alpha(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && isalpha((unsigned char) (c)))",
"#define is_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && ((c) == '_' || isalpha((unsigned char) (c))))",
"#define is_in_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && ((c) == '_' || isalnum((unsigned char) (c))))",
"#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))",
NULL
};
output_type_macros() {
static void
output_type_macros(void)
{
char **pp;
if (digit_contig)
@@ -334,7 +374,9 @@ output_type_macros() {
* Output digit conversion table (if digits are not contiguous).
*/
digit_convert() {
static void
digit_convert(void)
{
int maxdigit;
static char digit[] = "0123456789";
char *p;
@@ -350,7 +392,11 @@ digit_convert() {
for (p = digit ; *p && *p != i ; p++);
if (*p == '\0')
p = digit;
fprintf(cfile, " %d,\n", p - digit);
fprintf(cfile, " %d,\n", (int)(p - digit));
}
fputs("};\n", cfile);
}
/*
* $PchId: mksyntax.c,v 1.7 2006/05/23 12:04:27 philip Exp $
*/

View File

@@ -1,7 +1,7 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -14,10 +14,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -34,7 +30,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mktokens 5.1 (Berkeley) 3/7/91
# @(#)mktokens 8.1 (Berkeley) 5/31/93
# $FreeBSD: src/bin/sh/mktokens,v 1.9 2004/04/06 20:06:51 markm Exp $
# All calls to awk removed, because Minix bawk is deficient. (kjb)
@@ -42,7 +39,9 @@
# token marks the end of a list. The third column is the name to print in
# error messages.
cat > /tmp/ka$$ <<\!
#temp=`/usr/bin/mktemp -t ka`
temp=/tmp/mkt$$
cat > $temp <<\!
TEOF 1 end of file
TNL 0 newline
TSEMI 0 ";"
@@ -70,16 +69,17 @@ TBEGIN 0 "{"
TEND 1 "}"
TCASE 0 "case"
TESAC 1 "esac"
TNOT 0 "!"
!
nl=`wc -l /tmp/ka$$`
exec > token.def
nl=`wc -l $temp`
exec > token.h
i=0
while read line
do
set -$- $line
echo "#define $1 $i"
i=`expr $i + 1`
done </tmp/ka$$
done <$temp
echo '
/* Array indicating which tokens mark the end of a list */
const char tokendlist[] = {'
@@ -87,18 +87,18 @@ while read line
do
set -$- $line
echo " $2,"
done </tmp/ka$$
done <$temp
echo '};
char *const tokname[] = {'
const char *const tokname[] = {'
sed -e 's/"/\\"/g' \
-e 's/[^ ]*[ ][ ]*[^ ]*[ ][ ]*\(.*\)/ "\1",/' \
/tmp/ka$$
$temp
echo '};
'
i=0
go=
sed 's/"//g' /tmp/ka$$ |
sed 's/"//g' $temp |
while read line
do
set -$- $line
@@ -106,7 +106,7 @@ sed 's/"//g' /tmp/ka$$ |
then
echo "#define KWDOFFSET $i"
echo
echo "char *const parsekwd[] = {"
echo "const char *const parsekwd[] = {"
go=true
fi
if [ "$go" ]
@@ -118,4 +118,7 @@ sed 's/"//g' /tmp/ka$$ |
echo ' 0
};'
rm /tmp/ka$$
rm $temp
#
# $PchId: mktokens,v 1.5 2006/05/22 12:43:35 philip Exp $

50
commands/ash/myhistedit.h Normal file
View File

@@ -0,0 +1,50 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)myhistedit.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/myhistedit.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
#include <histedit.h>
extern History *hist;
extern EditLine *el;
extern int displayhist;
void histedit(void);
void sethistsize(const char *);
int histcmd(int, char **);
int bindcmd(int, char **);
/* From libedit */
void re_goto_bottom(EditLine *);
/*
* $PchId: myhistedit.h,v 1.5 2006/03/29 15:55:18 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,14 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mystring.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/mystring.c,v 1.13 2004/04/06 20:06:51 markm Exp $");
*/
/*
* String functions.
@@ -44,12 +46,11 @@ static char sccsid[] = "@(#)mystring.c 5.1 (Berkeley) 3/7/91";
* equal(s1, s2) Return true if strings are equal.
* scopy(from, to) Copy a string.
* scopyn(from, to, n) Like scopy, but checks for overflow.
* strchr(s, c) Find first occurance of c in s.
* bcopy(from, to, n) Copy a block of memory.
* number(s) Convert a string of digits to an integer.
* is_number(s) Return true if s is a string of digits.
*/
#include <stdlib.h>
#include "shell.h"
#include "syntax.h"
#include "error.h"
@@ -58,6 +59,14 @@ static char sccsid[] = "@(#)mystring.c 5.1 (Berkeley) 3/7/91";
char nullstr[1]; /* zero length string */
/*
* equal - #defined in mystring.h
*/
/*
* scopy - #defined in mystring.h
*/
/*
* scopyn - copy a string from "from" to "to", truncating the string
@@ -66,11 +75,8 @@ char nullstr[1]; /* zero length string */
*/
void
scopyn(from, to, size)
register char const *from;
register char *to;
register int size;
{
scopyn(const char *from, char *to, int size)
{
while (--size > 0) {
if ((*to++ = *from++) == '\0')
@@ -80,59 +86,13 @@ scopyn(from, to, size)
}
/*
* strchr - find first occurrence of a character in a string.
*/
#ifndef SYS5
char *
mystrchr(s, charwanted)
char const *s;
register char charwanted;
{
register char const *scan;
/*
* The odd placement of the two tests is so NUL is findable.
*/
for (scan = s ; *scan != charwanted ; ) /* ++ moved down for opt. */
if (*scan++ == '\0')
return NULL;
return (char *)scan;
}
#endif
/*
* bcopy - copy bytes
*
* This routine was derived from code by Henry Spencer.
*/
void
mybcopy(src, dst, length)
pointer dst;
const pointer src;
register int length;
{
register char *d = dst;
register char *s = src;
while (--length >= 0)
*d++ = *s++;
}
/*
* prefix -- see if pfx is a prefix of string.
*/
int
prefix(pfx, string)
register char const *pfx;
register char const *string;
{
prefix(const char *pfx, const char *string)
{
while (*pfx) {
if (*pfx++ != *string++)
return 0;
@@ -147,12 +107,10 @@ prefix(pfx, string)
*/
int
number(s)
const char *s;
{
number(const char *s)
{
if (! is_number(s))
error2("Illegal number", (char *)s);
error("Illegal number: %s", (char *)s);
return atoi(s);
}
@@ -163,12 +121,15 @@ number(s)
*/
int
is_number(p)
register const char *p;
{
is_number(const char *p)
{
do {
if (! is_digit(*p))
return 0;
} while (*++p != '\0');
return 1;
}
/*
* $PchId: mystring.c,v 1.4 2006/05/22 12:21:53 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,39 +29,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mystring.h 5.1 (Berkeley) 3/7/91
* @(#)mystring.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/mystring.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#ifndef SYSV
#define strchr mystrchr
#endif
#include <string.h>
#ifdef __STDC__
void scopyn(const char *, char *, int);
char *strchr(const char *, int);
void mybcopy(const pointer, pointer, int);
int prefix(const char *, const char *);
int number(const char *);
int is_number(const char *);
int strcmp(const char *, const char *); /* from C library */
char *strcpy(char *, const char *); /* from C library */
int strlen(const char *); /* from C library */
char *strcat(char *, const char *); /* from C library */
char *strerror(int); /* from C library */
#else
void scopyn();
char *strchr();
void mybcopy();
int prefix();
int number();
int is_number();
int strcmp();
char *strcpy();
int strlen();
char *strcat();
char *strerror();
#endif
#define equal(s1, s2) (strcmp(s1, s2) == 0)
#define scopy(s1, s2) ((void)strcpy(s2, s1))
#define bcopy(src, dst, n) mybcopy((pointer)(src), (pointer)(dst), n)
/*
* $PchId: mystring.h,v 1.3 2006/03/29 15:49:08 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,9 +29,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nodes.c.pat 5.2 (Berkeley) 3/8/91
* @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/nodes.c.pat,v 1.15 2004/04/06 20:06:51 markm Exp $
*/
#include <stdlib.h>
/*
* Routine for dealing with parsed shell commands.
*/
@@ -43,35 +41,26 @@
#include "shell.h"
#include "nodes.h"
#include "memalloc.h"
#include "machdep.h"
#include "mystring.h"
int funcblocksize; /* size of structures in function */
int funcstringsize; /* size of strings in node */
#ifdef __STDC__
pointer funcblock; /* block to allocate function from */
#else
char *funcblock; /* block to allocate function from */
#ifndef __minix
#include <sys/param.h>
#endif
char *funcstring; /* block to allocate strings from */
#include "machdep.h"
STATIC int funcblocksize; /* size of structures in function */
STATIC int funcstringsize; /* size of strings in node */
STATIC pointer funcblock; /* block to allocate function from */
STATIC char *funcstring; /* block to allocate strings from */
%SIZES
#ifdef __STDC__
STATIC void calcsize(union node *);
STATIC void sizenodelist(struct nodelist *);
STATIC union node *copynode(union node *);
STATIC struct nodelist *copynodelist(struct nodelist *);
STATIC char *nodesavestr(char *);
#else
STATIC void calcsize();
STATIC void sizenodelist();
STATIC union node *copynode();
STATIC struct nodelist *copynodelist();
STATIC char *nodesavestr();
#endif
@@ -80,86 +69,81 @@ STATIC char *nodesavestr();
*/
union node *
copyfunc(n)
union node *n;
{
if (n == NULL)
return NULL;
funcblocksize = 0;
funcstringsize = 0;
calcsize(n);
funcblock = ckmalloc(funcblocksize + funcstringsize);
funcstring = (char *)funcblock + funcblocksize;
return copynode(n);
copyfunc(union node *n)
{
if (n == NULL)
return NULL;
funcblocksize = 0;
funcstringsize = 0;
calcsize(n);
funcblock = ckmalloc(funcblocksize + funcstringsize);
funcstring = (char *)funcblock + funcblocksize;
return copynode(n);
}
STATIC void
calcsize(n)
union node *n;
{
%CALCSIZE
calcsize(union node *n)
{
%CALCSIZE
}
STATIC void
sizenodelist(lp)
struct nodelist *lp;
{
while (lp) {
funcblocksize += ALIGN(sizeof (struct nodelist));
calcsize(lp->n);
lp = lp->next;
}
sizenodelist(struct nodelist *lp)
{
while (lp) {
funcblocksize += ALIGN(sizeof(struct nodelist));
calcsize(lp->n);
lp = lp->next;
}
}
STATIC union node *
copynode(n)
union node *n;
{
union node *new;
copynode(union node *n)
{
union node *new;
%COPY
return new;
%COPY
return new;
}
STATIC struct nodelist *
copynodelist(lp)
struct nodelist *lp;
{
struct nodelist *start;
struct nodelist **lpp;
copynodelist(struct nodelist *lp)
{
struct nodelist *start;
struct nodelist **lpp;
lpp = &start;
while (lp) {
*lpp = funcblock;
*(char **)&funcblock += ALIGN(sizeof (struct nodelist));
(*lpp)->n = copynode(lp->n);
lp = lp->next;
lpp = &(*lpp)->next;
}
*lpp = NULL;
return start;
lpp = &start;
while (lp) {
*lpp = funcblock;
funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist));
(*lpp)->n = copynode(lp->n);
lp = lp->next;
lpp = &(*lpp)->next;
}
*lpp = NULL;
return start;
}
STATIC char *
nodesavestr(s)
char *s;
{
register char *p = s;
register char *q = funcstring;
char *rtn = funcstring;
nodesavestr(char *s)
{
char *p = s;
char *q = funcstring;
char *rtn = funcstring;
while (*q++ = *p++);
funcstring = q;
return rtn;
while ((*q++ = *p++) != '\0')
continue;
funcstring = q;
return rtn;
}
@@ -169,9 +153,12 @@ nodesavestr(s)
*/
void
freefunc(n)
union node *n;
{
if (n)
ckfree(n);
freefunc(union node *n)
{
if (n)
ckfree(n);
}
/*
* $PchId: nodes.c.pat,v 1.5 2006/05/22 12:43:57 philip Exp $
*/

View File

@@ -1,7 +1,6 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -14,10 +13,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -34,7 +29,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)nodetypes 5.1 (Berkeley) 3/7/91
# @(#)nodetypes 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/nodetypes,v 1.9 2004/04/06 20:06:51 markm Exp $
# This file describes the nodes used in parse trees. Unindented lines
# contain a node type followed by a structure tag. Subsequent indented
@@ -118,7 +114,9 @@ NARG narg # represents a word
NTO nfile # fd> fname
NFROM nfile # fd< fname
NFROMTO nfile # fd<> fname
NAPPEND nfile # fd>> fname
NCLOBBER nfile # fd>| fname
type int
next nodeptr # next redirection in list
fd int # file descriptor being redirected
@@ -131,6 +129,8 @@ NFROMFD ndup # fd>&dupfd
next nodeptr # next redirection in list
fd int # file descriptor being redirected
dupfd int # file descriptor to duplicate
vname nodeptr # file name if fd>&$var
NHERE nhere # fd<<\!
NXHERE nhere # fd<<!
@@ -138,3 +138,10 @@ NXHERE nhere # fd<<!
next nodeptr # next redirection in list
fd int # file descriptor being redirected
doc nodeptr # input to command (NARG node)
NNOT nnot # ! command (actually pipeline)
type int
com nodeptr
#
# $PchId: nodetypes,v 1.3 2006/03/29 15:43:35 philip Exp $

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,18 @@
*/
#ifndef lint
static char sccsid[] = "@(#)options.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/options.c,v 1.21 2004/04/06 20:06:51 markm Exp $");
*/
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#define DEFINE_OPTIONS
@@ -52,25 +58,25 @@ static char sccsid[] = "@(#)options.c 5.2 (Berkeley) 3/13/91";
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "builtins.h"
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
char *arg0; /* value of $0 */
struct shparam shellparam; /* current positional parameters */
char **argptr; /* argument list for builtin commands */
char *optarg; /* set by nextopt (like getopt) */
char *shoptarg; /* set by nextopt (like getopt) */
char *optptr; /* used by nextopt */
int editable; /* isatty(0) && isatty(1) */
int editable; /* isatty(0) && isatty(1) */
char *minusc; /* argument to -c option */
#ifdef __STDC__
STATIC void options(int);
STATIC void minus_o(char *, int);
STATIC void setoption(int, int);
#else
STATIC void options();
STATIC void setoption();
#endif
STATIC int getopts(char *, char *, char **, char ***, char **);
/*
@@ -78,46 +84,56 @@ STATIC void setoption();
*/
void
procargs(argc, argv)
char **argv;
{
char *p;
procargs(int argc, char **argv)
{
int i;
argptr = argv;
if (argc > 0)
argptr++;
for (p = optval ; p < optval + sizeof optval - 1 ; p++)
*p = 2;
for (i = 0; i < NOPTS; i++)
optlist[i].val = 2;
privileged = (getuid() != geteuid() || getgid() != getegid());
options(1);
if (*argptr == NULL && minusc == NULL)
sflag = 1;
editable = (isatty(0) && isatty(1));
if (iflag == 2 && sflag == 1 && editable)
iflag = 1;
if (jflag == 2)
jflag = iflag;
for (p = optval ; p < optval + sizeof optval - 1 ; p++)
if (*p == 2)
*p = 0;
if (mflag == 2)
mflag = iflag;
for (i = 0; i < NOPTS; i++)
if (optlist[i].val == 2)
optlist[i].val = 0;
arg0 = argv[0];
if (sflag == 0) {
arg0 = *argptr++;
if (minusc == NULL) {
commandname = arg0;
setinputfile(commandname, 0);
}
if (sflag == 0 && minusc == NULL) {
commandname = arg0 = *argptr++;
setinputfile(commandname, 0);
}
/* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
if (argptr && minusc && *argptr)
arg0 = *argptr++;
shellparam.p = argptr;
shellparam.reset = 1;
/* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
while (*argptr) {
shellparam.nparam++;
argptr++;
}
setinteractive(iflag);
setjobctl(jflag);
optschanged();
}
void
optschanged(void)
{
setinteractive(iflag);
#if !defined(NO_HISTORY) && !defined(EDITLINE)
histedit();
#endif
setjobctl(mflag);
}
/*
* Process shell options. The global variable argptr contains a pointer
@@ -125,8 +141,9 @@ procargs(argc, argv)
*/
STATIC void
options(cmdline) {
register char *p;
options(int cmdline)
{
char *p;
int val;
int c;
@@ -136,14 +153,14 @@ options(cmdline) {
argptr++;
if ((c = *p++) == '-') {
val = 1;
if (p[0] == '\0' || p[0] == '-' && p[1] == '\0') {
if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
if (!cmdline) {
/* "-" means turn off -x and -v */
if (p[0] == '\0')
xflag = vflag = 0;
/* "--" means reset params */
else if (*argptr == NULL)
setparam(argptr);
setparam(argptr);
}
break; /* "-" or "--" terminates options */
}
@@ -166,26 +183,79 @@ options(cmdline) {
#ifdef NOHACK
break;
#endif
} else if (c == 'o') {
minus_o(*argptr, val);
if (*argptr)
argptr++;
} else {
if (c == 'p' && !val && privileged) {
(void) setuid(getuid());
(void) setgid(getgid());
}
setoption(c, val);
}
}
if (! cmdline)
break;
}
}
STATIC void
minus_o(char *name, int val)
{
int doneset, i;
if (name == NULL) {
if (val) {
/* "Pretty" output. */
out1str("Current option settings\n");
for (i = 0; i < NOPTS; i++)
out1fmt("%-16s%s\n", optlist[i].name,
optlist[i].val ? "on" : "off");
} else {
/* Output suitable for re-input to shell. */
for (doneset = i = 0; i < NOPTS; i++)
if (optlist[i].val) {
if (!doneset) {
out1str("set");
doneset = 1;
}
out1fmt(" -o %s", optlist[i].name);
}
if (doneset)
out1c('\n');
}
} else {
for (i = 0; i < NOPTS; i++)
if (equal(name, optlist[i].name)) {
if (!val && privileged && equal(name, "privileged")) {
(void) setuid(getuid());
(void) setgid(getgid());
}
setoption(optlist[i].letter, val);
return;
}
error("Illegal option -o %s", name);
}
}
STATIC void
setoption(flag, val)
char flag;
int val;
{
register char *p;
setoption(int flag, int val)
{
int i;
if ((p = strchr(optchar, flag)) == NULL)
error("Illegal option -%c", flag);
optval[p - optchar] = val;
for (i = 0; i < NOPTS; i++)
if (optlist[i].letter == flag) {
optlist[i].val = val;
if (val) {
/* #%$ hack for ksh semantics */
if (flag == 'V')
Eflag = 0;
else if (flag == 'E')
Vflag = 0;
}
return;
}
error("Illegal option -%c", flag);
}
@@ -194,10 +264,12 @@ setoption(flag, val)
INCLUDE "options.h"
SHELLPROC {
char *p;
int i;
for (i = 0; i < NOPTS; i++)
optlist[i].val = 0;
optschanged();
for (p = optval ; p < optval + sizeof optval ; p++)
*p = 0;
}
#endif
@@ -207,9 +279,8 @@ SHELLPROC {
*/
void
setparam(argv)
char **argv;
{
setparam(char **argv)
{
char **newparam;
char **ap;
int nparam;
@@ -233,9 +304,8 @@ setparam(argv)
*/
void
freeparam(param)
struct shparam *param;
{
freeparam(struct shparam *param)
{
char **ap;
if (param->malloc) {
@@ -251,7 +321,9 @@ freeparam(param)
* The shift builtin command.
*/
shiftcmd(argc, argv) char **argv; {
int
shiftcmd(int argc, char **argv)
{
int n;
char **ap1, **ap2;
@@ -259,7 +331,7 @@ shiftcmd(argc, argv) char **argv; {
if (argc > 1)
n = number(argv[1]);
if (n > shellparam.nparam)
n = shellparam.nparam;
error("can't shift that many");
INTOFF;
shellparam.nparam -= n;
for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
@@ -279,13 +351,14 @@ shiftcmd(argc, argv) char **argv; {
* The set command builtin.
*/
setcmd(argc, argv) char **argv; {
int
setcmd(int argc, char **argv)
{
if (argc == 1)
return showvarscmd(argc, argv);
INTOFF;
options(0);
setinteractive(iflag);
setjobctl(jflag);
optschanged();
if (*argptr != NULL) {
setparam(argptr);
}
@@ -294,6 +367,15 @@ setcmd(argc, argv) char **argv; {
}
void
getoptsreset(const char *value)
{
if (number(value) == 1) {
shellparam.optnext = NULL;
shellparam.reset = 1;
}
}
/*
* The getopts builtin. Shellparam.optnext points to the next argument
* to be processed. Shellparam.optptr points to the next character to
@@ -301,63 +383,127 @@ setcmd(argc, argv) char **argv; {
* then it's the first time getopts has been called.
*/
getoptscmd(argc, argv) char **argv; {
register char *p, *q;
char c;
int
getoptscmd(int argc, char **argv)
{
char **optbase = NULL;
if (argc < 3)
error("usage: getopts optstring var [arg]");
else if (argc == 3)
optbase = shellparam.p;
else
optbase = &argv[3];
if (shellparam.reset == 1) {
shellparam.optnext = optbase;
shellparam.optptr = NULL;
shellparam.reset = 0;
}
return getopts(argv[1], argv[2], optbase, &shellparam.optnext,
&shellparam.optptr);
}
STATIC int
getopts(char *optstr, char *optvar, char **optfirst, char ***optnext,
char **optptr)
{
char *p, *q;
char c = '?';
int done = 0;
int ind = 0;
int err = 0;
char s[10];
if (argc != 3)
error("Usage: getopts optstring var");
if (shellparam.optnext == NULL) {
shellparam.optnext = shellparam.p;
shellparam.optptr = NULL;
}
if ((p = shellparam.optptr) == NULL || *p == '\0') {
p = *shellparam.optnext;
if ((p = *optptr) == NULL || *p == '\0') {
/* Current word is done, advance */
if (*optnext == NULL)
return 1;
p = **optnext;
if (p == NULL || *p != '-' || *++p == '\0') {
atend:
fmtstr(s, 10, "%d", shellparam.optnext - shellparam.p + 1);
setvar("OPTIND", s, 0);
shellparam.optnext = NULL;
return 1;
ind = *optnext - optfirst + 1;
*optnext = NULL;
p = NULL;
done = 1;
goto out;
}
shellparam.optnext++;
(*optnext)++;
if (p[0] == '-' && p[1] == '\0') /* check for "--" */
goto atend;
}
c = *p++;
for (q = argv[1] ; *q != c ; ) {
for (q = optstr; *q != c; ) {
if (*q == '\0') {
out1fmt("Illegal option -%c\n", c);
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
err |= setvarsafe("OPTARG", s, 0);
}
else {
out1fmt("Illegal option -%c\n", c);
(void) unsetvar("OPTARG");
}
c = '?';
goto out;
goto bad;
}
if (*++q == ':')
q++;
}
if (*++q == ':') {
if (*p == '\0') {
if ((p = *shellparam.optnext) == NULL) {
out1fmt("No arg for -%c option\n", c);
c = '?';
goto out;
if (*p == '\0' && (p = **optnext) == NULL) {
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
err |= setvarsafe("OPTARG", s, 0);
c = ':';
}
shellparam.optnext++;
else {
out1fmt("No arg for -%c option\n", c);
(void) unsetvar("OPTARG");
c = '?';
}
goto bad;
}
setvar("OPTARG", p, 0);
p = "";
if (p == **optnext)
(*optnext)++;
setvarsafe("OPTARG", p, 0);
p = NULL;
}
else
setvarsafe("OPTARG", "", 0);
ind = *optnext - optfirst + 1;
goto out;
bad:
ind = 1;
*optnext = NULL;
p = NULL;
out:
shellparam.optptr = p;
*optptr = p;
fmtstr(s, sizeof(s), "%d", ind);
err |= setvarsafe("OPTIND", s, VNOFUNC);
s[0] = c;
s[1] = '\0';
setvar(argv[2], s, 0);
fmtstr(s, 10, "%d", shellparam.optnext - shellparam.p + 1);
setvar("OPTIND", s, 0);
return 0;
err |= setvarsafe(optvar, s, 0);
if (err) {
*optnext = NULL;
*optptr = NULL;
flushall();
exraise(EXERROR);
}
return done;
}
/*
* XXX - should get rid of. have all builtins use getopt(3). the
* library getopt must have the BSD extension static variable "optreset"
* otherwise it can't be used within the shell safely.
*
* Standard option processing (a la getopt) for builtin routines. The
* only argument that is passed to nextopt is the option string; the
* other arguments are unnecessary. It return the character, or '\0' on
@@ -365,10 +511,9 @@ out:
*/
int
nextopt(optstring)
char *optstring;
{
register char *p, *q;
nextopt(char *optstring)
{
char *p, *q;
char c;
if ((p = optptr) == NULL || *p == '\0') {
@@ -389,9 +534,13 @@ nextopt(optstring)
if (*++q == ':') {
if (*p == '\0' && (p = *argptr++) == NULL)
error("No arg for -%c option", c);
optarg = p;
shoptarg = p;
p = NULL;
}
optptr = p;
return c;
}
/*
* $PchId: options.c,v 1.6 2006/05/29 13:09:12 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,38 +29,71 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)options.h 5.1 (Berkeley) 3/7/91
* @(#)options.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/options.h,v 1.13 2004/04/06 20:06:51 markm Exp $
*/
struct shparam {
int nparam; /* number of positional parameters (without $0) */
char malloc; /* true if parameter list dynamicly allocated */
int nparam; /* # of positional parameters (without $0) */
unsigned char malloc; /* if parameter list dynamically allocated */
unsigned char reset; /* if getopts has been reset */
char **p; /* parameter list */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
};
#define eflag optval[0]
#define fflag optval[1]
#define Iflag optval[2]
#define iflag optval[3]
#define jflag optval[4]
#define nflag optval[5]
#define sflag optval[6]
#define xflag optval[7]
#define zflag optval[8]
#define vflag optval[9]
#define eflag optlist[0].val
#define fflag optlist[1].val
#define Iflag optlist[2].val
#define iflag optlist[3].val
#define mflag optlist[4].val
#define nflag optlist[5].val
#define sflag optlist[6].val
#define xflag optlist[7].val
#define vflag optlist[8].val
#define Vflag optlist[9].val
#define Eflag optlist[10].val
#define Cflag optlist[11].val
#define aflag optlist[12].val
#define bflag optlist[13].val
#define uflag optlist[14].val
#define privileged optlist[15].val
#define Tflag optlist[16].val
#define Pflag optlist[17].val
#define NOPTS 10
#define NOPTS 18
struct optent {
const char *name;
const char letter;
char val;
};
#ifdef DEFINE_OPTIONS
const char optchar[NOPTS+1] = "efIijnsxzv"; /* shell flags */
char optval[NOPTS+1]; /* values of option flags */
struct optent optlist[NOPTS] = {
{ "errexit", 'e', 0 },
{ "noglob", 'f', 0 },
{ "ignoreeof", 'I', 0 },
{ "interactive",'i', 0 },
{ "monitor", 'm', 0 },
{ "noexec", 'n', 0 },
{ "stdin", 's', 0 },
{ "xtrace", 'x', 0 },
{ "verbose", 'v', 0 },
{ "vi", 'V', 0 },
{ "emacs", 'E', 0 },
{ "noclobber", 'C', 0 },
{ "allexport", 'a', 0 },
{ "notify", 'b', 0 },
{ "nounset", 'u', 0 },
{ "privileged", 'p', 0 },
{ "trapsasync", 'T', 0 },
{ "physical", 'P', 0 },
};
#else
extern const char optchar[NOPTS+1];
extern char optval[NOPTS+1];
extern struct optent optlist[NOPTS];
#endif
@@ -72,19 +101,20 @@ extern char *minusc; /* argument to -c option */
extern char *arg0; /* $0 */
extern struct shparam shellparam; /* $@ */
extern char **argptr; /* argument list for builtin commands */
extern char *optarg; /* set by nextopt */
extern char *shoptarg; /* set by nextopt */
extern char *optptr; /* used by nextopt */
extern int editable; /* isatty(0) && isatty(1) */
extern int editable; /* isatty(0) && isatty(1) */
#ifdef __STDC__
void procargs(int, char **);
void optschanged(void);
void setparam(char **);
void freeparam(struct shparam *);
int shiftcmd(int, char **);
int setcmd(int, char **);
int getoptscmd(int, char **);
int nextopt(char *);
#else
void procargs();
void setparam();
void freeparam();
int nextopt();
#endif
void getoptsreset(const char *);
/*
* $PchId: options.h,v 1.5 2006/05/29 13:08:45 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,7 +31,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)output.c 5.1 (Berkeley) 3/7/91";
static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
/*
@@ -55,12 +51,16 @@ static char sccsid[] = "@(#)output.c 5.1 (Berkeley) 3/7/91";
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "var.h"
#ifdef __STDC__
#include "stdarg.h"
#else
#include <varargs.h>
#endif
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define OUTBUFSIZ BUFSIZ
@@ -115,27 +115,63 @@ open_mem(block, length, file)
void
out1str(p)
char *p;
const char *p;
{
outstr(p, out1);
}
void
out1qstr(const char *p)
{
outqstr(p, out1);
}
void
out2str(p)
char *p;
{
out2str(const char *p)
{
outstr(p, out2);
}
void
outstr(p, file)
register char *p;
register const char *p;
register struct output *file;
{
while (*p)
outc(*p++, file);
if (file == out2)
flushout(file);
}
/* Like outstr(), but quote for re-input into the shell. */
void
outqstr(const char *p, struct output *file)
{
char ch;
if (p[strcspn(p, "|&;<>()$`\\\"'")] == '\0' && (!ifsset() ||
p[strcspn(p, ifsval())] == '\0')) {
outstr(p, file);
return;
}
out1c('\'');
while ((ch = *p++) != '\0') {
switch (ch) {
case '\'':
/*
* Can't quote single quotes inside single quotes;
* close them, write escaped single quote, open again.
*/
outstr("'\\''", file);
break;
default:
outc(ch, file);
}
}
out1c('\'');
}
@@ -208,7 +244,8 @@ freestdout() {
#ifdef __STDC__
void
outfmt(struct output *file, char *fmt, ...) {
outfmt(struct output *file, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -218,7 +255,8 @@ outfmt(struct output *file, char *fmt, ...) {
void
out1fmt(char *fmt, ...) {
out1fmt(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -226,9 +264,20 @@ out1fmt(char *fmt, ...) {
va_end(ap);
}
void
dprintf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
doformat(out2, fmt, ap);
va_end(ap);
flushout(out2);
}
void
fmtstr(char *outbuf, int length, char *fmt, ...) {
fmtstr(char *outbuf, int length, const char *fmt, ...)
{
va_list ap;
struct output strout;
@@ -275,6 +324,19 @@ out1fmt(va_alist)
va_end(ap);
}
void
dprintf(va_alist)
va_dcl
{
va_list ap;
char *fmt;
va_start(ap);
fmt = va_arg(ap, char *);
doformat(out2, fmt, ap);
va_end(ap);
flushout(out2);
}
void
fmtstr(va_alist)
@@ -325,11 +387,8 @@ static const char digit[17] = "0123456789ABCDEF";
void
doformat(dest, f, ap)
register struct output *dest;
register char *f; /* format string */
va_list ap;
{
doformat(struct output *dest, const char *f, va_list ap)
{
register char c;
char temp[TEMPSIZE];
int flushleft;
@@ -517,15 +576,6 @@ xwrite(fd, buf, nbytes)
}
}
/*
* Version of ioctl that retries after a signal is caught.
* $PchId: output.c,v 1.6 2006/05/22 12:46:03 philip Exp $
*/
int
xioctl(fd, request, arg) {
int i;
while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);
return i;
}

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,11 +29,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)output.h 5.1 (Berkeley) 3/7/91
* @(#)output.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/output.h,v 1.13 2004/04/06 20:06:51 markm Exp $
*/
#ifndef OUTPUT_INCL
#include <stdarg.h>
struct output {
char *nextc;
int nleft;
@@ -53,38 +52,27 @@ extern struct output memout;
extern struct output *out1;
extern struct output *out2;
#ifndef __printflike
#define __printflike(a,b)
#endif
#ifdef __STDC__
void outstr(char *, struct output *);
void out1str(char *);
void out2str(char *);
void outfmt(struct output *, char *, ...);
void out1fmt(char *, ...);
void fmtstr(char *, int, char *, ...);
/* void doformat(struct output *, char *, va_list); */
void doformat();
void open_mem(char *, int, struct output *);
void out1str(const char *);
void out1qstr(const char *);
void out2str(const char *);
void out2qstr(const char *);
void outstr(const char *, struct output *);
void outqstr(const char *, struct output *);
void emptyoutbuf(struct output *);
void flushall(void);
void flushout(struct output *);
void freestdout(void);
void outfmt(struct output *, const char *, ...) __printflike(2, 3);
void out1fmt(const char *, ...) __printflike(1, 2);
void dprintf(const char *, ...) __printflike(1, 2);
void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
int xwrite(int, char *, int);
int xioctl(int, int, int);
#else
void outstr();
void out1str();
void out2str();
void outfmt();
void out1fmt();
void fmtstr();
/* void doformat(); */
void doformat();
void emptyoutbuf();
void flushall();
void flushout();
void freestdout();
int xwrite();
int xioctl();
#endif
#define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
#define out1c(c) outc(c, out1);
@@ -92,3 +80,7 @@ int xioctl();
#define OUTPUT_INCL
#endif
/*
* $PchId: output.h,v 1.5 2006/05/23 12:04:54 philip Exp $
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)parser.h 5.1 (Berkeley) 3/7/91
* @(#)parser.h 8.3 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/parser.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
/* control characters in argument strings */
@@ -42,18 +39,27 @@
#define CTLENDVAR '\203'
#define CTLBACKQ '\204'
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
/* CTLBACKQ | CTLQUOTE == '\205' */
#define CTLARI '\206'
#define CTLENDARI '\207'
#define CTLQUOTEMARK '\210'
/* variable substitution byte (follows CTLVAR) */
#define VSTYPE 07 /* type of variable substitution */
#define VSNUL 040 /* colon--treat the empty string as unset */
#define VSQUOTE 0100 /* inside double quotes--suppress splitting */
#define VSTYPE 0x0f /* type of variable substitution */
#define VSNUL 0x10 /* colon--treat the empty string as unset */
#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
/* values of VSTYPE field */
#define VSNORMAL 1 /* normal variable: $var or ${var} */
#define VSMINUS 2 /* ${var-text} */
#define VSPLUS 3 /* ${var+text} */
#define VSQUESTION 4 /* ${var?message} */
#define VSASSIGN 5 /* ${var=text} */
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */
#define VSMINUS 0x2 /* ${var-text} */
#define VSPLUS 0x3 /* ${var+text} */
#define VSQUESTION 0x4 /* ${var?message} */
#define VSASSIGN 0x5 /* ${var=text} */
#define VSTRIMLEFT 0x6 /* ${var#pattern} */
#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
#define VSLENGTH 0xa /* ${#var} */
/*
@@ -63,12 +69,14 @@
*/
extern int tokpushback;
#define NEOF ((union node *)&tokpushback)
extern int whichprompt; /* 1 == PS1, 2 == PS2 */
#ifdef __STDC__
union node *parsecmd(int);
void fixredir(union node *, const char *, int);
int goodname(char *);
#else
union node *parsecmd();
int goodname();
#endif
char *getprompt(void *);
/*
* $PchId: parser.h,v 1.3 2006/03/29 14:33:35 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,23 @@
*/
#ifndef lint
static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/redir.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
/*
* Code for dealing with input/output redirection.
@@ -47,15 +58,10 @@ static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
#include "jobs.h"
#include "expand.h"
#include "redir.h"
#include "eval.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include "options.h"
#define EMPTY -2 /* marks an unused slot in redirtab */
@@ -65,25 +71,21 @@ static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
MKINIT
struct redirtab {
struct redirtab *next;
short renamed[10];
int renamed[10];
};
MKINIT struct redirtab *redirlist;
/* We keep track of whether or not fd0 has been redirected. This is for
background commands, where we want to redirect fd0 to /dev/null only
if it hasn't already been redirected. */
int fd0_redirected = 0;
/*
* We keep track of whether or not fd0 has been redirected. This is for
* background commands, where we want to redirect fd0 to /dev/null only
* if it hasn't already been redirected.
*/
STATIC int fd0_redirected = 0;
#ifdef __STDC__
STATIC void openredirect(union node *, char *);
STATIC void openredirect(union node *, char[10 ]);
STATIC int openhere(union node *);
#else
STATIC void openredirect();
STATIC int openhere();
#endif
/*
@@ -95,15 +97,14 @@ STATIC int openhere();
*/
void
redirect(redir, flags)
union node *redir;
int flags;
{
redirect(union node *redir, int flags)
{
union node *n;
struct redirtab *sv;
struct redirtab *sv = NULL;
int i;
int fd;
char memory[10]; /* file descriptors to write to memory */
int try;
char memory[10]; /* file descriptors to write to memory */
for (i = 10 ; --i >= 0 ; )
memory[i] = 0;
@@ -117,21 +118,38 @@ redirect(redir, flags)
}
for (n = redir ; n ; n = n->nfile.next) {
fd = n->nfile.fd;
try = 0;
if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
n->ndup.dupfd == fd)
continue; /* redirect from/to same file descriptor */
if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
INTOFF;
if ((i = copyfd(fd, 10)) != EMPTY) {
again:
if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
switch (errno) {
case EBADF:
if (!try) {
openredirect(n, memory);
try++;
goto again;
}
/* FALLTHROUGH*/
default:
INTON;
error("%d: %s", fd, strerror(errno));
break;
}
}
if (!try) {
sv->renamed[fd] = i;
close(fd);
}
INTON;
if (i == EMPTY)
error("Out of file descriptors");
} else {
close(fd);
}
if (fd == 0)
fd0_redirected++;
openredirect(n, memory);
if (!try)
openredirect(n, memory);
}
if (memory[1])
out1 = &memout;
@@ -141,16 +159,15 @@ redirect(redir, flags)
STATIC void
openredirect(redir, memory)
union node *redir;
char memory[10];
{
openredirect(union node *redir, char memory[10])
{
struct stat sb;
int fd = redir->nfile.fd;
char *fname;
int f;
/* Assume redirection succeeds. */
exitstatus = 0;
{ extern int exitstatus; exitstatus = 0; }
/*
* We suppress interrupts so that we won't leave open file
@@ -163,34 +180,35 @@ openredirect(redir, memory)
case NFROM:
fname = redir->nfile.expfname;
if ((f = open(fname, O_RDONLY)) < 0)
error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
error("cannot open %s: %s", fname, strerror(errno));
movefd:
if (f != fd) {
copyfd(f, fd);
dup2(f, fd);
close(f);
}
break;
case NFROMTO:
fname = redir->nfile.expfname;
if ((f = open(fname, O_RDWR|O_CREAT, 0666)) < 0)
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NTO:
fname = redir->nfile.expfname;
#ifdef O_CREAT
if (Cflag && stat(fname, &sb) != -1 && S_ISREG(sb.st_mode))
error("cannot create %s: %s", fname,
strerror(EEXIST));
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#else
if ((f = creat(fname, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#endif
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NCLOBBER:
fname = redir->nfile.expfname;
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NAPPEND:
fname = redir->nfile.expfname;
#ifdef O_APPEND
if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#else
if ((f = open(fname, O_WRONLY)) < 0
&& (f = creat(fname, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
lseek(f, 0L, 2);
#endif
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NTOFD:
case NFROMFD:
@@ -198,7 +216,9 @@ movefd:
if (memory[redir->ndup.dupfd])
memory[fd] = 1;
else
copyfd(redir->ndup.dupfd, fd);
dup2(redir->ndup.dupfd, fd);
} else {
close(fd);
}
break;
case NHERE:
@@ -219,14 +239,13 @@ movefd:
*/
STATIC int
openhere(redir)
union node *redir;
{
openhere(union node *redir)
{
int pip[2];
int len;
int len = 0;
if (pipe(pip) < 0)
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
if (redir->type == NHERE) {
len = strlen(redir->nhere.doc->narg.text);
if (len <= PIPESIZE) {
@@ -239,9 +258,7 @@ openhere(redir)
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
signal(SIGPIPE, SIG_DFL);
if (redir->type == NHERE)
xwrite(pip[1], redir->nhere.doc->narg.text, len);
@@ -261,18 +278,20 @@ out:
*/
void
popredir() {
register struct redirtab *rp = redirlist;
popredir(void)
{
struct redirtab *rp = redirlist;
int i;
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] != EMPTY) {
if (i == 0)
fd0_redirected--;
close(i);
if (i == 0)
fd0_redirected--;
if (rp->renamed[i] >= 0) {
copyfd(rp->renamed[i], i);
dup2(rp->renamed[i], i);
close(rp->renamed[i]);
} else {
close(i);
}
}
}
@@ -282,8 +301,6 @@ popredir() {
INTON;
}
/*
* Undo all redirections. Called on error or interrupt.
*/
@@ -303,14 +320,21 @@ SHELLPROC {
#endif
/* Return true if fd 0 has already been redirected at least once. */
int
fd0_redirected_p(void)
{
return fd0_redirected != 0;
}
/*
* Discard all saved file descriptors.
*/
void
clearredir() {
register struct redirtab *rp;
clearredir(void)
{
struct redirtab *rp;
int i;
for (rp = redirlist ; rp ; rp = rp->next) {
@@ -323,48 +347,6 @@ clearredir() {
}
}
/*
* Copy a file descriptor, like the F_DUPFD option of fcntl. Returns -1
* if the source file descriptor is closed, EMPTY if there are no unused
* file descriptors left.
* $PchId: redir.c,v 1.5 2006/05/22 12:27:37 philip Exp $
*/
int
copyfd(from, to) {
#ifdef F_DUPFD
int newfd;
newfd = fcntl(from, F_DUPFD, to);
if (newfd < 0 && errno == EMFILE)
return EMPTY;
return newfd;
#else
char toclose[32];
int i;
int newfd;
int e;
for (i = 0 ; i < to ; i++)
toclose[i] = 0;
INTOFF;
while ((newfd = dup(from)) >= 0 && newfd < to)
toclose[newfd] = 1;
e = errno;
for (i = 0 ; i < to ; i++) {
if (toclose[i])
close(i);
}
INTON;
if (newfd < 0 && e == EMFILE)
return EMPTY;
return newfd;
#endif
}
/* Return true if fd 0 has already been redirected at least once. */
int
fd0_redirected_p () {
return fd0_redirected != 0;
}

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,24 +29,21 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)redir.h 5.1 (Berkeley) 3/7/91
* @(#)redir.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/redir.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
/* flags passed to redirect */
#define REDIR_PUSH 01 /* save previous values of file descriptors */
#define REDIR_BACKQ 02 /* save the command output in memory */
#ifdef __STDC__
union node;
void redirect(union node *, int);
void popredir(void);
void clearredir(void);
int copyfd(int, int);
int fd0_redirected_p(void);
#else
void redirect();
void popredir();
void clearredir();
int copyfd();
int fd0_redirected_p();
#endif
void clearredir(void);
/*
* $PchId: redir.h,v 1.3 2006/03/29 14:13:34 philip Exp $
*/

463
commands/ash/setmode.c Normal file
View File

@@ -0,0 +1,463 @@
/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dave Borman at Cray Research, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#ifdef SETMODE_DEBUG
#include <stdio.h>
#endif
#include "shell.h"
#ifndef S_ISTXT
#define S_ISTXT S_ISVTX
#endif
#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
typedef struct bitcmd {
char cmd;
char cmd2;
mode_t bits;
} BITCMD;
#define CMD2_CLR 0x01
#define CMD2_SET 0x02
#define CMD2_GBITS 0x04
#define CMD2_OBITS 0x08
#define CMD2_UBITS 0x10
static BITCMD *addcmd (BITCMD *, int, int, int, unsigned int);
static int compress_mode (BITCMD *);
#ifdef SETMODE_DEBUG
static void dumpmode __P((BITCMD *));
#endif
/*
* Given the old mode and an array of bitcmd structures, apply the operations
* described in the bitcmd structures to the old mode, and return the new mode.
* Note that there is no '=' command; a strict assignment is just a '-' (clear
* bits) followed by a '+' (set bits).
*/
mode_t
getmode(bbox, omode)
void *bbox;
mode_t omode;
{
register BITCMD *set;
register mode_t clrval, newmode, value;
set = (BITCMD *)bbox;
newmode = omode;
for (value = 0;; set++)
switch(set->cmd) {
/*
* When copying the user, group or other bits around, we "know"
* where the bits are in the mode so that we can do shifts to
* copy them around. If we don't use shifts, it gets real
* grundgy with lots of single bit checks and bit sets.
*/
case 'u':
value = (newmode & S_IRWXU) >> 6;
goto common;
case 'g':
value = (newmode & S_IRWXG) >> 3;
goto common;
case 'o':
value = newmode & S_IRWXO;
common: if (set->cmd2 & CMD2_CLR) {
clrval =
(set->cmd2 & CMD2_SET) ? S_IRWXO : value;
if (set->cmd2 & CMD2_UBITS)
newmode &= ~((clrval<<6) & set->bits);
if (set->cmd2 & CMD2_GBITS)
newmode &= ~((clrval<<3) & set->bits);
if (set->cmd2 & CMD2_OBITS)
newmode &= ~(clrval & set->bits);
}
if (set->cmd2 & CMD2_SET) {
if (set->cmd2 & CMD2_UBITS)
newmode |= (value<<6) & set->bits;
if (set->cmd2 & CMD2_GBITS)
newmode |= (value<<3) & set->bits;
if (set->cmd2 & CMD2_OBITS)
newmode |= value & set->bits;
}
break;
case '+':
newmode |= set->bits;
break;
case '-':
newmode &= ~set->bits;
break;
case 'X':
if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
newmode |= set->bits;
break;
case '\0':
default:
#ifdef SETMODE_DEBUG
(void)printf("getmode:%04o -> %04o\n", omode, newmode);
#endif
return (newmode);
}
}
#define ADDCMD(a, b, c, d) \
if (set >= endset) { \
register BITCMD *newset; \
setlen += SET_LEN_INCR; \
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
if (!saveset) \
return (NULL); \
set = newset + (set - saveset); \
saveset = newset; \
endset = newset + (setlen - 2); \
} \
set = addcmd(set, (a), (b), (c), (d))
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
void *
setmode(p)
register char *p;
{
register int perm, who;
register char op;
BITCMD *set, *saveset, *endset;
sigset_t sigset, sigoset;
mode_t mask;
int equalopdone, permXbits, setlen;
if (!*p)
return (NULL);
/*
* Get a copy of the mask for the permissions that are mask relative.
* Flip the bits, we want what's not set. Since it's possible that
* the caller is opening files inside a signal handler, protect them
* as best we can.
*/
sigfillset(&sigset);
(void)sigprocmask(SIG_BLOCK, &sigset, &sigoset);
(void)umask(mask = umask(0));
mask = ~mask;
(void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
setlen = SET_LEN + 2;
if ((set = malloc((unsigned int)(sizeof(BITCMD) * setlen))) == NULL)
return (NULL);
saveset = set;
endset = set + (setlen - 2);
/*
* If an absolute number, get it and return; disallow non-octal digits
* or illegal bits.
*/
if (isdigit(*p)) {
perm = (mode_t)strtol(p, NULL, 8);
if (perm & ~(STANDARD_BITS|S_ISTXT)) {
free(saveset);
return (NULL);
}
while (*++p)
if (*p < '0' || *p > '7') {
free(saveset);
return (NULL);
}
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
return (saveset);
}
/*
* Build list of structures to set/clear/copy bits as described by
* each clause of the symbolic mode.
*/
for (;;) {
/* First, find out which bits might be modified. */
for (who = 0;; ++p) {
switch (*p) {
case 'a':
who |= STANDARD_BITS;
break;
case 'u':
who |= S_ISUID|S_IRWXU;
break;
case 'g':
who |= S_ISGID|S_IRWXG;
break;
case 'o':
who |= S_IRWXO;
break;
default:
goto getop;
}
}
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
free(saveset);
return (NULL);
}
if (op == '=')
equalopdone = 0;
who &= ~S_ISTXT;
for (perm = 0, permXbits = 0;; ++p) {
switch (*p) {
case 'r':
perm |= S_IRUSR|S_IRGRP|S_IROTH;
break;
case 's':
/* If only "other" bits ignore set-id. */
if (who & ~S_IRWXO)
perm |= S_ISUID|S_ISGID;
break;
case 't':
/* If only "other" bits ignore sticky. */
if (who & ~S_IRWXO) {
who |= S_ISTXT;
perm |= S_ISTXT;
}
break;
case 'w':
perm |= S_IWUSR|S_IWGRP|S_IWOTH;
break;
case 'X':
permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
break;
case 'x':
perm |= S_IXUSR|S_IXGRP|S_IXOTH;
break;
case 'u':
case 'g':
case 'o':
/*
* When ever we hit 'u', 'g', or 'o', we have
* to flush out any partial mode that we have,
* and then do the copying of the mode bits.
*/
if (perm) {
ADDCMD(op, who, perm, mask);
perm = 0;
}
if (op == '=')
equalopdone = 1;
if (op == '+' && permXbits) {
ADDCMD('X', who, permXbits, mask);
permXbits = 0;
}
ADDCMD(*p, who, op, mask);
break;
default:
/*
* Add any permissions that we haven't already
* done.
*/
if (perm || (op == '=' && !equalopdone)) {
if (op == '=')
equalopdone = 1;
ADDCMD(op, who, perm, mask);
perm = 0;
}
if (permXbits) {
ADDCMD('X', who, permXbits, mask);
permXbits = 0;
}
goto apply;
}
}
apply: if (!*p)
break;
if (*p != ',')
goto getop;
++p;
}
set->cmd = 0;
#ifdef SETMODE_DEBUG
(void)printf("Before compress_mode()\n");
dumpmode(saveset);
#endif
compress_mode(saveset);
#ifdef SETMODE_DEBUG
(void)printf("After compress_mode()\n");
dumpmode(saveset);
#endif
return (saveset);
}
static BITCMD *
addcmd(set, op, who, oparg, mask)
BITCMD *set;
register int oparg, who;
register int op;
unsigned int mask;
{
switch (op) {
case '=':
set->cmd = '-';
set->bits = who ? who : STANDARD_BITS;
set++;
op = '+';
/* FALLTHROUGH */
case '+':
case '-':
case 'X':
set->cmd = op;
set->bits = (who ? who : mask) & oparg;
break;
case 'u':
case 'g':
case 'o':
set->cmd = op;
if (who) {
set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
((who & S_IRGRP) ? CMD2_GBITS : 0) |
((who & S_IROTH) ? CMD2_OBITS : 0);
set->bits = ~0;
} else {
set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
set->bits = mask;
}
if (oparg == '+')
set->cmd2 |= CMD2_SET;
else if (oparg == '-')
set->cmd2 |= CMD2_CLR;
else if (oparg == '=')
set->cmd2 |= CMD2_SET|CMD2_CLR;
break;
}
return (set + 1);
}
#ifdef SETMODE_DEBUG
static void
dumpmode(set)
register BITCMD *set;
{
for (; set->cmd; ++set)
(void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
set->cmd2 & CMD2_CLR ? " CLR" : "",
set->cmd2 & CMD2_SET ? " SET" : "",
set->cmd2 & CMD2_UBITS ? " UBITS" : "",
set->cmd2 & CMD2_GBITS ? " GBITS" : "",
set->cmd2 & CMD2_OBITS ? " OBITS" : "");
}
#endif
/*
* Given an array of bitcmd structures, compress by compacting consecutive
* '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
* 'g' and 'o' commands continue to be separate. They could probably be
* compacted, but it's not worth the effort.
*/
static int
compress_mode(set)
register BITCMD *set;
{
register BITCMD *nset;
register int setbits, clrbits, Xbits, op;
for (nset = set;;) {
/* Copy over any 'u', 'g' and 'o' commands. */
while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
*set++ = *nset++;
if (!op)
return;
}
for (setbits = clrbits = Xbits = 0;; nset++) {
if ((op = nset->cmd) == '-') {
clrbits |= nset->bits;
setbits &= ~nset->bits;
Xbits &= ~nset->bits;
} else if (op == '+') {
setbits |= nset->bits;
clrbits &= ~nset->bits;
Xbits &= ~nset->bits;
} else if (op == 'X')
Xbits |= nset->bits & ~setbits;
else
break;
}
if (clrbits) {
set->cmd = '-';
set->cmd2 = 0;
set->bits = clrbits;
set++;
}
if (setbits) {
set->cmd = '+';
set->cmd2 = 0;
set->bits = setbits;
set++;
}
if (Xbits) {
set->cmd = 'X';
set->cmd2 = 0;
set->bits = Xbits;
set++;
}
}
}
/*
* $PchId: setmode.c,v 1.3 2006/05/23 11:57:34 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,19 +29,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)shell.h 5.4 (Berkeley) 4/12/91
* @(#)shell.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/shell.h,v 1.17 2004/04/06 20:06:51 markm Exp $
*/
#include <sys/types.h> /* for mode_t */
/*
* The follow should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
* SYMLINKS -> 1 if your system includes symbolic links, 0 otherwise.
* DIRENT -> 1 if your system has the SVR3 directory(3X) routines.
* UDIR -> 1 if you want the shell to simulate the /u directory.
* TILDE -> 1 if you want the shell to expand ~logname.
* USEGETPW -> 1 if getpwnam() must be used to look up a name.
* ATTY -> 1 to include code for atty(1).
* SHORTNAMES -> 1 if your linker cannot handle long names.
* READLINE -> 1 if line editing by readline() should be enabled.
* define BSD if you are running 4.2 BSD or later.
* define SYSV if you are running under System V.
@@ -56,52 +50,47 @@
* a quit signal will generate a core dump.
*/
#ifndef JOBS
#define JOBS 1
#endif
#ifndef BSD
#define BSD 1
#endif
#ifndef DEBUG
#define DEBUG 0
#endif
#define POSIX 1
#define JOBS 0
/* Set SYMLINKS to 0 by request of Giovanni Falzoni, who wrote the
* symlink patches for Minix; email to minix-devel-l of thu 3 nov.
/*
* Type of used arithmetics. SUSv3 requires us to have at least signed long.
*/
typedef long arith_t;
#define ARITH_FORMAT_STR "%ld"
#define atoarith_t(arg) strtol(arg, NULL, 0)
#define strtoarith_t(nptr, endptr, base) strtol(nptr, endptr, base)
#if 0
#define SYMLINKS defined(S_ISLNK)
#else
#define SYMLINKS 0
#endif
#define DIRENT 1
#define UDIR 0
#define TILDE 1
#define USEGETPW 0
#define ATTY 0
#define READLINE 1
#define HASHBANG 0
/* #define BSD */
#define POSIX 1
#define DEBUG 0
#ifdef __STDC__
typedef void *pointer;
#ifndef NULL
#define NULL (void *)0
#endif
#else /* not __STDC__ */
typedef char *pointer;
#ifndef NULL
#define NULL 0
#endif
#endif /* not __STDC__ */
#define STATIC /* empty */
#define MKINIT /* empty */
#include <sys/cdefs.h>
#include <sys/types.h>
#define STATIC static
#define MKINIT /* empty */
extern char nullstr[1]; /* null string */
#if DEBUG
#define TRACE(param) trace param
#define TRACE(param) sh_trace param
#else
#define TRACE(param)
#endif
#ifdef __minix
#define __unused
typedef long quad_t; /* XXX */
typedef unsigned long u_quad_t; /* XXX */
#endif
mode_t getmode(void *, int /* mode_t */);
void *setmode(char *);
/*
* $PchId: shell.h,v 1.7 2006/05/22 12:47:00 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,38 +31,54 @@
*/
#ifndef lint
static char sccsid[] = "@(#)show.c 5.2 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/show.c,v 1.21 2004/04/06 20:06:51 markm Exp $");
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include "shell.h"
#include "parser.h"
#include "nodes.h"
#include "mystring.h"
#include "show.h"
#if DEBUG
static shtree(), shcmd(), sharg(), indent();
static void trputc(int c);
static void shtree(union node *, int, char *, FILE*);
static void shcmd(union node *, FILE *);
static void sharg(union node *, FILE *);
static void indent(int, char *, FILE *);
static void trstring(char *);
static void showtree(union node *n);
showtree(n)
union node *n;
{
static void
showtree(union node *n)
{
trputs("showtree called\n");
shtree(n, 1, NULL, stdout);
}
static
shtree(n, ind, pfx, fp)
union node *n;
char *pfx;
FILE *fp;
{
static void
shtree(union node *n, int ind, char *pfx, FILE *fp)
{
struct nodelist *lp;
char *s;
if (n == NULL)
return;
indent(ind, pfx, fp);
switch(n->type) {
case NSEMI:
@@ -109,11 +121,9 @@ binop:
static
shcmd(cmd, fp)
union node *cmd;
FILE *fp;
{
static void
shcmd(union node *cmd, FILE *fp)
{
union node *np;
int first;
char *s;
@@ -133,14 +143,20 @@ shcmd(cmd, fp)
case NTO: s = ">"; dftfd = 1; break;
case NAPPEND: s = ">>"; dftfd = 1; break;
case NTOFD: s = ">&"; dftfd = 1; break;
case NCLOBBER: s = ">|"; dftfd = 1; break;
case NFROM: s = "<"; dftfd = 0; break;
case NFROMTO: s = "<>"; dftfd = 0; break;
case NFROMFD: s = "<&"; dftfd = 0; break;
default: s = "*error*"; dftfd = 0; break;
}
if (np->nfile.fd != dftfd)
fprintf(fp, "%d", np->nfile.fd);
fputs(s, fp);
if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
fprintf(fp, "%d", np->ndup.dupfd);
if (np->ndup.dupfd >= 0)
fprintf(fp, "%d", np->ndup.dupfd);
else
fprintf(fp, "-");
} else {
sharg(np->nfile.fname, fp);
}
@@ -150,11 +166,9 @@ shcmd(cmd, fp)
static
sharg(arg, fp)
union node *arg;
FILE *fp;
{
static void
sharg(union node *arg, FILE *fp)
{
char *p;
struct nodelist *bqlist;
int subtype;
@@ -174,10 +188,15 @@ sharg(arg, fp)
putc('$', fp);
putc('{', fp);
subtype = *++p;
if (subtype == VSLENGTH)
putc('#', fp);
while (*p != '=')
putc(*p++, fp);
if (subtype & VSNUL)
putc(':', fp);
switch (subtype & VSTYPE) {
case VSNORMAL:
putc('}', fp);
@@ -194,6 +213,22 @@ sharg(arg, fp)
case VSASSIGN:
putc('=', fp);
break;
case VSTRIMLEFT:
putc('#', fp);
break;
case VSTRIMLEFTMAX:
putc('#', fp);
putc('#', fp);
break;
case VSTRIMRIGHT:
putc('%', fp);
break;
case VSTRIMRIGHTMAX:
putc('%', fp);
putc('%', fp);
break;
case VSLENGTH:
break;
default:
printf("<subtype %d>", subtype);
}
@@ -216,11 +251,9 @@ sharg(arg, fp)
}
static
indent(amount, pfx, fp)
char *pfx;
FILE *fp;
{
static void
indent(int amount, char *pfx, FILE *fp)
{
int i;
for (i = 0 ; i < amount ; i++) {
@@ -229,8 +262,6 @@ indent(amount, pfx, fp)
putc('\t', fp);
}
}
#endif
/*
@@ -247,52 +278,48 @@ int debug = 0;
#endif
trputc(c) {
#if DEBUG
static void
trputc(int c)
{
if (tracefile == NULL)
return;
putc(c, tracefile);
if (c == '\n')
fflush(tracefile);
#endif
}
trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
char *fmt;
{
#if DEBUG
int e = errno;
if (tracefile == NULL)
return;
fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
if (strchr(fmt, '\n'))
fflush(tracefile);
errno = e;
#endif
void
sh_trace(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (tracefile != NULL) {
(void) vfprintf(tracefile, fmt, va);
if (strchr(fmt, '\n'))
(void) fflush(tracefile);
}
va_end(va);
}
trputs(s)
char *s;
{
#if DEBUG
void
trputs(char *s)
{
if (tracefile == NULL)
return;
fputs(s, tracefile);
if (strchr(s, '\n'))
fflush(tracefile);
#endif
}
trstring(s)
char *s;
{
register char *p;
static void
trstring(char *s)
{
char *p;
char c;
#if DEBUG
if (tracefile == NULL)
return;
putc('"', tracefile);
@@ -324,14 +351,12 @@ backslash: putc('\\', tracefile);
}
}
putc('"', tracefile);
#endif
}
trargs(ap)
char **ap;
{
#if DEBUG
void
trargs(char **ap)
{
if (tracefile == NULL)
return;
while (*ap) {
@@ -342,36 +367,43 @@ trargs(ap)
putc('\n', tracefile);
}
fflush(tracefile);
#endif
}
opentrace() {
void
opentrace(void)
{
char s[100];
char *p;
char *getenv();
int flags;
#if DEBUG
if (!debug)
return;
if ((p = getenv("HOME")) == NULL) {
if (getuid() == 0)
p = "/";
else
p = "/tmp";
#ifdef not_this_way
{
char *p;
if ((p = getenv("HOME")) == NULL) {
if (geteuid() == 0)
p = "/";
else
p = "/tmp";
}
scopy(p, s);
strcat(s, "/trace");
}
scopy(p, s);
strcat(s, "/trace");
#else
scopy("./trace", s);
#endif /* not_this_way */
if ((tracefile = fopen(s, "a")) == NULL) {
fprintf(stderr, "Can't open %s\n", s);
fprintf(stderr, "Can't open %s: %s\n", s, strerror(errno));
return;
}
#ifdef O_APPEND
if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
#endif
fputs("\nTracing started.\n", tracefile);
fflush(tracefile);
#endif
}
#endif /* DEBUG */
/*
* $PchId: show.c,v 1.6 2006/05/22 12:27:51 philip Exp $
*/

42
commands/ash/show.h Normal file
View File

@@ -0,0 +1,42 @@
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)show.h 1.1 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/show.h,v 1.11 2004/04/06 20:06:51 markm Exp $
*/
#ifdef DEBUG
void sh_trace(const char *, ...);
void trargs(char **);
void trputs(char *);
void opentrace(void);
#endif
/*
* $PchId: show.h,v 1.4 2006/03/29 13:28:45 philip Exp $
*/

View File

@@ -1,15 +0,0 @@
/* Replacement for something BSD has in sys/cdefs.h. */
#ifndef _ASH_SYS_CDEFS
#define _ASH_SYS_CDEFS
#if __STDC__
#define __P(params) params
#else
#define __P(params) ()
#endif
/* Probably in sys/types.h. */
typedef void (*sig_t) __P(( int ));
#endif /* _ASH_SYS_CDEFS */

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,25 +31,45 @@
*/
#ifndef lint
static char sccsid[] = "@(#)trap.c 5.2 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/trap.c,v 1.29 2004/04/06 20:06:51 markm Exp $");
*/
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#include "main.h"
#include "nodes.h" /* for other headers */
#include "eval.h"
#include "jobs.h"
#include "show.h"
#include "options.h"
#include "syntax.h"
#include "signames.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "trap.h"
#include "mystring.h"
#include <sys/types.h>
#include <signal.h>
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
#include "builtins.h"
#ifdef __minix
#define NO_SIGINTERRUPT
#define NO_SYS_SIGNAME
#define NO_SYS_SIGLIST
#endif
typedef void (*sig_T)(int);
/*
* Sigmode records the current value of the signal handlers for the various
@@ -64,40 +80,130 @@ static char sccsid[] = "@(#)trap.c 5.2 (Berkeley) 4/12/91";
#define S_DFL 1 /* default signal handling (SIG_DFL) */
#define S_CATCH 2 /* signal is caught */
#define S_IGN 3 /* signal is ignored (SIG_IGN) */
#define S_HARD_IGN 4 /* signal is ignored permenantly */
#define S_HARD_IGN 4 /* signal is ignored permanently */
#define S_RESET 5 /* temporary - to reset a hard ignored sig */
extern char nullstr[1]; /* null string */
MKINIT char sigmode[_NSIG]; /* current value of signal */
int pendingsigs; /* indicates some signal received */
int is_interactive= -1; /* Shell is interactive */
int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[_NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[_NSIG];
/* indicates specified signal received */
static int ignore_sigchld; /* Used while handling SIGCHLD traps. */
volatile sig_atomic_t gotwinch;
static int sigstring_to_signum (char *);
static void printsignals (void);
static int getsigaction(int, sig_T *);
static void onsig (int);
#ifdef NO_SIGINTERRUPT
static int siginterrupt (int,int);
#endif
static char *strsigname (int);
/*
* Map a string to a signal number.
*/
static int
sigstring_to_signum(char *sig)
{
if (is_number(sig)) {
int signo;
signo = atoi(sig);
return ((signo >= 0 && signo < _NSIG) ? signo : (-1));
} else if (strcasecmp(sig, "exit") == 0) {
return (0);
} else {
int n;
if (strncasecmp(sig, "sig", 3) == 0)
sig += 3;
for (n = 1; n < _NSIG; n++)
if (strcasecmp(strsigname(n), sig) == 0)
return (n);
}
return (-1);
}
/*
* Print a list of valid signal names.
*/
static void
printsignals(void)
{
int n, outlen;
outlen = 0;
for (n = 1; n < _NSIG; n++) {
if (strsigname(n)) {
out1fmt("%s", strsigname(n));
outlen += strlen(strsigname(n));
} else {
out1fmt("%d", n);
outlen += 3; /* good enough */
}
++outlen;
if (outlen > 70 || n == _NSIG - 1) {
out1str("\n");
outlen = 0;
} else {
out1c(' ');
}
}
}
char *trap[MAXSIG+1]; /* trap handler commands */
MKINIT char sigmode[MAXSIG]; /* current value of signal */
char gotsig[MAXSIG]; /* indicates specified signal received */
int pendingsigs; /* indicates some signal received */
/*
* The trap builtin.
*/
trapcmd(argc, argv) char **argv; {
int
trapcmd(int argc, char **argv)
{
char *action;
char **ap;
int signo;
if (argc <= 1) {
for (signo = 0 ; signo <= MAXSIG ; signo++) {
if (trap[signo] != NULL)
out1fmt("%d: %s\n", signo, trap[signo]);
for (signo = 0 ; signo < _NSIG ; signo++) {
if (trap[signo] != NULL) {
if (signo == 0) {
out1fmt("trap -- '%s' %s\n",
trap[signo], "exit");
} else if (strsigname(signo)) {
out1fmt("trap -- '%s' %s\n",
trap[signo], strsigname(signo));
} else {
out1fmt("trap -- '%s' %d\n",
trap[signo], signo);
}
}
}
return 0;
}
ap = argv + 1;
if (is_number(*ap))
action = NULL;
else
action = *ap++;
while (*ap) {
if ((signo = number(*ap)) < 0 || signo > MAXSIG)
error("%s: bad trap", *ap);
action = NULL;
if (*++argv && strcmp(*argv, "--") == 0)
argv++;
if (*argv && sigstring_to_signum(*argv) == -1) {
if ((*argv)[0] != '-') {
action = *argv;
argv++;
} else if ((*argv)[1] == '\0') {
argv++;
} else if ((*argv)[1] == 'l' && (*argv)[2] == '\0') {
printsignals();
return 0;
} else {
error("bad option %s", *argv);
}
}
while (*argv) {
if ((signo = sigstring_to_signum(*argv)) == -1)
error("bad signal %s", *argv);
INTOFF;
if (action)
action = savestr(action);
@@ -107,22 +213,21 @@ trapcmd(argc, argv) char **argv; {
if (signo != 0)
setsignal(signo);
INTON;
ap++;
argv++;
}
return 0;
}
/*
* Clear traps on a fork.
*/
void
clear_traps() {
char **tp;
clear_traps(void)
{
char *volatile *tp;
for (tp = trap ; tp <= &trap[MAXSIG] ; tp++) {
for (tp = trap ; tp <= &trap[_NSIG - 1] ; tp++) {
if (*tp && **tp) { /* trap not NULL or SIG_IGN */
INTOFF;
ckfree(*tp);
@@ -135,18 +240,16 @@ clear_traps() {
}
/*
* Set the signal handler for the specified signal. The routine figures
* out what it should be set to.
*/
int
setsignal(signo) {
void
setsignal(int signo)
{
int action;
sig_t sigact;
sig_T sig, sigact = SIG_DFL;
char *t;
extern void onsig();
if ((t = trap[signo]) == NULL)
action = S_DFL;
@@ -154,11 +257,10 @@ setsignal(signo) {
action = S_CATCH;
else
action = S_IGN;
if (rootshell && action == S_DFL) {
if (action == S_DFL) {
switch (signo) {
case SIGINT:
if (iflag)
action = S_CATCH;
action = S_CATCH;
break;
case SIGQUIT:
#if DEBUG
@@ -169,68 +271,103 @@ setsignal(signo) {
break;
}
#endif
/* FALLTHROUGH */
action = S_CATCH;
break;
case SIGTERM:
if (iflag)
if (rootshell && iflag)
action = S_IGN;
break;
#if JOBS
case SIGTSTP:
case SIGTTOU:
if (jflag)
if (rootshell && mflag)
action = S_IGN;
break;
#endif
#ifndef NO_HISTORY
case SIGWINCH:
if (rootshell && iflag)
action = S_CATCH;
break;
#endif
}
}
t = &sigmode[signo - 1];
if (*t == 0) { /* current setting unknown */
t = &sigmode[signo];
if (*t == 0) {
/*
* There is a race condition here if action is not S_IGN.
* A signal can be ignored that shouldn't be.
* current setting unknown
*/
if ((int)(sigact = signal(signo, SIG_IGN)) == -1)
error("Signal system call failed");
if (!getsigaction(signo, &sigact)) {
/*
* Pretend it worked; maybe we should give a warning
* here, but other shells don't. We don't alter
* sigmode, so that we retry every time.
*/
return;
}
if (sigact == SIG_IGN) {
*t = S_HARD_IGN;
if (mflag && (signo == SIGTSTP ||
signo == SIGTTIN || signo == SIGTTOU)) {
*t = S_IGN; /* don't hard ignore these */
} else
*t = S_HARD_IGN;
} else {
*t = S_IGN;
*t = S_RESET; /* force to be set */
}
}
if (*t == S_HARD_IGN || *t == action)
return 0;
return;
switch (action) {
case S_DFL: sigact = SIG_DFL; break;
case S_CATCH: sigact = onsig; break;
case S_IGN: sigact = SIG_IGN; break;
}
*t = action;
return (int)signal(signo, sigact);
sig = signal(signo, sigact);
if (sig != SIG_ERR && action == S_CATCH)
siginterrupt(signo, 1);
}
/*
* Return the current setting for sig w/o changing it.
*/
static int
getsigaction(int signo, sig_T *sigact)
{
struct sigaction sa;
if (sigaction(signo, (struct sigaction *)0, &sa) == -1)
return 0;
*sigact = (sig_T) sa.sa_handler;
return 1;
}
/*
* Ignore a signal.
*/
void
ignoresig(signo) {
if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
ignoresig(int signo)
{
if (sigmode[signo] != S_IGN && sigmode[signo] != S_HARD_IGN) {
signal(signo, SIG_IGN);
}
sigmode[signo - 1] = S_HARD_IGN;
sigmode[signo] = S_HARD_IGN;
}
#ifdef mkinit
INCLUDE "signames.h"
INCLUDE <signal.h>
INCLUDE "trap.h"
SHELLPROC {
char *sm;
clear_traps();
for (sm = sigmode ; sm < sigmode + MAXSIG ; sm++) {
for (sm = sigmode ; sm < sigmode + _NSIG ; sm++) {
if (*sm == S_IGN)
*sm = S_HARD_IGN;
}
@@ -238,82 +375,119 @@ SHELLPROC {
#endif
/*
* Signal handler.
*/
static void
onsig(int signo)
{
void
onsig(signo) {
#ifndef BSD
signal(signo, onsig);
#endif
if (signo == SIGINT && trap[SIGINT] == NULL) {
onint();
return;
}
gotsig[signo - 1] = 1;
pendingsigs++;
}
if (signo != SIGCHLD || !ignore_sigchld)
gotsig[signo] = 1;
pendingsigs++;
/* If we are currently in a wait builtin, prepare to break it */
if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
breakwaitcmd = 1;
/*
* If a trap is set, not ignored and not the null command, we need
* to make sure traps are executed even when a child blocks signals.
*/
if (Tflag &&
trap[signo] != NULL &&
! trap[signo][0] == '\0' &&
! (trap[signo][0] == ':' && trap[signo][1] == '\0'))
breakwaitcmd = 1;
#ifndef NO_HISTORY
if (signo == SIGWINCH)
gotwinch = 1;
#endif
}
/*
* Called to execute a trap. Perhaps we should avoid entering new trap
* handlers while we are executing a trap handler.
*/
void
dotrap() {
dotrap(void)
{
int i;
int savestatus;
in_dotrap++;
for (;;) {
for (i = 1 ; ; i++) {
if (gotsig[i - 1])
for (i = 1; i < _NSIG; i++) {
if (gotsig[i]) {
gotsig[i] = 0;
if (trap[i]) {
/*
* Ignore SIGCHLD to avoid infinite
* recursion if the trap action does
* a fork.
*/
if (i == SIGCHLD)
ignore_sigchld++;
savestatus = exitstatus;
evalstring(trap[i]);
exitstatus = savestatus;
if (i == SIGCHLD)
ignore_sigchld--;
}
break;
if (i >= MAXSIG)
goto done;
}
}
gotsig[i - 1] = 0;
savestatus=exitstatus;
evalstring(trap[i]);
exitstatus=savestatus;
if (i >= _NSIG)
break;
}
done:
in_dotrap--;
pendingsigs = 0;
}
/*
* Controls whether the shell is interactive or not.
*/
int is_interactive;
void
setinteractive(on) {
setinteractive(int on)
{
if (on == is_interactive)
return;
setsignal(SIGINT);
setsignal(SIGQUIT);
setsignal(SIGTERM);
#ifndef NO_HISTORY
setsignal(SIGWINCH);
#endif
is_interactive = on;
}
/*
* Called to exit the shell.
*/
void
exitshell(status) {
exitshell(int status)
{
struct jmploc loc1, loc2;
char *p;
TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
if (setjmp(loc1.loc)) goto l1;
if (setjmp(loc2.loc)) goto l2;
if (setjmp(loc1.loc)) {
goto l1;
}
if (setjmp(loc2.loc)) {
goto l2;
}
handler = &loc1;
if ((p = trap[0]) != NULL && *p != '\0') {
trap[0] = NULL;
@@ -326,3 +500,85 @@ l1: handler = &loc2; /* probably unnecessary */
#endif
l2: _exit(status);
}
#ifdef NO_SIGINTERRUPT
static int siginterrupt(sig, flag)
int sig;
int flag;
{
return 0;
}
#endif
#ifdef NO_SYS_SIGNAME
static char *strsigname(sig)
int sig;
{
switch(sig)
{
case 0: return "Signal 0"; /* 0 */
case SIGHUP: return "hup"; /* 1 */
case SIGINT: return "int"; /* 2 */
case SIGQUIT: return "quit"; /* 3 */
case SIGILL: return "ill"; /* 4 */
case SIGTRAP: return "trap"; /* 5 */
case SIGABRT: return "abrt"; /* 6 */
#ifdef __minix_vmd
case SIGEMT: return "emt"; /* 7 */
#else
case SIGBUS: return "bus"; /* 7 */
#endif
case SIGFPE: return "fpe"; /* 8 */
case SIGKILL: return "kill"; /* 9 */
case SIGUSR1: return "usr1"; /* 10 */
case SIGSEGV: return "segv"; /* 11 */
case SIGUSR2: return "usr2"; /* 12 */
case SIGPIPE: return "pipe"; /* 13 */
case SIGALRM: return "alrm"; /* 14 */
case SIGTERM: return "term"; /* 15 */
#ifdef __minix_vmd
case 16: return "Signal 16"; /* 16 */
#else
case SIGEMT: return "emt"; /* 16 */
#endif
case SIGCHLD: return "chld"; /* 17 */
case SIGCONT: return "cont"; /* 18 */
case SIGSTOP: return "stop"; /* 19 */
case SIGTSTP: return "tstp"; /* 20 */
case SIGTTIN: return "ttin"; /* 21 */
case SIGTTOU: return "ttou"; /* 22 */
case SIGWINCH: return "winch"; /* 23 */
#ifdef __minix_vmd
case SIGFPEMU: return "fpemu"; /* 30 */
#endif
default: return "Signal n";
}
}
#else
static char *strsigname(sig)
int sig;
{
return sys_signame[sig];
}
#endif
#ifdef NO_SYS_SIGLIST
#include "signames.h"
char *strsiglist(sig)
int sig;
{
if (sig > MAXSIG)
return NULL;
return sigmesg[sig];
}
#else
char *strsiglist(sig)
int sig;
{
return sys_siglist[sig];
}
#endif
/*
* $PchId: trap.c,v 1.7 2006/05/23 11:56:21 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,23 +29,24 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)trap.h 5.1 (Berkeley) 3/7/91
* @(#)trap.h 8.3 (Berkeley) 6/5/95
* $FreeBSD: src/bin/sh/trap.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
extern int pendingsigs;
extern int in_dotrap;
extern int is_interactive;
extern volatile sig_atomic_t gotwinch;
#ifdef __STDC__
int trapcmd(int, char **);
void clear_traps(void);
int setsignal(int);
void setsignal(int);
void ignoresig(int);
void dotrap(void);
void setinteractive(int);
void exitshell(int);
#else
void clear_traps();
int setsignal();
void ignoresig();
void dotrap();
void setinteractive();
void exitshell();
#endif
char *strsiglist(int);
/*
* $PchId: trap.h,v 1.6 2006/05/22 12:48:30 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,13 +31,27 @@
*/
#ifndef lint
static char sccsid[] = "@(#)var.c 5.3 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/var.c,v 1.26.2.1 2004/09/30 04:41:55 des Exp $");
*/
#include <unistd.h>
#include <stdlib.h>
#ifndef NO_PATHS_H
#include <paths.h>
#endif
/*
* Shell variables.
*/
#include <locale.h>
#include "shell.h"
#include "output.h"
#include "expand.h"
@@ -55,7 +65,16 @@ static char sccsid[] = "@(#)var.c 5.3 (Berkeley) 4/12/91";
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "parser.h"
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
#include "builtins.h"
#ifndef _PATH_DEFPATH
#define _PATH_DEFPATH "/usr/bin:/bin"
#endif
#define VTABSIZE 39
@@ -64,48 +83,57 @@ struct varinit {
struct var *var;
int flags;
char *text;
void (*func)(const char *);
};
#if ATTY
struct var vatty;
#ifndef NO_HISTORY
struct var vhistsize;
#endif
struct var vifs;
struct var vmail;
struct var vmpath;
struct var vpath;
struct var vppid;
struct var vps1;
struct var vps2;
struct var vpse;
struct var vvers;
#if ATTY
struct var vterm;
#endif
STATIC struct var voptind;
const struct varinit varinit[] = {
#if ATTY
{&vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY="},
STATIC const struct varinit varinit[] = {
#if !defined(NO_HISTORY) && !defined(EDITLINE)
{ &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=",
sethistsize },
#endif
{&vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n"},
{&vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL="},
{&vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH="},
{&vpath, VSTRFIXED|VTEXTFIXED, "PATH=:/bin:/usr/bin"},
/*
{ &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n",
NULL },
{ &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=",
NULL },
{ &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=",
NULL },
{ &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH,
changepath },
{ &vppid, VSTRFIXED|VTEXTFIXED|VUNSET, "PPID=",
NULL },
/*
* vps1 depends on uid
*/
{&vps2, VSTRFIXED|VTEXTFIXED, "PS2=> "},
{&vpse, VSTRFIXED|VTEXTFIXED, "PSE=* "},
#if ATTY
{&vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM="},
#endif
{NULL, 0, NULL}
{ &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
NULL },
{ &vpse, VSTRFIXED|VTEXTFIXED|VUNSET, "PSE=",
NULL },
{ &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
getoptsreset },
{ NULL, 0, NULL,
NULL }
};
struct var *vartab[VTABSIZE];
STATIC struct var *vartab[VTABSIZE];
STATIC void unsetvar __P((char *));
STATIC struct var **hashvar __P((char *));
STATIC int varequal __P((char *, char *));
STATIC struct var **hashvar(char *);
STATIC int varequal(char *, char *);
STATIC int localevar(char *);
/*
* Initialize the varable symbol tables and import the environment
@@ -133,7 +161,9 @@ INIT {
*/
void
initvar() {
initvar(void)
{
char ppid[20];
const struct varinit *ip;
struct var *vp;
struct var **vpp;
@@ -145,6 +175,7 @@ initvar() {
*vpp = vp;
vp->text = ip->text;
vp->flags = ip->flags;
vp->func = ip->func;
}
}
/*
@@ -154,20 +185,48 @@ initvar() {
vpp = hashvar("PS1=");
vps1.next = *vpp;
*vpp = &vps1;
vps1.text = getuid() ? "PS1=$ " : "PS1=# ";
vps1.text = geteuid() ? "PS1=$ " : "PS1=# ";
vps1.flags = VSTRFIXED|VTEXTFIXED;
}
if ((vppid.flags & VEXPORT) == 0) {
fmtstr(ppid, sizeof(ppid), "%d", (int)getppid());
setvarsafe("PPID", ppid, 0);
}
}
/*
* Set the value of a variable. The flags argument is ored with the
* Safe version of setvar, returns 1 on success 0 on failure.
*/
int
setvarsafe(char *name, char *val, int flags)
{
struct jmploc jmploc;
struct jmploc *volatile savehandler = handler;
int err = 0;
#if __GNUC__
/* Avoid longjmp clobbering */
(void) &err;
#endif
if (setjmp(jmploc.loc))
err = 1;
else {
handler = &jmploc;
setvar(name, val, flags);
}
handler = savehandler;
return err;
}
/*
* Set the value of a variable. The flags argument is tored with the
* flags of the variable. If val is NULL, the variable is unset.
*/
void
setvar(name, val, flags)
char *name, *val;
{
setvar(char *name, char *val, int flags)
{
char *p, *q;
int len;
int namelen;
@@ -176,8 +235,9 @@ setvar(name, val, flags)
isbad = 0;
p = name;
if (! is_name(*p++))
if (! is_name(*p))
isbad = 1;
p++;
for (;;) {
if (! is_in_name(*p)) {
if (*p == '\0' || *p == '=')
@@ -188,7 +248,7 @@ setvar(name, val, flags)
}
namelen = p - name;
if (isbad)
error("%.*s: is read only", namelen, name);
error("%.*s: bad variable name", namelen, name);
len = namelen + 2; /* 2 is space for '=' and '\0' */
if (val == NULL) {
flags |= VUNSET;
@@ -206,7 +266,26 @@ setvar(name, val, flags)
setvareq(nameeq, flags);
}
STATIC int
localevar(char *s)
{
static char *lnames[7] = {
"ALL", "COLLATE", "CTYPE", "MONETARY",
"NUMERIC", "TIME", NULL
};
char **ss;
if (*s != 'L')
return 0;
if (varequal(s + 1, "ANG"))
return 1;
if (strncmp(s + 1, "C_", 2) != 0)
return 0;
for (ss = lnames; *ss ; ss++)
if (varequal(s + 3, *ss))
return 1;
return 0;
}
/*
* Same as setvar except that the variable and value are passed in
@@ -216,28 +295,42 @@ setvar(name, val, flags)
*/
void
setvareq(s, flags)
char *s;
{
setvareq(char *s, int flags)
{
struct var *vp, **vpp;
int len;
if (aflag)
flags |= VEXPORT;
vpp = hashvar(s);
for (vp = *vpp ; vp ; vp = vp->next) {
if (varequal(s, vp->text)) {
if (vp->flags & VREADONLY) {
int len = strchr(s, '=') - s;
len = strchr(s, '=') - s;
error("%.*s: is read only", len, s);
}
INTOFF;
if (vp == &vpath)
changepath(s + 5); /* 5 = strlen("PATH=") */
if (vp->func && (flags & VNOFUNC) == 0)
(*vp->func)(strchr(s, '=') + 1);
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
ckfree(vp->text);
vp->flags &=~ (VTEXTFIXED|VSTACK|VUNSET);
vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
vp->flags |= flags;
vp->text = s;
/*
* We could roll this to a function, to handle it as
* a regular variable function callback, but why bother?
*/
if (vp == &vmpath || (vp == &vmail && ! mpathset()))
chkmail(1);
if ((vp->flags & VEXPORT) && localevar(s)) {
putenv(s);
(void) setlocale(LC_ALL, "");
}
INTON;
return;
}
@@ -247,7 +340,14 @@ setvareq(s, flags)
vp->flags = flags;
vp->text = s;
vp->next = *vpp;
vp->func = NULL;
INTOFF;
*vpp = vp;
if ((vp->flags & VEXPORT) && localevar(s)) {
putenv(s);
(void) setlocale(LC_ALL, "");
}
INTON;
}
@@ -257,9 +357,8 @@ setvareq(s, flags)
*/
void
listsetvar(list)
struct strlist *list;
{
listsetvar(struct strlist *list)
{
struct strlist *lp;
INTOFF;
@@ -276,9 +375,8 @@ listsetvar(list)
*/
char *
lookupvar(name)
char *name;
{
lookupvar(char *name)
{
struct var *v;
for (v = *hashvar(name) ; v ; v = v->next) {
@@ -300,9 +398,8 @@ lookupvar(name)
*/
char *
bltinlookup(name, doall)
char *name;
{
bltinlookup(char *name, int doall)
{
struct strlist *sp;
struct var *v;
@@ -312,8 +409,8 @@ bltinlookup(name, doall)
}
for (v = *hashvar(name) ; v ; v = v->next) {
if (varequal(v->text, name)) {
if (v->flags & VUNSET
|| ! doall && (v->flags & VEXPORT) == 0)
if ((v->flags & VUNSET)
|| (!doall && (v->flags & VEXPORT) == 0))
return NULL;
return strchr(v->text, '=') + 1;
}
@@ -329,7 +426,8 @@ bltinlookup(name, doall)
*/
char **
environment() {
environment(void)
{
int nenv;
struct var **vpp;
struct var *vp;
@@ -359,15 +457,14 @@ environment() {
*/
#ifdef mkinit
MKINIT void shprocvar();
SHELLPROC {
shprocvar();
}
#endif
void
shprocvar() {
shprocvar(void)
{
struct var **vpp;
struct var *vp, **prev;
@@ -400,14 +497,21 @@ shprocvar() {
*/
int
showvarscmd(argc, argv) char **argv; {
showvarscmd(int argc __unused, char **argv __unused)
{
struct var **vpp;
struct var *vp;
const char *s;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next) {
if ((vp->flags & VUNSET) == 0)
out1fmt("%s\n", vp->text);
if (vp->flags & VUNSET)
continue;
for (s = vp->text; *s != '='; s++)
out1c(*s);
out1c('=');
out1qstr(s + 1);
out1c('\n');
}
}
return 0;
@@ -420,15 +524,35 @@ showvarscmd(argc, argv) char **argv; {
*/
int
exportcmd(argc, argv) char **argv; {
exportcmd(int argc, char **argv)
{
struct var **vpp;
struct var *vp;
char *name;
char *p;
char *cmdname;
int ch, values;
int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
cmdname = argv[0];
optreset = optind = 1;
opterr = 0;
values = 0;
while ((ch = getopt(argc, argv, "p")) != -1) {
switch (ch) {
case 'p':
values = 1;
break;
case '?':
default:
error("unknown option: -%c", optopt);
}
}
argc -= optind;
argv += optind;
listsetvar(cmdenviron);
if (argc > 1) {
if (argc != 0) {
while ((name = *argptr++) != NULL) {
if ((p = strchr(name, '=')) != NULL) {
p++;
@@ -436,7 +560,12 @@ exportcmd(argc, argv) char **argv; {
vpp = hashvar(name);
for (vp = *vpp ; vp ; vp = vp->next) {
if (varequal(vp->text, name)) {
vp->flags |= flag;
if ((vp->flags & VEXPORT) && localevar(vp->text)) {
putenv(vp->text);
(void) setlocale(LC_ALL, "");
}
goto found;
}
}
@@ -448,8 +577,16 @@ found:;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next) {
if (vp->flags & flag) {
if (values) {
out1str(cmdname);
out1c(' ');
}
for (p = vp->text ; *p != '=' ; p++)
out1c(*p);
if (values && !(vp->flags & VUNSET)) {
out1c('=');
out1qstr(p + 1);
}
out1c('\n');
}
}
@@ -463,7 +600,9 @@ found:;
* The "local" command.
*/
localcmd(argc, argv) char **argv; {
int
localcmd(int argc __unused, char **argv __unused)
{
char *name;
if (! in_function())
@@ -483,9 +622,8 @@ localcmd(argc, argv) char **argv; {
*/
void
mklocal(name)
char *name;
{
mklocal(char *name)
{
struct localvar *lvp;
struct var **vpp;
struct var *vp;
@@ -493,8 +631,8 @@ mklocal(name)
INTOFF;
lvp = ckmalloc(sizeof (struct localvar));
if (name[0] == '-' && name[1] == '\0') {
lvp->text = ckmalloc(sizeof optval);
bcopy(optval, lvp->text, sizeof optval);
lvp->text = ckmalloc(sizeof optlist);
memcpy(lvp->text, optlist, sizeof optlist);
vp = NULL;
} else {
vpp = hashvar(name);
@@ -527,7 +665,8 @@ mklocal(name)
*/
void
poplocalvars() {
poplocalvars(void)
{
struct localvar *lvp;
struct var *vp;
@@ -535,10 +674,10 @@ poplocalvars() {
localvars = lvp->next;
vp = lvp->vp;
if (vp == NULL) { /* $- saved */
bcopy(lvp->text, optval, sizeof optval);
memcpy(optlist, lvp->text, sizeof optlist);
ckfree(lvp->text);
} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
unsetvar(vp->text);
(void)unsetvar(vp->text);
} else {
if ((vp->flags & VTEXTFIXED) == 0)
ckfree(vp->text);
@@ -550,7 +689,9 @@ poplocalvars() {
}
setvarcmd(argc, argv) char **argv; {
int
setvarcmd(int argc, char **argv)
{
if (argc <= 2)
return unsetcmd(argc, argv);
else if (argc == 3)
@@ -567,14 +708,31 @@ setvarcmd(argc, argv) char **argv; {
* with the same name.
*/
unsetcmd(argc, argv) char **argv; {
int
unsetcmd(int argc __unused, char **argv __unused)
{
char **ap;
int i;
int flg_func = 0;
int flg_var = 0;
int ret = 0;
for (ap = argv + 1 ; *ap ; ap++) {
unsetfunc(*ap);
unsetvar(*ap);
while ((i = nextopt("vf")) != '\0') {
if (i == 'f')
flg_func = 1;
else
flg_var = 1;
}
return 0;
if (flg_func == 0 && flg_var == 0)
flg_var = 1;
for (ap = argptr; *ap ; ap++) {
if (flg_func)
ret |= unsetfunc(*ap);
if (flg_var)
ret |= unsetvar(*ap);
}
return ret;
}
@@ -582,22 +740,25 @@ unsetcmd(argc, argv) char **argv; {
* Unset the specified variable.
*/
STATIC void
unsetvar(s)
char *s;
{
int
unsetvar(char *s)
{
struct var **vpp;
struct var *vp;
vpp = hashvar(s);
for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
if (varequal(vp->text, s)) {
if (vp->flags & VREADONLY)
return (1);
INTOFF;
if (*(strchr(vp->text, '=') + 1) != '\0'
|| vp->flags & VREADONLY) {
if (*(strchr(vp->text, '=') + 1) != '\0')
setvar(s, nullstr, 0);
if ((vp->flags & VEXPORT) && localevar(vp->text)) {
unsetenv(s);
setlocale(LC_ALL, "");
}
vp->flags &=~ VEXPORT;
vp->flags &= ~VEXPORT;
vp->flags |= VUNSET;
if ((vp->flags & VSTRFIXED) == 0) {
if ((vp->flags & VTEXTFIXED) == 0)
@@ -606,9 +767,11 @@ unsetvar(s)
ckfree(vp);
}
INTON;
return;
return (0);
}
}
return (0);
}
@@ -618,14 +781,13 @@ unsetvar(s)
*/
STATIC struct var **
hashvar(p)
register char *p;
{
hashvar(char *p)
{
unsigned int hashval;
hashval = *p << 4;
hashval = ((unsigned char) *p) << 4;
while (*p && *p != '=')
hashval += *p++;
hashval += (unsigned char) *p++;
return &vartab[hashval % VTABSIZE];
}
@@ -638,9 +800,8 @@ hashvar(p)
*/
STATIC int
varequal(p, q)
register char *p, *q;
{
varequal(char *p, char *q)
{
while (*p == *q++) {
if (*p++ == '=')
return 1;
@@ -649,3 +810,7 @@ varequal(p, q)
return 1;
return 0;
}
/*
* $PchId: var.c,v 1.5 2006/05/22 12:28:49 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)var.h 5.1 (Berkeley) 3/7/91
* @(#)var.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/var.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
/*
@@ -41,43 +38,45 @@
*/
/* flags */
#define VEXPORT 01 /* variable is exported */
#define VREADONLY 02 /* variable cannot be modified */
#define VSTRFIXED 04 /* variable struct is staticly allocated */
#define VTEXTFIXED 010 /* text is staticly allocated */
#define VSTACK 020 /* text is allocated on the stack */
#define VUNSET 040 /* the variable is not set */
#define VEXPORT 0x01 /* variable is exported */
#define VREADONLY 0x02 /* variable cannot be modified */
#define VSTRFIXED 0x04 /* variable struct is staticly allocated */
#define VTEXTFIXED 0x08 /* text is staticly allocated */
#define VSTACK 0x10 /* text is allocated on the stack */
#define VUNSET 0x20 /* the variable is not set */
#define VNOFUNC 0x40 /* don't call the callback function */
struct var {
struct var *next; /* next entry in hash list */
int flags; /* flags are defined above */
char *text; /* name=value */
int flags; /* flags are defined above */
char *text; /* name=value */
void (*func)(const char *);
/* function to be called when */
/* the variable gets set/unset */
};
struct localvar {
struct localvar *next; /* next local variable in list */
struct var *vp; /* the variable that was made local */
int flags; /* saved flags */
char *text; /* saved text */
struct localvar *next; /* next local variable in list */
struct var *vp; /* the variable that was made local */
int flags; /* saved flags */
char *text; /* saved text */
};
struct localvar *localvars;
#if ATTY
extern struct var vatty;
#endif
extern struct var vifs;
extern struct var vmail;
extern struct var vmpath;
extern struct var vpath;
extern struct var vppid;
extern struct var vps1;
extern struct var vps2;
extern struct var vpse;
#if ATTY
extern struct var vterm;
#ifndef NO_HISTORY
extern struct var vhistsize;
#endif
/*
@@ -87,43 +86,39 @@ extern struct var vterm;
*/
#define ifsval() (vifs.text + 4)
#define ifsset() ((vifs.flags & VUNSET) == 0)
#define mailval() (vmail.text + 5)
#define mpathval() (vmpath.text + 9)
#define pathval() (vpath.text + 5)
#define ps1val() (vps1.text + 4)
#define ps2val() (vps2.text + 4)
#define pseval() (vpse.text + 4)
#if ATTY
#define termval() (vterm.text + 5)
#define optindval() (voptind.text + 7)
#ifndef NO_HISTORY
#define histsizeval() (vhistsize.text + 9)
#endif
#if ATTY
#define attyset() ((vatty.flags & VUNSET) == 0)
#endif
#define mpathset() ((vmpath.flags & VUNSET) == 0)
#ifdef __STDC__
void initvar();
void initvar(void);
void setvar(char *, char *, int);
void setvareq(char *, int);
struct strlist;
void listsetvar(struct strlist *);
char *lookupvar(char *);
char *bltinlookup(char *, int);
char **environment();
char **environment(void);
void shprocvar(void);
int showvarscmd(int, char **);
int exportcmd(int, char **);
int localcmd(int, char **);
void mklocal(char *);
void poplocalvars(void);
#else
void initvar();
void setvar();
void setvareq();
void listsetvar();
char *lookupvar();
char *bltinlookup();
char **environment();
int showvarscmd();
void mklocal();
void poplocalvars();
#endif
int setvarcmd(int, char **);
int unsetcmd(int, char **);
int unsetvar(char *);
int setvarsafe(char *, char *, int);
/*
* $PchId: var.h,v 1.4 2006/03/29 12:04:45 philip Exp $
*/

View File

@@ -1,38 +0,0 @@
a small AWK clone
このプログラムは、Minix 1.2 用に書いたものです。浮動小数点演算を使い
ますから、Minix 1.5 以前の ACK-C ではコンパイルできません。そのため makefile
では、Peter S. Houselさんの浮動小数点パッケージを使うようになっています。
CFLAGS の -f が、その指示です。この浮動小数点パッケージは、非常によくできて
いますが、atan(x, y) の引き数の順序が逆になっていますので、修正しておいてく
ださい。他にも何かあったような記憶がありますが、忘れてしまいました。もし、何
か問題があるようでしたら、ご連絡いただければ、私が自分で使っているものを公表
するようにします。
このプログラムは、Shift-JIS の漢字コードを扱うようになっています。
EUC に対応させる場合は、正規表現の扱い等、漢字コードに関係する部分の書換が必
要ですが、大した手間ではありません。どなたか変更された場合は、パッチを用意し
ていただけると嬉しいです。
当初は、昔の awk の仕様になっていましたが、「AWK Programming Language」
が出版され、POSIX 1003.2 の draft でも nawk 仕様が採用されたのを機会に、nawk
の仕様に書き換えました。オリジナルの awk と違って、parser も lexical analizer
も hand maid ですから、64K+64K のメモリに収まっています。
本来は、Minix らしい、教材的なプログラムにすべきですし、そうしたかっ
たのですが、もともと、自分たちが使うために、メモもとらずにスクリーンを見なが
ら書いてしまったため、きれいなコーディングになっていません。しかし、64K+64K
のメモリで使える awk が他にありませんので、とりあえず現行の状態で公開しておく
ことにしました。
プログラムそのものは、正規表現の評価順序に依存するものを除いて、「AWK
Programming Language」に掲載されているテストプログラムに通ることを確認してあ
ります。
32-bit Minix の場合は、AT&T オジナルの awk とか gawk, mawk といった
プログラムが使えますが、浮動小数点をサポートした、c386 でこのプログラムをコ
ンパイルすることもできます。
平林 浩一 (kh@hiraide.mogami-wire.co.jp) 1995-01-29

View File

@@ -12,7 +12,7 @@ BIGFILES=#-D_FILE_OFFSET_BITS=64
CFLAGS=-Wall -Winline -O -g $(BIGFILES) -Dlstat=stat -D_POSIX_SOURCE=1
# Where you want it installed when you do 'make install'
PREFIX=/usr/local
PREFIX=/usr
PREFIX_BIN=$(PREFIX)/bin
PREFIX_LIB=$(PREFIX)/lib
PREFIX_MAN=$(PREFIX)/man

View File

@@ -27,9 +27,9 @@
#include <minix/const.h>
#include <minix/type.h>
#include "../../servers/fs/const.h"
#include "../../servers/fs/type.h"
#include "../../servers/fs/inode.h"
#include "../../servers/mfs/const.h"
#include "../../servers/mfs/type.h"
#include "../../servers/mfs/inode.h"
#include "de.h"

View File

@@ -18,10 +18,10 @@
#include <minix/const.h>
#include <minix/type.h>
#include "../../servers/fs/const.h"
#include "../../servers/fs/type.h"
#include "../../servers/fs/super.h"
#include "../../servers/fs/inode.h"
#include "../../servers/mfs/const.h"
#include "../../servers/mfs/type.h"
#include "../../servers/mfs/super.h"
#include "../../servers/mfs/inode.h"
#include <minix/fslib.h>
#include "de.h"

View File

@@ -23,9 +23,9 @@
#include <minix/const.h>
#include <minix/type.h>
#include "../../servers/fs/const.h"
#include "../../servers/fs/type.h"
#include "../../servers/fs/inode.h"
#include "../../servers/mfs/const.h"
#include "../../servers/mfs/type.h"
#include "../../servers/mfs/inode.h"
#include <minix/fslib.h>
#include "de.h"

View File

@@ -17,8 +17,8 @@
#include <minix/config.h>
#include <minix/const.h>
#include "../../servers/fs/const.h"
#include "../../servers/fs/inode.h"
#include "../../servers/mfs/const.h"
#include "../../servers/mfs/inode.h"
#include "de.h"

View File

@@ -25,9 +25,9 @@
#include <minix/const.h>
#include <minix/type.h>
#include "../../servers/fs/const.h"
#include "../../servers/fs/type.h"
#include "../../servers/fs/inode.h"
#include "../../servers/mfs/const.h"
#include "../../servers/mfs/type.h"
#include "../../servers/mfs/inode.h"
#include <minix/fslib.h>
#include "de.h"

View File

@@ -173,12 +173,14 @@ int opendev(network_t *np, fdtype_t fdtype, int compete)
switch (fdtype) {
case FT_ETHERNET:
/* Set NONBLOCK to avoid waiting for a device driver to become ready */
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) | O_NONBLOCK);
if (ioctl(np->fdp->fd, NWIOGETHSTAT, &ethstat) < 0) {
/* Not an Ethernet. */
close(fdp->fd);
return 0;
}
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) & ~O_NONBLOCK);
np->eth= ethstat.nwes_addr;
ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD
| NWEO_REMANY | NWEO_TYPEANY | NWEO_RWDATALL;

View File

@@ -8,6 +8,8 @@
* routine is TS_INP for detection of TTY input.
*/
#define _MINIX 1
#include "elle.h"
#if !(V6)
@@ -21,6 +23,7 @@ int tsf_pause = 0; /* Set if ts_pause works. Ref'd by equit in e_main */
#if !(SYSV || BBN) /* SYSV and BBN have weird tty calls */
#if MINIX
#include <sys/ioctl.h>
#include <termios.h>
struct termios origterm, newterm;
#else

View File

@@ -3,7 +3,9 @@
#endif
/* sbbcpy.c */
#ifndef _MINIX
_PROTOTYPE( int bcopy, (SBMA from, SBMA to, unsigned cnt) );
#endif
_PROTOTYPE( int sbm_wcpy, (int *from, int *to, unsigned cnt) );
/* sberr.c */

View File

@@ -61,6 +61,7 @@ elvprsv: elvprsv.c
install: /usr/bin/elvis \
/bin/elvis \
/usr/bin/vi \
/usr/bin/ctags /usr/bin/ref /usr/bin/fmt \
/usr/bin/elvrec /usr/bin/elvprsv
@@ -70,6 +71,11 @@ install: /usr/bin/elvis \
/bin/elvis: elvis
install -cs -o bin elvis $@
/usr/bin/vi: /usr/bin/elvis
if [ ! -x $@ ]; \
then install -l $? $@ ; \
fi
/usr/bin/ctags: ctags
install -cs -o bin ctags $@

Some files were not shown because too many files have changed in this diff Show More