Contrary to popular belief and many people's wishes, this is not
a C-related question. (Nor are closely-related questions
concerning the echo of keyboard input.) The delivery of
characters from a "keyboard" to a C program is a function of the
operating system in use, and has not been standardized by the C
language. Some versions of curses have a cbreak() function
which does what you want. If you're specifically trying to read
a short password without echo, you might try getpass()
. Under
Unix, use ioctl
to play with the terminal driver modes (CBREAK
or RAW
under "classic" versions; ICANON
, c_cc[VMIN]
and
c_cc[VTIME]
under System V or Posix systems). Under MS-DOS, use
getch()
. Under VMS, try the Screen Management (SMG$
) routines,
or curses, or issue low-level $QIO
's with the IO$_READVBLK
(and
perhaps IO$M_NOECHO
) function codes to ask for one character at
a time. Under other operating systems, you're on your own.
Beware that some operating systems make this sort of thing
impossible, because character collection into input lines is
done by peripheral processors not under direct control of the
CPU running your program.
Operating system specific questions are not appropriate for comp.lang.c . Many common questions are answered in frequently-asked questions postings in such groups as comp.unix.questions and comp.os.msdos.programmer . Note that the answers are often not unique even across different variants of a system; bear in mind when answering system-specific questions that the answer that applies to your system may not apply to everyone else's.
References: PCS Sec. 10 pp. 128-9, Sec. 10.1 pp. 130-1.
These, too, are entirely operating-system-specific. Some
versions of curses have a nodelay()
function. Depending on your
system, you may also be able to use "nonblocking I/O", or a
system call named "select", or the FIONREAD
ioctl
, or kbhit()
,
or rdchk()
, or the O_NDELAY
option to open()
or fcntl()
.
Such things depend on the terminal type (or display) you're
using. You will have to use a library such as termcap
or
curses
, or some system-specific routines, to perform these
functions.
Consult your system documentation, or ask on an appropriate system-specific newsgroup (but check its FAQ list first). Mouse handling is completely different under the X window system, MS- DOS, Macintosh, and probably every other system.
argv[0]
may contain all or part of the pathname, or it may
contain nothing. You may be able to duplicate the command
language interpreter's search path logic to locate the
executable if the name in argv[0]
is present but incomplete.
However, there is no guaranteed or portable solution.
In general, it cannot. Different operating systems implement name/value functionality similar to the Unix environment in different ways. Whether the "environment" can be usefully altered by a running program, and if so, how, is system-dependent.
Under Unix, a process can modify its own environment (some
systems provide setenv()
and/or putenv()
functions to do this),
and the modified environment is usually passed on to any child
processes, but it is not propagated back to the parent
process.
On Unix-like systems, you can try the access()
routine, although it's got a few
problems. (It isn't atomic with respect to the following
action, and can have anomalies if used in setuid programs.)
Another option (perhaps preferable) is to call
stat()
on the file. Otherwise, the only
guaranteed and portable way to test for file existence is to try
opening the file (which doesn't help if you're trying to avoid
overwriting an existing file, unless you've got something like the
BSD Unix O_EXCL
open
option available).
If the "size of a file" is the number of characters you'll be
able to read from it in C, it is in general impossible to
determine this number in advance. Under Unix, the stat
call
will give you an exact answer, and several other systems supply
a Unix-like stat
which will give an approximate answer. You can
fseek
to the end and then use ftell
, but this usage is
nonportable (it gives you an accurate answer only under Unix,
and otherwise a quasi-accurate answer only for ANSI C "binary"
files). Some systems provide routines called filesize
or
filelength
.
Are you sure you have to determine the file's size in advance? Since the most accurate way of determining the size of a file as a C program will see it is to open the file and read it, perhaps you can rearrange the code to learn the size as it reads.
BSD systems provide ftruncate()
, several others supply chsize()
,
and a few may provide a (possibly undocumented) fcntl
option
F_FREESP
. Under MS-DOS, you can sometimes use write(fd, "", 0)
.
However, there is no truly portable solution.
Unfortunately, there is no portable way. V7 Unix, and derived
systems, provided a fairly useful ftime()
routine with
resolution up to a millisecond, but it has disappeared from
System V and Posix. Other routines you might look for on your
system include nap()
, setitimer()
, msleep()
, usleep()
, clock()
,
and gettimeofday()
. The select()
and poll()
calls (if
available) can be pressed into service to implement simple
delays. On MS-DOS machines, it is possible to reprogram the
system timer and timer interrupts.
You want a dynamic linker and/or loader. It is possible to
malloc
some space and read in object files, but you have to know
an awful lot about object file formats, relocation, etc. Under
BSD Unix, you could use system()
and ld -A
to do the linking for
you. Many (most?) versions of SunOS and System V have the -ldl
library which allows object files to be dynamically loaded.
There is also a GNU package called "dld". See also question
7.6.
Use system()
.
References: K&R II Sec. B6 p. 253; ANSI Sec. 4.10.4.5; H&S Sec. 21.2; PCS Sec. 11 p. 179;
Unix and some other systems provide a popen()
routine, which
sets up a stdio
stream on a pipe connected to the process
running a command, so that the output can be read (or the input
supplied). Alternately, invoke the command simply (see
question 16.12) in such a way that
it writes its output to a file, then open and read that file.
References: PCS Sec. 11 p. 169 .
See if you can use the opendir()
and readdir()
routines, which
are available on most Unix systems. Implementations also exist
for MS-DOS, VMS, and other systems. (MS-DOS also has FINDFIRST
and FINDNEXT
routines which do essentially the same thing.)
It's system-dependent. Under Unix, you typically open, read,
and write a device in /dev
, and use the facilities of the
terminal driver to adjust its characteristics. Under MS-DOS,
you can either use some primitive BIOS interrupts, or (if you
require decent performance) one of any number of interrupt-driven
serial I/O packages.