/*
 * unistd.h - User level <unistd> library definition.
 * 
 * Author     Alain Greiner (2016,2017,2018)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.0 of the License.
 *
 * ALMOS-MKH 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.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _UNISTD_H_
#define _UNISTD_H_

/***************************************************************************************** 
 * This file defines the user level <unistd> library.
 * All these functions make a system call to access the kernel structures.
 * The user/kernel shared structures and mnemonics are defined in
 * the <syscalls/shared_include/shared_unistd.h> file.
 ****************************************************************************************/

#include <shared_unistd.h>

/***************************************************************************************** 
 * This function implements the <alarm> system call.
 * It sets a timer to deliver the signal SIGALRM to the calling process,
 * after the specified number of seconds. 
 * If an alarm has already been set with alarm() but has not been delivered, 
 * another call to alarm() will supersede the prior call.
 * The request alarm(0) cancels the current alarm and the signal will not be delivered.
 ***************************************************************************************** 
 * @ seconds   : number of seconds.
 * @ returns the amount of time left on the timer from a previous call to alarm().
 *   If no alarm is currently set, the return value is 0.
 ****************************************************************************************/
unsigned alarm( unsigned seconds );

/***************************************************************************************** 
 * This function implements the <chdir> system call.
 * It changes the current working directory in the reference process descriptor.
 *****************************************************************************************
 * @ pathname   : pathname (can be relative or absolute).
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int chdir( const char * pathname );

/***************************************************************************************** 
 * This function implements the <close> system call.
 * It releases the memory allocated for the file identified by the <fd> argument,
 * and remove the fd array_entry in all process descriptor copies.
 *****************************************************************************************
 * @ fd   : file descriptor index in fd_array.
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int close( int fd );

/***************************************************************************************** 
 * This function implement the <exec> system call.
 * It creates, in the same cluster as the calling thread, a new process descriptor,
 * and a new associated main thread descriptor, executing a new memory image defined 
 * by the <filename> argument. This new process inherit from the old process the PID
 * and the PPID, as well as all open files (including the TXT). 
 * The old process descriptor, and all its threads are blocked, and marked for deletion.
 * Therefore the exec syscall does not return to the calling thread in case of success.
 * This function initializes the exec_info_t structure (embedded in process descriptor),
 * and containing the <filename>, <args> and <envs> arguments.
 * 
 * TODO : the <envs> argument is not supported yet (must be NULL).
 ***************************************************************************************** 
 * @ filename : string pointer on .elf filename (virtual pointer in user space)
 * @ args     : NULL terminated array of strings pointers on process arguments.
 * @ envs     : NULL terminated array of strings pointers on environment variables.
 * @ does not return if success / returns -1 if failure.
 ****************************************************************************************/
int execve( char  * filename,
            char ** args,
            char ** envs );

/***************************************************************************************** 
 * This function implement the <fork> system call.
 * The calling process descriptor (parent process), and the associated thread descriptor
 * are replicated in a - likely - remote cluster, that becomes the new process owner. 
 * The child process get a new PID is linked to the parent PID. The child process inherit
 * from the parent process the memory image, and all open files (including the TXT).
 * The child process becomes the TXT terminal owner.
 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be
 * stored in the calling thread descriptor by the specific fork_place() system call.
 * If not, the kernel function makes a query to the DQDT to select the target cluster. 
 ***************************************************************************************** 
 * @ if success, returns child process PID to parent, and return O to child.
 * @ if failure, returns -1 to parent / no child process is created.
 ****************************************************************************************/
int fork( void );

/***************************************************************************************** 
 * This function implements the <fsync> system call.
 * It causes all the modified data and attributes of file identified by the <fd> argument
 * to be copied from the file mapper and file descriptor to the IOC device.
 *****************************************************************************************
 * @ fd   : file descriptor index in fd_array.
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int fsync( int fd );

/***************************************************************************************** 
 * This function implements the <getcwd> system call.
 * It returns the pathname of the current working directory.
 *****************************************************************************************
 * buf     : buffer addres in user space.
 * nbytes  : user buffer size in bytes.
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int getcwd( char       * buf,
            unsigned int nbytes );

/***************************************************************************************** 
 * This function implements the <getpid> system call.
 * It returns the process identifier.
 ***************************************************************************************** 
 * @ returns the process PID for the calling thread process.
 ****************************************************************************************/
