// ---------------------------------------------------------------------------
// - csio.cxx -
// - standard system library - c i/o function implementation -
// ---------------------------------------------------------------------------
// - This program is free software; you can redistribute it and/or modify -
// - it provided that this copyright notice is kept intact. -
// - -
// - This program is distributed in the hope that it will be useful, but -
// - without any warranty; without even the implied warranty of -
// - merchantability or fitness for a particular purpose. In no event shall -
// - the copyright holder be liable for any direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software. -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2007 amaury darsch -
// ---------------------------------------------------------------------------
#include "cstr.hpp"
#include "ccnv.hpp"
#include "cerr.hpp"
#include "csio.hpp"
#include "csio.hxx"
namespace afnix {
// the selector handle structure
struct s_select {
// input set
fd_set d_iset;
// output set
fd_set d_oset;
// max sid
int d_smax;
// create a new handle
s_select (void) {
FD_ZERO (&d_iset);
FD_ZERO (&d_oset);
d_smax = 0;
}
};
// return the default input stream associated with this process
int c_stdin (void) {
return STDIN_FILENO;
}
// return the default output stream associated with this process
int c_stdout (void) {
return STDOUT_FILENO;
}
// return the default error stream associated with this process
int c_stderr (void) {
return STDERR_FILENO;
}
// check if the name corresponds to a file name and can be accessed.
// it does not necessarily means that it can be opened.
bool c_isfile (const char* name) {
int status;
struct stat buffer;
if (c_strlen (name) == 0) return false;
status = stat (name,&buffer);
if ((status == 0) && S_ISREG (buffer.st_mode)) return true;
return false;
}
// check if the name corresponds to a directory name and can be accessed.
// it does not necessarily means that it can be opened.
bool c_isdir (const char* name) {
int status;
struct stat buffer;
if (c_strlen (name) == 0) return false;
status = stat (name,&buffer);
if ((status == 0) && S_ISDIR (buffer.st_mode)) return true;
return false;
}
// open a file for reading. a file descriptor is returned on success or
// -1 in case of error.
int c_openr (const char* name) {
int fd = open (name, O_RDONLY);
return (fd == -1) ? c_errmap (errno) : fd;
}
// open a file for writing. a file descriptor is returned on success or
// -1 in case of error.
int c_openw (const char* name, const bool tflag, const bool aflag) {
// compute flag and mode
int flag = O_WRONLY | O_CREAT;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
if (tflag == true) flag |= O_TRUNC;
if (aflag == true) flag |= O_APPEND;
// try to open the file
int fd = open (name, flag, mode);
return (fd == -1) ? c_errmap (errno) : fd;
}
// open a file for read write. A file descriptor is returned on success or
// -1 in case of error.
int c_openrw (const char* name, const bool tflag, const bool aflag) {
// compute flag and mode
int flag = O_RDWR | O_CREAT;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
if (tflag == true) flag |= O_TRUNC;
if (aflag == true) flag |= O_APPEND;
// try to open the file
int fd = open (name, flag, mode);
return (fd == -1) ? c_errmap (errno) : fd;
}
// open a session file for read write by user and read by other.
int c_opensd (const char* name) {
// compute flag and mode
int flag = O_RDWR | O_CREAT | O_EXCL;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
// try to open the file
int fd = open (name, flag, mode);
return (fd == -1) ? c_errmap (errno) : fd;
}
// open a temporary file
// wait for a character or timeout
bool c_rdwait (const int sid, const long tout) {
// chck for good descriptor
if (sid < 0) return false;
// initialize the set
fd_set set;
FD_ZERO (&set);
FD_SET (sid, &set);
// initialize the timeout
struct timeval timeout;
timeout.tv_sec = tout / 1000;
timeout.tv_usec = (tout % 1000) * 1000;
// wait on select
int status = 0;
if (tout == -1)
status = select (sid+1, &set, NULL, NULL, NULL);
else
status = select (sid+1, &set, NULL, NULL, &timeout);
return (status == 1) ? true : false;
}
// read n bytes in a buffer. The buffer must be pre-allocated. The number
// of bytes read is returned
t_long c_read (const int sid, char* buffer, const t_long count) {
// standard checks
if ((sid < 0) || (buffer == 0)) return AFNIX_ERR_IARG;
// read n bytes and return error code
t_long result = read (sid, buffer, count);
return (result == -1) ? c_errmap (errno) : result;
}
// write n bytes from a buffer. The buffer must be pre-allocated. The number
// of bytes written is returned
t_long c_write (const int sid, const char* buffer, const t_long count) {
// standard checks
if ((sid < 0) || (buffer == 0)) return AFNIX_ERR_IARG;
if (count == 0) return 0;
// write n bytes and return
t_long result = write (sid, buffer, count);
return (result == -1) ? c_errmap (errno) : result;
}
// close this stream.
bool c_close (const int sid) {
if (sid < 0) return AFNIX_ERR_IARG;
return (close (sid) == -1) ? false : true;
}
// return the size of a file
t_long c_fsize (const int sid) {
struct stat buffer;
// check that we have a regular file
int status = fstat (sid,&buffer);
if ((status != 0) || (!S_ISREG (buffer.st_mode))) return AFNIX_ERR_IARG;
// return the file size
return buffer.st_size;
}
// set a file at a certain position
bool c_lseek (const int sid, const t_long pos) {
off_t status = lseek (sid, (off_t) pos, SEEK_SET);
if (status == (off_t) -1) return false;
return true;
}
// lock completly a file
bool c_flock (const int sid, const bool wlk) {
// standard check
if (sid == -1) return false;
// make a full range locking
struct flock fl;
fl.l_type = wlk ? F_WRLCK : F_RDLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
// lock or wait
return (fcntl (sid, F_SETLKW, &fl) == -1) ? false : true;
}
// unlock a file
bool c_funlock (const int sid) {
// standard check
if (sid == -1) return false;
// unlock the file
struct flock fl;
fl.l_type = F_UNLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
// lock or wait
return (fcntl (sid, F_SETLK, &fl) == -1) ? false : true;
}
// remove the file given its name.
bool c_rm (const char* name) {
if (name == nilp) return false;
return (unlink (name) == 0) ? true : false;
}
// create a new selector handle
void* c_shnew (void) {
return new s_select;
}
// free a selector handle
void c_shfree (void* handle) {
s_select* sh = (s_select*) handle;
delete sh;
}
// add an input descriptor to the select handle
void c_shiadd (void* handle, const int sid) {
if ((handle == nilp) || (sid < 0)) return;
s_select* sh = (s_select*) handle;
FD_SET (sid, &(sh->d_iset));
if (sid > sh->d_smax) sh->d_smax = sid;
}
// add an output descriptor to the select handle
void c_shoadd (void* handle, const int sid) {
if ((handle == nilp) || (sid < 0)) return;
s_select* sh = (s_select*) handle;
FD_SET (sid, &(sh->d_oset));
if (sid > sh->d_smax) sh->d_smax = sid;
}
// wait for a descriptor to be ready
long c_shwait (void* handle, const long tout) {
// check for valid call
if (handle == nilp) return 0;
s_select* sh = (s_select*) handle;
// initialize the timeout
struct timeval timeout;
timeout.tv_sec = tout / 1000;
timeout.tv_usec = (tout % 1000) * 1000;
// now call select
int result = 0;
int nsh = sh->d_smax + 1;
if (tout < 0)
result = select (nsh, &(sh->d_iset), &(sh->d_oset), NULL, NULL);
else
result = select (nsh, &(sh->d_iset), &(sh->d_oset), NULL, &timeout);
// check for error and remap
if (result == 1) result = c_errmap (errno);
return result;
}
// return true if an input descriptor is set
bool c_shitst (void* handle, const int sid) {
// check for valid call
if ((handle == nilp) || (sid < 0)) return false;
s_select* sh = (s_select*) handle;
return (FD_ISSET (sid, &(sh->d_iset)) == 0) ? false : true;
}
// return true if an output descriptor is set
bool c_shotst (void* handle, const int sid) {
// check for valid call
if ((handle == nilp) || (sid < 0)) return false;
s_select* sh = (s_select*) handle;
return (FD_ISSET (sid, &(sh->d_oset)) == 0) ? false : true;
}
}
syntax highlighted by Code2HTML, v. 0.9.1