sourcecode

Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Wednesday, July 11, 2012

EXECVE(2)

$man 2 execve

NAME
       execve - execute program

SYNOPSIS
       #include

       int execve(const char *filename, char *const argv[],
                  char *const envp[]);



Also the man page points out:
*  Any   outstanding   asynchronous   I/O   operations   are   canceled.



  • If the execution is unsuccessful, execve returns with -1 and its calling process continues.
  • If the execution is successful, execve overwrites its calling process (the rest of the code in the calling process is not reached) and the exit status is the same as defined in the process calling execve. (Either case the exit status code is the same).

The envp does not seem to work well in execve(). It is suggested to use execvp() instead.

/**********************END**********************/

WAIT(2) and status

$man 2 wait

NAME
       wait, waitpid, waitid - wait for process to change state

SYNOPSIS
       #include
       #include

       pid_t wait(int *status);

       pid_t waitpid(pid_t pid, int *status, int options);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       waitid():
           _SVID_SOURCE || _XOPEN_SOURCE >= 500 ||
           _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
           || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L




If no wait() function is used, the parent vs child process is in a race condition, i.e. the order of execution of the two processes is not determined.

When there are different exit paths in the child, it is possible to have them identified by the status variable, calling WEXITSTATUS(status) in the parent process after wait(2), according to _exit(status) numbers.







/*********************END*********************/

READ(2)

$man 2 read

NAME
       read - read from a file descriptor

SYNOPSIS
       #include

       ssize_t read(int fd, void *buf, size_t count);
 



  • size_t and ssize_t are both int

  • fd: STDIN_FILENO for standard in (keyboard, effectively 0)

  • There are three numbers: the buff size (bSize), the acceptance count size (cSize) and the actually input size (iSize).  
    1. When (iSize < cSize): if the input is terminated by Enter, then add one to the number of letters; if the input is terminated by ctrl+d, then no extra letter is appended. 
      • For example, user input: $ABC
        with an Enter, then iSize == 4, and the buffer stores ASCII (* means garbage integers):
        65 66 67 10 *  *  *
      • user input: $ABC
        with a ctrl+d, then iSzie == 3, and the buffer stores ASCII:
        65 66 67 *  *  *
    2. When (iSize > cSize), the exceeding input is ignored and resultant iSize == cSize
    3.  When (bSize < cSize), danger! The system does not perform boundary check! So one can input long enough to write out of the buffer's boundary and no warnings given. This probably won't corrupt immediately, but it still can cause fatal error potentially at any time!
    4. When a read() function is encountered, the system waits for the input. And every call of read(), the buf is overwritten.
For write(2) function, similar scenarios show. the fd can be STDOUT_FILENO for standard output (monitor, effectively 1).

/*********************END*******************/

Thursday, July 5, 2012

pthread_create()

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
http://www.cs.cf.ac.uk/Dave/C

Tried to find the simplest example of using pthread_create for a beginner. The man page of pthread_create, again, is rather a reference for experts who already know how to use pthread_create.

Here I have the simplest working code without all the distractions:
#include <stdio.h>
#include <pthread.h>

void* threadFunction(){//the function is the entry point of a new thread
  printf("Catch = %d\n",22);
}

int main(){

  pthread_t threadId;//to record the thread id of the newly created thread
  //effectively pthread_t is type unsigned long int

  pthread_create(&threadId, NULL, threadFunction, NULL);
  //threadFunction, inputArg together is a function call equivalent to the
  //more familiar form: threadFunction(inputArg);

  pthread_join(threadId,NULL);
  //this function call forces the main() is waiting for the thread to complete. 
  //(for the thread to "join" back?)
  //Otherwise, the main
  //may exit before the thread finishes, thus aborts the thread prematurely

  printf("threadId = %lu\n",threadId);

  return 0;
  }
 

The thread function takes exactly one entrance parameter,  similar to main() you can have main(char argc, char** argv). It is common practice to have the entrance parameter be a struct so that complicated data can be passed into the thread.

#include <stdio.h>
#include <pthread.h>

void* threadFunction(void* threadFunctionArg){
  int* pMax = threadFunctionArg;
  printf("Double the input =%d\n",*pMax * 2);
}


int main(){
  int num=5;//some information to pass to the new thread

  pthread_t threadId;//to record the thread id of the newly created thread
  //effectively pthread_t is type unsigned long int

  int threadStatus;//to record the return status of the new thread
  //0 means good, otherwise an error number is recorded.

  void* inputArg = &num;//used to pass into the thread function

  threadStatus = pthread_create(&threadId, NULL, threadFunction, inputArg);
  //threadFunction, inputArg together is a function call equivalent to the
  //more familiar form: threadFunction(inputArg);

  pthread_join(threadId,NULL);
  //the main() is waiting for the thread to complete. Otherwise, the main
  //may exit before the thread finishes, thus aborts the thread prematurely

  printf("threadId = %lu\n",threadId);

  printf("threadStatus = %d\n",threadStatus);

  return 0;
  }
/********************END******************/