int getpid( void );

/***************************************************************************************** 
 * This function implements the <isatty> system call.
 * It test whether a file descriptor refers to a terminal.
 ***************************************************************************************** 
 * @ fd   : file descriptor index in fd_array.
 * @ returns 1 if fd is an open file descriptor referring to a terminal / 0 otherwise.
 ****************************************************************************************/
int isatty( int fd );

/***************************************************************************************** 
 * This function implements the <lseek> system call.
 * It repositions the offset of the file descriptor identified by <fd>,
 * according to the operation type defined by the <whence> argument.
 *****************************************************************************************
 * @ fd       : open file index in fd_array.
 * @ offset   : used to compute new offset value.
 * @ whence   : operation type (SEEK_SET / SEEK_CUR / SEEK_END)
 * @ return new offset value if success / returns -1 if failure.
 ****************************************************************************************/
int lseek( int           fd,
           unsigned int  offset,
           int           whence );

/***************************************************************************************** 
 * This function implements the <pause> system call.
 * It stops the calling process until a signal is received.
 *****************************************************************************************
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int pause( void );

/***************************************************************************************** 
 * This function implements the <pipe> system call.
 * It creates in the calling thread cluster an unnamed pipe, and two (read and write)
 * file descriptors to access this pipe. The argument is a pointer a fd[] array.
 *****************************************************************************************
 * @ fd[0] : [out] buffer for read only file descriptor index.
 * @ fd[1] : [out] buffer for write only file descriptor index.
 * @ return 0 if success / return -1 if failure.
 ****************************************************************************************/
int pipe( int fd[2] );

/***************************************************************************************** 
 * This function implements the <read> system call.
 * It reads bytes from an open file identified by the <fd> file descriptor.
 * This file can be a regular file or a character oriented device.
 *****************************************************************************************
 * @ fd       : file index in fd_array.
 * @ buf      : buffer virtual address in user space.
 * @ count    : number of bytes.
 * @ return number of bytes actually read if success / returns -1 if failure.
 ****************************************************************************************/
int read( int            fd,
          void         * buf,
          unsigned int   count );

/***************************************************************************************** 
 * This function implements the <rmdir> system call.
 * It removes a directory file whose name is given by <pathname>.
 * The directory must not contain any entries other than `.' and `..'.
 *****************************************************************************************
 * @ pathname   : pathname (can be relative or absolute).
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int rmdir( char * pathname ); 

/***************************************************************************************** 
 * This function implements the <sleep> system call.
 * It suspends execution of the calling thread until either <seconds> have elapsed,
 * or a signal is delivered to the thread and its action is to terminate the thread.
 * System activity may lengthen the sleep by an indeterminate amount.
 *****************************************************************************************
 * @ seconds   : sleep duration in seconds.
 * @ return 0 if success / returns number of unslept seconds if signal delivery.
 ****************************************************************************************/
unsigned int sleep( unsigned int seconds );

/***************************************************************************************** 
 * This function implements the <sync> system call.
 * It forces all kernel mappers (file caches) to be copied to the IOC device.
 ****************************************************************************************/
void sync( void );

/***************************************************************************************** 
 * This function implements the <unlink> system call.
 * It removes a directory entry identified by the <pathname> from the parent directory, 
 * and decrement the link count of the file referenced by the link.
 * If the link count reduces to zero, and no process has the file open, then all resources
 * associated with the file are released.  If one or more process have the file open when
 * the last link is removed, the link is removed, but the removal of the file is delayed 
 * until all references to it have been closed.
 *****************************************************************************************
 * @ pathname   : pathname (can be relative or absolute).
 * @ return 0 if success / returns -1 if failure.
 ****************************************************************************************/
int unlink( const char * pathname );

/***************************************************************************************** 
 * This function implements the <write> system call.
 * It writes bytes to an open file identified by the <fd> file descriptor.
 * This file can be a regular file or character oriented device.
 *****************************************************************************************
 * @ fd       : file index in fd_array.
 * @ buf      : buffer virtual address in user space.
 * @ count    : number of bytes.
 * @ return number of bytes actually written if success / returns -1 if failure.
 ****************************************************************************************/
int write( int            fd,
           const void   * buf,
           unsigned int   count );

#endif
