Skip to content

Commit

Permalink
Fixed (and hacked) some termios functions to work properly with ncurs…
Browse files Browse the repository at this point in the history
…es. Added scandir to dirent. Added termcap.os4 file that is used in ncurses
  • Loading branch information
afxgroup committed Aug 17, 2022
1 parent 99718a3 commit cb320a6
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 13 deletions.
1 change: 1 addition & 0 deletions libc.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ C_DIRENT := \
dirent/dirfd.o \
dirent/fdopendir.o \
dirent/opendir.o \
dirent/scandir.o \
dirent/readdir.o \
dirent/readdir_r.o \
dirent/readdir64_r.o \
Expand Down
58 changes: 58 additions & 0 deletions library/dirent/scandir.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* $Id: dirent_scandir.c,v 1.0 2022-08-17 12:04:22 clib2devs Exp $
*/

#ifndef _DIRENT_HEADERS_H
#include "dirent_headers.h"
#endif /* _DIRENT_HEADERS_H */

#ifndef _STDLIB_MEMORY_H
#include "stdlib_memory.h"
#endif /* _STDLIB_MEMORY_H */

int scandir(const char *path, struct dirent ***res,
int (*sel)(const struct dirent *),
int (*cmp)(const struct dirent **, const struct dirent **)) {
DIR *d = opendir(path);
struct dirent *de, **names = 0, **tmp;
size_t cnt = 0, len = 0;
int old_errno = errno;

if (!d) {
__set_errno(EACCES);
return -1;
}

while ((errno = 0), (de = readdir(d))) {
if (sel && !sel(de))
continue;
if (cnt >= len) {
len = 2 * len + 1;
if (len > SIZE_MAX / sizeof *names)
break;
tmp = realloc(names, len * sizeof *names);
if (!tmp)
break;
names = tmp;
}
names[cnt] = malloc(de->d_reclen);
if (!names[cnt])
break;
memcpy(names[cnt++], de, de->d_reclen);
}

closedir(d);

if (errno) {
if (names)
while (cnt-- > 0) free(names[cnt]);
free(names);
return -1;
}
__set_errno(old_errno);

if (cmp)
qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *)) cmp);
*res = names;
return cnt;
}
9 changes: 5 additions & 4 deletions library/include/dirent.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ struct dirent {
};

extern DIR *opendir(const char * path_name);
extern struct dirent * readdir(DIR * directory_pointer);
extern struct dirent *readdir(DIR * directory_pointer);
extern void rewinddir(DIR * directory_pointer);
extern int closedir(DIR * directory_pointer);
extern int closedir(DIR * directory_pointer);
extern DIR *fdopendir(int);
extern int alphasort(const struct dirent **a, const struct dirent **b);
extern int dirfd(DIR *dirp);
extern int alphasort(const struct dirent **a, const struct dirent **b);
extern int dirfd(DIR *dirp);
extern int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));

