2012-01-22 17:46:41 -05:00
|
|
|
#include <sys/keycodes.h>
|
|
|
|
#include <sys/termmode.h>
|
2011-08-27 17:03:39 -04:00
|
|
|
#include <stdio.h>
|
2011-11-18 13:29:52 -05:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
2011-11-22 11:26:47 -05:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2011-11-26 05:00:45 -05:00
|
|
|
#include <error.h>
|
2011-08-27 17:03:39 -04:00
|
|
|
|
2012-03-02 12:15:55 -05:00
|
|
|
int docat(const char* inputname, int fd)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
const size_t BUFFER_SIZE = 255;
|
|
|
|
char buffer[BUFFER_SIZE+1];
|
|
|
|
ssize_t bytesread = read(fd, buffer, BUFFER_SIZE);
|
|
|
|
if ( bytesread == 0 ) { break; }
|
|
|
|
if ( bytesread < 0 )
|
|
|
|
{
|
|
|
|
error(0, errno, "read: %s", inputname);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if ( writeall(1, buffer, bytesread) )
|
|
|
|
{
|
|
|
|
error(0, errno, "write: %s", inputname);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} while ( true );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-11-18 13:29:52 -05:00
|
|
|
int cat(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
for ( int i = 1; i < argc; i++ )
|
|
|
|
{
|
|
|
|
int fd = open(argv[i], O_RDONLY);
|
2011-11-22 11:26:47 -05:00
|
|
|
if ( fd < 0 )
|
|
|
|
{
|
2011-11-26 05:00:45 -05:00
|
|
|
error(0, errno, "%s", argv[i]);
|
2011-11-22 11:26:47 -05:00
|
|
|
result = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2012-03-02 12:15:55 -05:00
|
|
|
|
|
|
|
result |= docat(argv[i], fd);
|
2011-11-18 13:29:52 -05:00
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-08-27 17:03:39 -04:00
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2011-11-18 13:29:52 -05:00
|
|
|
if ( 1 < argc )
|
|
|
|
{
|
|
|
|
return cat(argc, argv);
|
|
|
|
}
|
|
|
|
|
2012-03-04 10:49:51 -05:00
|
|
|
if ( !isatty(0) || !isatty(1) ) { return docat("<stdin>", 0); }
|
2012-03-02 12:15:55 -05:00
|
|
|
|
2011-08-27 17:03:39 -04:00
|
|
|
bool lastwasesc = false;
|
|
|
|
|
2012-01-22 17:46:41 -05:00
|
|
|
// TODO: This is just compatibility with how cat worked in early versions of
|
|
|
|
// Sortix. Ideally, this should be removed and just cat the raw stdin.
|
|
|
|
// Read the keyboard input from the user.
|
|
|
|
unsigned termmode = TERMMODE_KBKEY | TERMMODE_UNICODE | TERMMODE_SIGNAL;
|
|
|
|
if ( settermmode(0, termmode) ) { error(1, errno, "settermmode"); }
|
|
|
|
while ( true )
|
2011-08-27 17:03:39 -04:00
|
|
|
{
|
2012-01-22 17:46:41 -05:00
|
|
|
uint32_t codepoint;
|
|
|
|
ssize_t numbytes = read(0, &codepoint, sizeof(codepoint));
|
|
|
|
if ( !numbytes ) { break; }
|
|
|
|
if ( numbytes < 0 ) { break; }
|
|
|
|
int kbkey = KBKEY_DECODE(codepoint);
|
|
|
|
if ( kbkey < 0 ) { continue; }
|
|
|
|
if ( kbkey == KBKEY_UP ) { printf("\e[A"); fflush(stdout); continue; }
|
|
|
|
if ( kbkey == KBKEY_DOWN ) { printf("\e[B"); fflush(stdout); continue; }
|
|
|
|
if ( kbkey == KBKEY_RIGHT ) { printf("\e[C"); fflush(stdout); continue; }
|
|
|
|
if ( kbkey == KBKEY_LEFT ) { printf("\e[D"); fflush(stdout); continue; }
|
|
|
|
if ( kbkey == KBKEY_ESC ) { printf("\e["); fflush(stdout); lastwasesc = true; continue; }
|
|
|
|
if ( kbkey ) { continue; }
|
2011-08-27 17:03:39 -04:00
|
|
|
if ( lastwasesc && codepoint == '[' ) { continue; }
|
2012-01-22 17:46:41 -05:00
|
|
|
|
2011-08-27 17:03:39 -04:00
|
|
|
if ( codepoint >= 0x80 ) { continue; }
|
|
|
|
|
|
|
|
char msg[2]; msg[0] = codepoint; msg[1] = '\0';
|
|
|
|
printf(msg);
|
Implemented large parts of the stdio(3), including fprintf.
Made FILE an interface to various backends. This allows application writers
to override the standard FILE API functions with their own backends. This
is highly unportable - it'd be nice if a real standard existed for this.
glibc already does something like this internally, but AFAIK you can't hook
into it.
Added fdopen(3), fopen(3), fregister(3), funregister(3), fread(3),
fwrite(3), fseek(3), clearerr(3), ferror(3), feof(3), rewind(3), ftell(3),
fflush(3), fclose(3), fileno(3), fnewline(3), fcloseall(3), memset(3),
stdio(3), vfprintf(3), fprintf(3), and vprintf(3).
Added a file-descriptor backend to the FILE API.
fd's {0, 1, 2} are now initialized as stdin, stdout, and stderr when the
standard library initializes.
fcloseall(3) is now called on exit(3).
decl/intn_t_.h now @include(size_t.h) instead of declaring it itself.
Added <stdint.h>.
The following programs now flush stdout: cat(1), clear(1), editor(1),
init(1), mxsh(1).
printf(3) is now hooked up against vprintf(3), while Maxsi::PrintF
remains using the system call, for now.
2011-12-23 22:08:10 -05:00
|
|
|
fflush(stdout);
|
2011-08-27 17:03:39 -04:00
|
|
|
lastwasesc = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|