mirror of
https://github.com/GnoConsortium/gno.git
synced 2025-06-01 09:41:14 +00:00
- added non-ORCA rename(2) implementation
- added sigprocmask(2) - changed unlink(2) not to depend on remove(3) [was briefly mutually recursive] - added fcntl(2)
This commit is contained in:
parent
2dafe3f23e
commit
7fad7d2bd6
@ -1,3 +1,4 @@
|
|||||||
|
#line 1 ":src:gno:lib:libc:sys:syscall.c"
|
||||||
/*
|
/*
|
||||||
* libc/sys/syscall.c
|
* libc/sys/syscall.c
|
||||||
*
|
*
|
||||||
@ -9,7 +10,7 @@
|
|||||||
* Unless otherwise specified, see the respective man pages for details
|
* Unless otherwise specified, see the respective man pages for details
|
||||||
* about these routines.
|
* about these routines.
|
||||||
*
|
*
|
||||||
* $Id: syscall.c,v 1.2 1997/07/27 23:33:36 gdr Exp $
|
* $Id: syscall.c,v 1.3 1997/09/05 06:38:06 gdr Exp $
|
||||||
*
|
*
|
||||||
* This file is formatted with tab stops every 3 columns.
|
* This file is formatted with tab stops every 3 columns.
|
||||||
*/
|
*/
|
||||||
@ -774,6 +775,72 @@ read (int filds, void *buf, size_t bytecount) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rename
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
rename (const char *from, const char *to) {
|
||||||
|
struct {
|
||||||
|
word pCount;
|
||||||
|
GSStringPtr from;
|
||||||
|
GSStringPtr to;
|
||||||
|
} renblock;
|
||||||
|
struct stat sfrom, sto;
|
||||||
|
int ret2;
|
||||||
|
|
||||||
|
if (stat(from, &sfrom) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret2 = stat(to, &sto);
|
||||||
|
if ((ret2 < 0) && (errno != ENOENT)) {
|
||||||
|
/* problem stat'ing destination */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure the source and destination (if it exists) are of the same type */
|
||||||
|
if (ret2 == 0) {
|
||||||
|
if (S_ISDIR(sfrom.st_mode) && ! S_ISDIR(sto.st_mode)) {
|
||||||
|
errno = ENOTDIR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(sto.st_mode) && ! S_ISDIR(sfrom.st_mode)) {
|
||||||
|
errno = EISDIR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (unlink(to) < 0) {
|
||||||
|
if (errno == EACCES) {
|
||||||
|
errno = EEXIST; /* proper POSIX side effect */
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get GS/OS-style copies of the filenames */
|
||||||
|
renblock.pCount = 2;
|
||||||
|
if ((renblock.from = __C2GSMALLOC(from)) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((renblock.to = __C2GSMALLOC(to)) == NULL) {
|
||||||
|
GIfree(renblock.from);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangePathGS(&renblock);
|
||||||
|
ret2 = _toolErr;
|
||||||
|
GIfree(renblock.from);
|
||||||
|
GIfree(renblock.to);
|
||||||
|
if (ret2) {
|
||||||
|
errno = _mapErr(ret2);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -787,6 +854,44 @@ rexit (int code) {
|
|||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigprocmask - This would be much more efficient if it was implemented
|
||||||
|
* in the kernel. Note that in most cases we are doing
|
||||||
|
* two kernel traps (and thus context switches).
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
sigprocmask (int how, const sigset_t *set, sigset_t *oset) {
|
||||||
|
sigset_t old;
|
||||||
|
|
||||||
|
if (set != NULL) {
|
||||||
|
switch(how) {
|
||||||
|
case SIG_BLOCK:
|
||||||
|
old = sigblock(*set);
|
||||||
|
break;
|
||||||
|
case SIG_UNBLOCK:
|
||||||
|
old = sigblock(0);
|
||||||
|
sigblock(old & ~(*set));
|
||||||
|
break;
|
||||||
|
case SIG_SETMASK:
|
||||||
|
old = sigblock(0);
|
||||||
|
sigblock(*set);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (oset != NULL) { /* set == NULL */
|
||||||
|
old = sigblock(0);
|
||||||
|
sigblock(old);
|
||||||
|
} /* if both set and oset are NULL, this routine is a no-op */
|
||||||
|
|
||||||
|
if (oset != NULL) {
|
||||||
|
*oset = old;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* statfs
|
* statfs
|
||||||
*/
|
*/
|
||||||
@ -911,13 +1016,28 @@ umask (mode_t mask) {
|
|||||||
* unlink
|
* unlink
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int unlink(char *fname)
|
int
|
||||||
|
unlink(char *fname)
|
||||||
{
|
{
|
||||||
/*
|
struct {
|
||||||
* Orca/C doesn't specify what the "non-zero" return code is, so
|
word pCount;
|
||||||
* force it to be -1.
|
GSStringPtr pathname;
|
||||||
*/
|
} drec;
|
||||||
return (remove(fname) == 0) ? 0 : -1;
|
int err;
|
||||||
|
|
||||||
|
drec.pCount = 1;
|
||||||
|
drec.pathname = __C2GSMALLOC(fname);
|
||||||
|
if (drec.pathname == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DestroyGS(&drec);
|
||||||
|
err = _mapErr(_toolErr);
|
||||||
|
GIfree(drec.pathname);
|
||||||
|
if (err) {
|
||||||
|
errno = err;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -969,7 +1089,7 @@ waitpid(pid_t pid, union wait *istat, int options)
|
|||||||
/*
|
/*
|
||||||
* write
|
* write
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
write(int filds, void *buf, size_t bytecount) {
|
write(int filds, void *buf, size_t bytecount) {
|
||||||
IORecGS iorec = {4, filds, buf, (long) bytecount, 0L};
|
IORecGS iorec = {4, filds, buf, (long) bytecount, 0L};
|
||||||
@ -1022,6 +1142,52 @@ _libcPanic (const char *fmt, ...) {
|
|||||||
|
|
||||||
#endif /* VERSION_CHECK */
|
#endif /* VERSION_CHECK */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fcntl
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
fcntl (int fd, int cmd, ...) {
|
||||||
|
struct stat sbuf;
|
||||||
|
va_list list;
|
||||||
|
int result;
|
||||||
|
unsigned short mode;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
va_start(list, cmd);
|
||||||
|
switch(cmd) {
|
||||||
|
case F_DUPFD:
|
||||||
|
result = va_arg(list, int);
|
||||||
|
result = dup2(fd, result);
|
||||||
|
break;
|
||||||
|
case F_GETFL:
|
||||||
|
if (fstat(fd, &sbuf) == -1) {
|
||||||
|
err = errno;
|
||||||
|
result = -1;
|
||||||
|
} else {
|
||||||
|
mode = sbuf.st_mode & (S_IRUSR | S_IWUSR);
|
||||||
|
if (mode == (S_IRUSR | S_IWUSR)) {
|
||||||
|
result = O_RDWR;
|
||||||
|
} else if (mode == S_IRUSR) {
|
||||||
|
result = O_RDONLY;
|
||||||
|
} else if (mode == S_IWUSR) {
|
||||||
|
result = O_WRONLY;
|
||||||
|
} else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = EINVAL;
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
va_end(list);
|
||||||
|
if (err != 0) {
|
||||||
|
errno = err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open -- end of file because of higher optimization required
|
* open -- end of file because of higher optimization required
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user