extern int readdir_r(DIR *dir, struct dirent *buf, struct dirent **result);
extern int readdir64_r(DIR *dir, struct dirent *buf, struct dirent **result);
Expand Down
36 changes: 34 additions & 2 deletions library/termios/console_fdhookentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ LineEditor(BPTR file, char *buf, const int buflen, struct termios *tios) {
unsigned char z;
int do_edit = 1;
int shift_mode = 0;
int esc_mode = 0;

SetMode(file, DOSTRUE); /* Set raw mode. */

while (do_edit && len < buflen) {
/* 5 seconds. */
if (WaitForChar(file, 5000000) != DOSFALSE) {
if (WaitForChar(file, 5000000) != DOSFALSE)
{
if (Read(file, &z, 1) == ERROR) {
len = -1;
break;
Expand All @@ -56,6 +58,10 @@ LineEditor(BPTR file, char *buf, const int buflen, struct termios *tios) {
buf[len++] = '\n';
continue;

case 27: /* ESC */
esc_mode = 1;
continue;

case 155: /* CSI */
shift_mode = 1;
continue;
Expand All @@ -80,8 +86,10 @@ LineEditor(BPTR file, char *buf, const int buflen, struct termios *tios) {
continue;
}

if (shift_mode) {

if (shift_mode || esc_mode) {
shift_mode = 0;
esc_mode = 0;

switch (z) {
case 'C': /* Right arrowkey */
Expand All @@ -97,6 +105,21 @@ LineEditor(BPTR file, char *buf, const int buflen, struct termios *tios) {
pos--;

continue;

case 'A': /* Up arrowkey */

if (pos < len)
pos++;

continue;

case 'B': /* Down arrowkey */

if (pos > 0)
pos--;

continue;

}
}

Expand Down Expand Up @@ -175,6 +198,15 @@ __termios_console_hook(struct fd *fd, struct file_action_message *fam) {
result = LineEditor(file, fam->fam_Data, fam->fam_Size, tios);
}
else {
/* Well.. this seems an hack to make ncurses works correctly
* I don't know if there are other problems setting STDIO always
* in RAW Mode but I suppose that we are ok since we are using
* a termios hook
*/
if (FLAG_IS_SET(fd->fd_Flags, FDF_STDIO)) {
/* Set raw mode. */
SetMode(file, DOSTRUE);
}
result = Read(file, fam->fam_Data, fam->fam_Size);
}
} else if (fam->fam_Size > 0) {
Expand Down
14 changes: 7 additions & 7 deletions library/termios/tcgetattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ get_console_termios(struct fd *fd) {
if (FLAG_IS_SET(fd->fd_Flags, FDF_READ))
SET_FLAG(tios->c_cflag, CREAD);

/* Set up the initial termios state in RAW mode */
cfmakeraw(tios);
tios->c_lflag = ISIG|ICANON|ECHO;

memcpy(tios->c_cc, def_console_cc, NCCS);

Expand Down Expand Up @@ -131,17 +130,18 @@ tcgetattr(int file_descriptor, struct termios *user_tios) {

__fd_unlock(fd);

/* If someone ask for tcgetattr on STDOUT or STDERR make sure that we set also
* STDIN. This hack fix ncurses library for example */
if (file_descriptor == STDOUT_FILENO || file_descriptor == STDERR_FILENO) {
tcgetattr(STDIN_FILENO, user_tios);
}

out:

__stdio_unlock();

__check_abort();

/* If someone ask for tcgetattr on STDOUT or STDERR make sure that we set also
* STDIN. This hack fix ncurses library for example */
if (file_descriptor == STDOUT_FILENO || file_descriptor == STDERR_FILENO) {
tcgetattr(STDIN_FILENO, user_tios);
}

return (result);
}
File renamed without changes.
58 changes: 58 additions & 0 deletions misc/termcap.os4
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# From: Kent Polk <kent@swrinde.nde.swri.edu>, 30 May 90
# Added a few more entries, converted caret-type control sequence (^x) entries
# to '\0xx' entries since a couple of people mentioned losing '^x' sequences.
#
# :as:, :ae: Support for alternate character sets.
# :ve=\E[\040p:vi=\E[\060\040p: cursor visible/invisible.
# :xn: vt100 kludginess at column 80/NEWLINE ignore after 80 cols(Concept)
# This one appears to fix a problem I always had with a line ending
# at 'width+1' (I think) followed by a blank line in vi. The blank
# line tended to disappear and reappear depending on how the screen
# was refreshed. Note that this is probably needed only if you use
# something like a Dnet Fterm with the window sized to some peculiar
# dimension larger than 80 columns.
# :k0=\E9~: map F10 to k0 - could have F0-9 -> k0-9, but ... F10 was 'k;'

# From: Hans Verkuil <hans@wyst.hobby.nl>, 4 Dec 1995
# (amiga: added empty <acsc> to suppress a warning --esr)
# Additions by Steven Solie <ssolie@ieee.org>, 24 July 2006
# Added colors by Andrea Palmate' <andrea.palmate@gmail.com>, 17 August 2022
amiga-clib2|Amiga ANSI ncurses:\
:am:bs:bw:ms:xn:mi:cc:\
:Co#16:NC#3:co#80:li#24:pa#64:\
:AB=\2334%dm:AF=\2333%dm:AL=\233%dL:DC=\233%dP:\
:DL=\233%dM:dl=\233M:op=\23339;49m:\
:DC=\233%dP:DO=\233%dB:IC=\233%d@:LE=\233%dD:RI=\233%dC:\
:SF=\233%dS:SR=\233%dT:UP=\233%dA:ac=:ae=^O:as=^N:bl=^G:\
:bt=\233Z:cd=\233J:ce=\233K:cl=\233H\233J:\
:cm=\233%i%d;%dH:cr=^M:dc=\233P:do=\233B:ec=\233%dP:ei=:\
:ho=\233H:ic=\233@:im=:is=\23320l:k0=\2339~:k1=\2330~:\
:k2=\2331~:k3=\2332~:k4=\2333~:k5=\2334~:k6=\2335~:\
:k7=\2336~:k8=\2337~:k9=\2338~:kD=\177:kb=^H:kd=\233B:\
:kl=\233D:kr=\233C:ku=\233A:le=\233D:mb=\2337;2m:\
:md=\2331m:me=\2330m:mh=\2332m:mk=\2338m:mr=\2337m:\
:nd=\233C:nw=\233B\r:r1=\Ec:se=\2330m:sf=\233S:so=\2337m:\
:sr=\233T:ta=^I:te=\233?7h:ti=\233?7l:ue=\2330m:up=\233A:\
:us=\2334m:vb=^G:ve=\233 p:vi=\2330 p:\
:kI=\23340~:kP=\23341~:kN=\23342~:kh=\23344~:@7=\23345~:\
:F1=\23320~:F2=\23321~:

amiga-clib2-mono|Amiga ANSI ncurses:\
:am:bs:bw:ms:xn:mi:cc:\
:co#80:li#24:\
:AB=\2334%dm:AF=\2333%dm:AL=\233%dL:DC=\233%dP:\
:DL=\233%dM:dl=\233M:op=\23339;49m:\
:DC=\233%dP:DO=\233%dB:IC=\233%d@:LE=\233%dD:RI=\233%dC:\
:SF=\233%dS:SR=\233%dT:UP=\233%dA:ac=:ae=^O:as=^N:bl=^G:\
:bt=\233Z:cd=\233J:ce=\233K:cl=\233H\233J:\
:cm=\233%i%d;%dH:cr=^M:dc=\233P:do=\233B:ec=\233%dP:ei=:\
:ho=\233H:ic=\233@:im=:is=\23320l:k0=\2339~:k1=\2330~:\
:k2=\2331~:k3=\2332~:k4=\2333~:k5=\2334~:k6=\2335~:\
:k7=\2336~:k8=\2337~:k9=\2338~:kD=\177:kb=^H:kd=\233B~:\
:kl=\233D:kr=\233C:ku=\233A~:le=\233D:mb=\2337;2m:\
:md=\2331m:me=\2330m:mh=\2332m:mk=\2338m:mr=\2337m:\
:nd=\233C:nw=\233B\r:r1=\Ec:se=\2330m:sf=\233S:so=\2337m:\
:sr=\233T:ta=^I:te=\233?7h:ti=\233?7l:ue=\2330m:up=\233A:\
:us=\2334m:vb=^G:ve=\233 p:vi=\2330 p:\
:kI=\23340~:kP=\23341~:kN=\23342~:kh=\23344~:@7=\23345~:\
:F1=\23320~:F2=\23321~:
21 changes: 21 additions & 0 deletions test_programs/dirent/scandir.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
struct dirent **namelist;
int i, n;

n = scandir("T:", &namelist, 0, alphasort);
if (n < 0)
perror("scandir");
else {
for (i = 0; i < n; i++) {
printf("%s\n", namelist[i]->d_name);
free(namelist[i]);
}
}
free(namelist);

return 0;
}

0 comments on commit cb320a6

Please sign in to comment.