How to use a search operator in Gmail


  1. Go to Gmail.
  2. In the search box, type the search operator.

Search operators you can use

Tip: Once you do a search using search operators, you can use the results to set up a filter for these messages.

What you can search bySearch operator & example
Specify the sender from: Example: from:amy
Specify a recipient to: Example: to:david
Words in the subject line subject: Example: subject:dinner
Messages that match multiple terms OR or { } Example: from:amy OR from:david Example: {from:amy from:david}
Remove messages from your results - Example: dinner -movie
Find messages with words near each other. Use the number to say how many words apart the words can be  Add quotes to find messages in which the word you put first stays first. AROUND Example: dinner AROUND 5 friday Example: "secret AROUND 25 birthday"
Messages that have a certain label label: Example: label:friends
Messages that have an attachment has:attachment Example: has:attachment
Messages that have a Google Drive, Docs, Sheets, or Slides attachment or link has:drive has:document has:spreadsheet has:presentation Example: has:drive 
Messages that have a YouTube video has:youtube Example: has:youtube
Messages from a mailing list list: Example: list:
Attachments with a certain name or file type filename: Example: filename:pdf Example: filename:homework.txt
Search for an exact word or phrase " " Example: "dinner and movie tonight"
Group multiple search terms together ( ) Example: subject:(dinner movie)
Messages in any folder, including Spam and Trash in:anywhere Example: in:anywhere movie
Search for messages that are marked as important is:important label:important Example: is:important   
Starred, snoozed, unread, or read messages is:starred is:snoozed is:unread is:read Example: is:read is:starred
Messages that include an icon of a certain color has:yellow-star has:blue-info Example: has:purple-star
Recipients in the cc or bcc field cc: bcc: Example: cc:david Note: You can’t find messages that you received on bcc.
Search for messages sent during a certain time period after: before: older: newer: Example: after:2004/04/16 Example: before:2004/04/18
Search for messages older or newer than a time period using d (day), m (month), and y (year) older_than: newer_than: Example: newer_than:2d
Chat messages is:chat Example: is:chat movie
Search by email for delivered messages deliveredto: Example: deliveredto:
Messages in a certain category category: Example: category:updates
Messages larger than a certain size in bytes size: Example: size:1000000
Messages larger or smaller than a certain size in bytes larger: smaller: Example: larger:10M
Results that match a word exactly + Example: +unicorn
Messages with a certain message-id header Rfc822msgid: Example: rfc822msgid: 
Messages that have or don’t have a label has:userlabels has:nouserlabels Example: has:nouserlabels  Note: Labels are only added to a message, and not an entire conversation.

Note: When using numbers as part of your query, a space or a dash (-) will separate a number while a dot (.) will be a decimal. For example, 01.2047-100 is considered 2 numbers: 01.2047 and 100.

Materialized Views

REFRESH FAST Categories

There are three ways to categorize a materialized view’s ability to be fast refreshed.

  1. It can never be fast refreshed.
  2. It can always be fast refreshed.
  3. It can be fast refreshed after certain kinds of changes to the base table but not others.

For the first case Oracle will raise an error if you try to create such a materialized view with its refresh method defaulted to REFRESH FAST. In the example below table T does not have a materialized view log on it. Materialized views based on T cannot therefore be fast refreshed. If we attempt to create such a materialized view we get an error.

create materialized view MV REFRESH FAST as select * from t2 ; as select * from t2 * ERROR at line 3: ORA-23413: table "SCOTT"."T2" does not have a materialized view log

Source: Materialized Views: REFRESH FAST Categories

Using WSL and MobaXterm to Create a Linux Dev Environment on Windows — Nick Janetakis

For the last 5 years or so I’ve been using VMware’s Unity mode to seamlessly run Linux applications on Windows without having to dual boot.

Overall, it was a pretty solid set up but it had a few annoying issues. It got to the point where I woke up one day and backed up my source code and then rage uninstalled VMware followed by deleting the 100GB VM image.

There was no going back. I had to find a new solution.

Spoiler alert: This new set up is the best way I’ve come across to run both Linux and Windows together. If you’re on Windows and want to also run Linux tools (even graphical apps and Docker) you’ll learn how to set everything up by reading this article.

Source: Using WSL and MobaXterm to Create a Linux Dev Environment on Windows — Nick Janetakis

Local Area Network : How to fix slow LAN transfer speed of files in Windows – HowToSolutions

Recently I had to solve a problem of a very slow transfer of files between two computers on a LAN network using Ethernet cable. Both machines had Windows 7 x64 installed and the transfer speed was ridiculously slow at 10-15kb/s. Using Task Manager under Networking tab, Network Utilization was showing only around 0.25% for Local Area Connection.

I looked around the web for solutions and found quite a few suggestions how to tackle this problem. Those that I tried and the one that finally solved my problem are discussed here.

windows-7-features

Turning off “Remote Differential Compression”

One of the first suggestions that I came across was to turn off this Windows Feature in Windows 7.

This suggestion is common on the web but it turns out to be just a myth.

From TechNet:

This is 100% false. Neither Windows Update or file copy operations use RDC at all.

So I ignored this suggestion and continued looking.

command-prompt-running-as-administrator-netsh

Disabling “TCP Auto-Tuning”

This is another common suggestion that I came across and it uses NETSH command-line utility used for displaying and modifying the network configuration. To make the necessary changes, we need to run that utility as an Administrator.

  1. Open Command Prompt as Administrator:
    • Click on Start Menu
    • Type Command in search box
    • Command Prompt will show up in results. Right-click on it to open Context Menu
    • Select Run as administrator
    • If User Account Control Window shows up asking if you want to allow the following program to make changes, select Yes
  2. Type: netsh interface tcp set global autotuning=disabled
  3. Restart the computer
  4. To verify that the auto-tuning is still disabled type in Command Prompt:
    netsh interface tcp show global

This suggestion still didn’t solve my problem, so I looked further, but before doing that I wanted to set Auto-tuning back to the default value by typing netsh interface tcp set global autotuning=normal in the Command Prompt (running as an Administrator).

windows-7-network-adapter-advanced-tab

Disabling “Large Send Offload (LSO)”

Large Send Offload is a technique of improving network performance while at the same time reducing CPU overhead. Apparently it does not work very well, so it was suggested to disable it. If you would like to know about LSO, check this MSDN article from 2001.

LSO is an option located in a Device Manager under your network adapter, so this solution requires Administrator Privileges.

Follow these steps:

  1. Open Start Menu, right-click on Computer and select Properties
  2. Under Control Panel Home located on the left side of the window click on Device Manager
  3. You will get a list of all devices on your machine. Expand Network Adapters.
  4. Find your Network Card and double-click on it.
  5. Select Advanced tab. You will get a list filled with different options.
  6. Select Large Send Offload V2 (IPv4) and set the value to Disabled
  7. Do the same for Large Send Offload V2 (IPv6) if it is available
  8. Click OK

After clicking OK, I tried to send a file over the LAN network. The transfer speed started very slow, but it was gradually picking up speed. I decided to restart the computer and try to send that file again and this time it worked like a charm.

Now that sending of files worked as it should, I also checked speed for receiving files. It turned out that it was still slow but all I had to do to fix that was to disable Large Send Offload V2 on the other computer. Once done,  the problem was solved for receiving files as well.

Conclusion

In this post we examined different ways to solve slow speed on a LAN network. One of them is just a common myth, but for other two you need to have administrator privileges. I hope you found this article useful. Consider sharing it on a social networks. Comments are also welcome.

If you solved your slow LAN speed problem in a different way, let me know how and I might add that solution to the list.

netsh interface tcp show global

Source: Local Area Network : How to fix slow LAN transfer speed of files in Windows – HowToSolutions

Zakładanie stron WordPress

Koszty stałe (roczne) utrzymania strony WWW u providera to hosting + domena.

Hosting

84.87 pln/y https://hosting.linux.pl/hosting.html lub szybsze rozwiązanie na SSD Szybki SSD 4GB 158.6pln/y (wg mnie warto zainwestować w SSD)

Domena

Domena w zależności od nazwy od kilku złotych za rejestrację do 200pln za przedłużenie za rok https://hosting.linux.pl/domeny-cennik.html . Tu cena zależny od nazwy jaką wybierasz. Czyli koło ~110pln/y trzeba liczyć.

Template

Wybór template wyglądu strony z bogatej listy darmowych oraz płatnych templatów. Jeżeli płatny to jednorazowo ~60$ mail firmowy (skrzynka lub przekierowanie) – tu jest potrzebna konfiguracja na serwerze
WordPress (CMS) jest darmowy – trzeba założyć bazę i wgrać go na serwer.

Wtyczki & automatyzacje

Wtyczki i autonomizacje w zależności od potrzeb – tu potrzebna konfiguracja i sensowny dobór dodatków –> zapewniam site działający, backupowany i odporny na ataki. Jeżeli warto będzie coś kupić to wtedy o tym powiem ale raczej wyniknie to z kontekstu prac.

Grafika i teksty

Grafikę i tekst potrzebuję z Tobą/Wami obgadać tak abyśmy mieli wspólną koncepcję co będzie na stronie. Wiąże się to też ze znakiem graficznym i zdjęciami które warto zrobić dobrze i obrobić (Photoshop/watermark/logo). Lepiej dać mniej ale bardzo dobrej jakości niż coś z telefonu. Rozwiązanie jest na tyle intuicyjne że poprawki w tekście menu itp będzie mgli wprowadzać sami

Sklep oraz rezerwacje

Sklep zamówienia/rezerwacje online – jest jak najbardziej do zrobienia ale strona musi na siebie zarabiać. Proponuję to potraktować jako oddzielny temat.

SEO

SEO (Search Engine Optimization) – dołączenie i konfiguracja site do Google Analytics .

Find files by date modified in Windows

Yes finaly i instaled Windows 10

Using datemodified: in Windows File Explorer in Windows Vista, Windows 7, and Windows 8 allows you to find any files that have been modified by a date of your choice. Using this tip can be helpful for anyone who has lost a file but know when they last modified the file. Follow the steps below to get the date or date range window shown in the picture.

  1. Open the Windows File Explorer

  2. In the search box, in the top right corner of the window type datemodified:

  3. After datemodified: has been typed the “Select a date or date range” window will appear, select the date or date range for when you believe the file was last modified.

  4. Depending on the dates this search may take a few seconds to a minute to complete.

Source: Find files by date modified in Windows

“A Guide to Becoming a Full-Stack Developer in 2017”

Being a Full-Stack Developer doesn’t mean that you have necessarily mastered everything required to work with the front-end or back-end, but it means that you are able to work on both sides and understand what is going on when building an application.

Full-Stack Web Development, according to the Stack Overflow 2016 Developer Survey, is the most popular developer occupation today. It’s no wonder then that there are dozens of online and in-person programs that will help people become Full-Stack Developers and then even assist these new developers land high-paying programming jobs.

Some popular online programs can be found on Lynda, Udacity, Coursera, Thinkful, General Assembly, and so much more. Aside from these online programs, there are also in-person coding bootcamps that are teaching people the skills required to become web developers.

In this article I won’t be discussing which websites or coding bootcamps have the best web development programs, instead I will be providing a definitive guide to what I believe are the most important skills required to become a Full-Stack Web Developer today and land a job if you’ve never coded before. I will be basing the list off of three things:

  1. A combination of what most programs in 2017 are teaching students.
  2. My own personal experiences from interviewing at companies for developer positions in the past and also interviewing potential candidates for current Full-Stack Developer positions at my current company.
  3. Stories and feedback from people on Coderbyte who have been accepted to coding bootcamps and then proceeded to get programming jobs (see below).

 

“A Guide to Becoming a Full-Stack Developer in 2017” @borowskidaniel https://medium.com/coderbyte/a-guide-to-becoming-a-full-stack-developer-in-2017-5c3c08a1600c

Code Like a Pythonista: Idiomatic Python

Dictionary and Iterators

Dictionaries implement a sq_contains slot that implements the same test as the has_key() method. This means that we can write

if k in dict: ...
which is equivalent to
if dict.has_key(k): ...

Dictionaries implement a tp_iter slot that returns an efficient iterator that iterates over the keys of the dictionary. During such an iteration, the dictionary should not be modified, except that setting the value for an existing key is allowed (deletions or additions are not, nor is the update() method). This means that we can write

    for k in dict: ...

which is equivalent to, but much faster than

for k in dict.keys(): ...

as long as the restriction on modifications to the dictionary (either by the loop or by another thread) are not violated.

Add methods to dictionaries that return different kinds of iterators explicitly:

for key in dict.iterkeys(): ...
for value in dict.itervalues(): ...
for key, value in dict.iteritems(): ...

This means that for x in dict is shorthand for for x in dict.iterkeys().

Other mappings, if they support iterators at all, should also iterate over the keys. However, this should not be taken as an absolute rule; specific applications may have different requirements.

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.

navs = {} for (portfolio, equity, position) in data: navs.setdefault(portfolio, 0) navs[portfolio] += position * prices[equity]

Source: http://www.omahapython.org/IdiomaticPython.html

React continues to dominate the front-end landscape

“React continues to dominate the front-end landscape, and 2017 provided one of the most anticipated releases yet with version 16. It includes the fiber architecture which enables asynchronous UI rendering. This release also makes it much easier to manage unexpected application failures by providing error boundaries along with many other features.”

@TreyHuffine https://levelup.gitconnected.com/a-recap-of-front-end-development-in-2017-7072ce99e727

PLSQL NOT_DATA_FOUND and CURSORS

Here we are common problem in PLSQL. We try find answer for one common question in programing databases. Is the specyfic record exist in other table or not exist? Some examples below show how to menage this problem:

NOT_DATA_FOUND Example
DECLARE
    VAR_SUPP_NM VARCHAR2(100);
    VAR_SUPP_ID  NUMBER := 1;
    WHILE_VAR CHAR := 'Y';
BEGIN
  SELECT SUPP_NM
    INTO VAR_SUPP_NM
    FROM TEST.SUPPLIER
   WHERE SUPP_ID = VAR_SUPP_ID;

 DBMS_OUTPUT.PUT_LINE('DATA FOUND');

exception
  when no_data_found then 
  	-- here some code when data ont exist
	DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');

END;

In line 11 and 14 we have place to insert own code. Other solution we found when we use define explicit cursor:

Explicit Cursor Used to Fetch Just One Value
CREATE FUNCTION f_get_name (ip_emp_id IN NUMBER) RETURN VARCHAR2
AS
CURSOR c IS SELECT ename FROM emp WHERE emp_id = f_get_name.ip_emp_id;
lv_ename emp.ename%TYPE;
BEGIN
  OPEN c;
  FETCH c INTO lv_ename;
  IF (SQL%NOTFOUND) THEN
     RAISE NO_DATA_FOUND;
  ENDIF;
  FETCH c INTO lv_ename;
  IF (SQL%FOUND) THEN
    RAISE TOO_MANY_ROWS;
  ENDIF;
  CLOSE c;
  RETURN lv_ename;
END;

Explicit Cursors and Bulk Processing
CREATE OR REPLACE PROCEDURE refresh_store_feed AS
TYPE prod_array IS TABLE OF store_products%ROWTYPE INDEX BY BINARY_INTEGER;
l_prod prod_array;
CURSOR c IS
  SELECT product
    FROM listed_products@some_remote_site;
BEGIN
  OPEN C;
  LOOP
    FETCH C BULK COLLECT INTO l_prod LIMIT 100;
  FOR i IN 1 .. l_csi.COUNT
    LOOP
     /* ... do some procedural code here that cannot be done in SQL to l_csi(i) ... */
    END LOOP;
  FORALL i IN 1 .. l_csi.COUNT
    INSERT INTO store_products (product) VALUES (l_prod(i));
    EXIT WHEN c%NOTFOUND;
  END LOOP;
CLOSE C;
END;
/

REF Cursors in Brief

Though there are two other sections in this chapter that cover REF cursors more fully (“Static REF Cursors” and “Dynamic REF Cursors”), a brief overview regarding these types of cursors warrants mention in this section due to their structure: they must be explicitly opened, fetched from, and closed. If you are returning a result set to a client, a great way to avoid lots of repetitive code is to use a REF cursor. Essentially, the cursor you open usually depends on what input you receive from the requesting client. Listing 10-4 provides a brief example of a REF cursor scenario in PL/SQL:

REF Cursors Work Dynamically, But Are Declared

DECLARE
prod_cursor sys_refcursor;
BEGIN
	IF ( input_param = 'C' )
	THEN
		OPEN prod_cursor FOR
		SELECT * FROM prod_concepts
			WHERE concept_type = 'COLLATERAL'
				AND concept_dt < TO_DATE( '01-JAN-2003', 'DD-MON-YYYY');
	ELSE
		OPEN prod_cursor FOR
		SELECT * FROM prod_concepts
			WHERE concept_category = 'ADVERTISING';
	END IF;
LOOP

A Select … Into Cursor vs. a For … In Cursor
BEGIN
    FOR x IN (SELECT * FROM dual) LOOP ... END LOOP;
	END;
DECLARE
	CURSOR c IS SELECT * FROM dual;
BEGIN
	OPEN c;
	LOOP
		FETCH c INTO …
		EXIT WHEN c%NOTFOUND;
			…
		END LOOP;
		CLOSE c;
	END;
	BEGIN
		SELECT *INTO ...FROM dual;
		END;
	DECLARE
		CURSOR c IS SELECT * FROM dual;
		l_rec dual%ROWTYPE;
	BEGIN
	OPEN c;
	FETCH c INTO l_rec;
	IF (SQL%NOTFOUND)
	THEN
		RAISE NO_DATA_FOUND;
	END IF;
	FETCH c INTO l_rec;
	IF (SQL%FOUND)CHAPTER 
	THEN
		RAISE TOO_MANY_ROWS;
	END IF;
	CLOSE c;
END;

 

How to Open Magnet Link In Browser – Make Tech Easier

If you are a frequent torrent user, you will come across magnet link. Magnet link has been around for quite some time, but it is only recently when the Pirate Bay confirmed that it would switch to DHT, PEX and magnet links that makes people start to wonder what magnet link is all about. You can read about the full explanation of DHT, PEX and Magnet Links here. In short, it is a method for you to download files without having to first download the .torrent file. You can start the download with just a link (or URL).

Oracle 10gR2+ conditional PL/SQL Compilation

Examples

Example 1
create or replace procedure p
as
begin
  $IF $$debug_code
  $THEN
    dbms_output.put_line( 'Our debug code' );
    dbms_output.put_line( 'Would go here' );
  $END
  dbms_output.put_line( 'And our real code here' );
end;
/

alter procedure P compile
plsql_ccflags = 'debug_code:true' reuse settings
/

Example 2
create or replace procedure p2
as
begin
 $if $$plsql_debug
 $then
    $error 'This program must be compiled with PLSQL_DEBUG disabled' $end
 $end
 dbms_output.put_line( 'This is where it happens!' );
end;
/
Procedure created
ALTER SESSION SET PLSQL_DEBUG=TRUE
/
alter procedure p2 compile
/
Warning: Procedure altered with compilation errors.
show err
Errors for PROCEDURE P2:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/5      PLS-00179: $ERROR: This program must be compiled with PLSQL_DEBUG
         disabled

Source:

  1. http://www.oracle.com/technetwork/database/features/plsql/overview/plsql-conditional-compilation-133587.pdf
  2. Oracle 10gR2 – Conditional PL/SQL Compilation – AMIS Oracle and Java Blog

Alternative way monitoring Zabbix via PHP API

Purpose create this project

Display: alarms, warnings from Zabbix on PHP page. In this case I had to show some information about my services on independent web page.

Set enviroment for Zabbix PHP API

What you need to start:

  1. Zabbix API 2+ – doc: https://www.zabbix.com/documentation/, download: https://www.zabbix.com/download
  2. Apache 2.4+
  3. PHP 7+
  4. Bootstap 3+
  5. I have defined some alarms in Zabbix and I want to observe it in “application”. Just use https://github.com/confirm/PhpZabbixApi and https://www.zabbix.com/documentation/2.2/manual/api
  6. Fronted i use Bootstrap http://getbootstrap.com/javascript/#buttons and some additional lib’s https://datatables.net/extensions/index it is good effective way to make it simple an easy.
  7. Git (Btubucket, Github)

Work set

Zabbix PHP API

PhpZabbixApi is an open-source PHP class library to communicate with the Zabbix™ JSON-RPC API. Because PhpZabbixApi is generated directly from the origin Zabbix™ 2.0 PHP front-end source code / files, each real Zabbix™ JSON-RPC API method is implemented (hard-coded) directly as an own PHP method. This means PhpZabbixApi is IDE-friendly, because you’ve a PHP method for each API method, and there are no PHP magic functions or alike.

Bootstrap

Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.

Source code on Bitbucket

<?php
/**
 * ZabbixAPI_class.php Copyright 2017 by Karol Preiskorn
 *
 * @version 18.03.2017 21:35:17 Karol Preiskorn Init
 * @version 19.03.2017 16:37:59 KPreiskorn ZabbixAPI_class.php Export to BB
 *
 */
require_once 'PhpZabbixApi-2.4.5/build/ZabbixApi.class.php';
include 'header.php';

use ZabbixApi\ZabbixApi;

/**
 *
 * @todo add LDAP via uptime
 *
 * @var string $uri
 *
 */

$uri = "http://zabixx";
$username = "user";
$password = "pass";

// set passwords and uri
include "passwords.php";

/**
 * poor print_r function
 *
 * @param unknown $val
 *
 */
function print_r2($val)
{
    echo '<pre>';
    print_r($val);
    echo '</pre>';
}

/**
 * Better print_r function
 */
function obsafe_print_r($var, $return = false, $html = true, $level = 0)
{
    $spaces = "";
    $space = $html ? " " : " ";
    $newline = $html ? "<br />" : "\n";
    for ($i = 1; $i <= 6; $i ++) {
        $spaces .= $space;
    }
    $tabs = $spaces;
    for ($i = 1; $i <= $level; $i ++) {
        $tabs .= $spaces;
    }
    if (is_array($var)) {
        $title = "Array";
    } elseif (is_object($var)) {
        $title = get_class($var) . " Object";
    }
    $output = "<b>" . $title . "</b>" . $newline . $newline;
    foreach ($var as $key => $value) {
        if (is_array($value) || is_object($value)) {
            $level ++;
            $value = obsafe_print_r($value, true, $html, $level);
            $level --;
        }
        $output .= $tabs . "[" . $key . "] => [" . $value . "]" . $newline;
    }
    if ($return)
        return $output;
    else
        echo "<pre>" . $output . "</pre>";
}

/**
 *
 * Generate bootstrap table with headers and coun of elements
 *
 * @param string $title
 * @param unknown $count
 * @param unknown $id
 */
function print_table_header($title, $count, $headers, $id)
{
    print('<div class="panel panel-default">' . "\n");
    print('<div class="panel-heading">' . $title . ' <a href="#"> <span class="badge">' . $count . '</span></a></div>' . "\n");
    print("<table id='" . $id . "' class='table table-striped table-bordered'>" . "\n");

    print("<thead><tr>" . "\n");
    foreach ($headers as $header) {
        print("<th>" . $header . "</th>" . "\n");
    }
    print("</tr>\n</thead>\n<tbody>" . "\n");
}

try {
    // connect to Zabbix API
    $api = new ZabbixApi($uri, $username, $password);

    // get all graphs
    $alerts = $api->alertGet();
    // print_r2 ( $graphs [0] );

    arsort($alerts);

    $headers = array(
        "Alert Id",
        "Event Id",
        "Date time",
        "Sent to",
        "Subject",
        "Message"
    );

    print_table_header('Alerts', count($alerts), $headers, 'alarms');

    // print all alerts
    foreach ($alerts as $alert) {
        if ($alert->sendto != "") {
            if (strpos($alert->subject, "PROBLEM:") !== false) {
                $alerttype = "class='warning'";
            } else {
                $alerttype = "class='normal'";
            }
            if (preg_match("/Original event ID: ([0-9]{4,12})/", $alert->message, $regs)) {
                $eventid_org = "[link: <a href='#" . $regs[1] . "'>" . $regs[1] . "</a>]";
            } else {
                $eventid_org = "Not found Original event ID";
            }
            printf("<tr id='%s' %s><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" . "\n", $alert->eventid, $alerttype, $alert->alertid, $alert->eventid, date("Y-m-d h:i", $alert->clock), $alert->sendto, $alert->subject, $alert->message . " " . $eventid_org);
        }
    }
    print("</tbody>\n</table>\n</div>\n");

    // get all graphs
    $graphs = $api->graphGet();
    $header_graph = array(
        "Graph Id",
        "Description"
    );
    print_table_header('Graph', count($graphs), $header_graph, 'graph');

    // print all graph IDs
    foreach ($graphs as $graph) {
        printf("<tr><td>%8d</td><td>%s</td></tr>\n", $graph->graphid, $graph->name);
    }
    print("</tbody>\n</table>\n</div>\n");

    print('<div class="panel-footer">

        <p>© T-Mobile Polska Company | OSS development powered by Karol Preiskorn | internal use</p>

      </div>');
    print("</div></body></html>"); // end of container

    // print "<h1>Alerts... agian in raw</h2>";
                                       // obsafe_print_r ( $alerts, FALSE, TRUE );
} catch (Exception $e) {
    // Exception in ZabbixApi catched
    echo $e->getMessage();
}
?>

<?php
/**
 *
 * HTML 5
 *
 */
?>
<!DOCTYPE html>
<html>
<head>
<title>Zabbix</title>

<link rel="stylesheet" type="text/css"
	href="https://cdn.datatables.net/v/bs-3.3.7/jq-2.2.4/dt-1.10.13/af-2.1.3/b-1.2.4/b-colvis-1.2.4/fh-3.1.2/kt-2.2.0/r-2.1.1/rr-1.2.0/sc-1.4.2/se-1.2.0/datatables.min.css" />
<script type="text/javascript"
	src="https://cdn.datatables.net/v/bs-3.3.7/jq-2.2.4/dt-1.10.13/af-2.1.3/b-1.2.4/b-colvis-1.2.4/fh-3.1.2/kt-2.2.0/r-2.1.1/rr-1.2.0/sc-1.4.2/se-1.2.0/datatables.min.js"></script>

<script>
$(document).ready(function() {
    $('#alarms').DataTable( {
        deferRender:    true,
        scrollY:        400,
        scrollCollapse: false,
        scroller:       false
    } );
} );


$(document).ready(function() {
	$('#graph').DataTable({
        deferRender:    true,
        scrollY:        400,
        scrollCollapse: false,
        scroller:       false
    } );
} );
</script>

</head>

<body>
	<div class="container">
		<div class="jumbotron">
			<h1>Zabbix Alarm monitoring</h1>
			<p>Aplikacja monitoruje alarmy z Zabbix.</p>

			<a class="btn btn-primary btn-lg"
				href="http://wrex/zabbix/zabbix.php?action=dashboard.view"
				role="button">Zabbix Dashboard</a> <a class="btn btn-lg"
				href="#alarms" role="button">Alarms</a> <a class="btn btn-lg"
				href="#graph" role="button">Graph</a> <a class="btn btn-lg"
				href="simple-json.php" role="button">Simple JSON</a>


			<button class="btn btn-primary" type="button" data-toggle="collapse"
				data-target="#collapseExample" aria-expanded="false"
				aria-controls="collapseExample">About</button>


			<div class="collapse" id="collapseExample">
				<div class="well">Aplikacja monitoruje alarmy z OSS Zabbix na
					serwerze wrex. Dost�p do API poprzez klas� PHP -> ZabbixApi. Opis
					API
					https://www.zabbix.com/documentation/2.2/manual/api/reference/history/get
				</div>
			</div>

		</div>

<?php

/**
 * Zabbix monitoring in PHP
 *
 * @author Karol Preiskorn
 *
 * @version 2017-04-16 KP init
 * @version 17.03.2017 14:47:16 Karol Preiskorn dodanie informacji na temat Alert�w
 * @version 17.03.2017 18:07:38 Karol Preiskorn - dodanie synchronizacji
 * @version 9 gru 2017 12:47:16 KPreiskorn simple-json.php add composer and manage password
 *
 *
 *
 * phpinfo ();
 *
 */
$uri = "http://zabixx";
$username = "user";
$password = "pass";

// set passwords and uri
include "passwords.php";
/**
 *
 * @param unknown $in
 * @param number $indent
 * @param string $from_array
 * @return string
 */
function json_readable_encode($in, $indent = 0, $from_array = true) {
	$_myself = __FUNCTION__;
	$_escape = function ($str) {
		return preg_replace ( "!([\b\t\n\r\f\"\\'])!", "\\\\\\1", $str );
	};

	$out = '';

	foreach ( $in as $key => $value ) {
		$out .= str_repeat ( "\t", $indent + 1 );
		$out .= "\"" . $_escape ( ( string ) $key ) . "\": ";

		if (is_object ( $value ) || is_array ( $value )) {
			$out .= "\n";
			$out .= $_myself ( $value, $indent + 1 );
		} elseif (is_bool ( $value )) {
			$out .= $value ? 'true' : 'false';
		} elseif (is_null ( $value )) {
			$out .= 'null';
		} elseif (is_string ( $value )) {
			$out .= "\"" . $_escape ( $value ) . "\"";
		} else {
			$out .= $value;
		}

		$out .= ",\n";
	}

	if (! empty ( $out )) {
		$out = substr ( $out, 0, - 2 );
	}

	$out = str_repeat ( "\t", $indent ) . "{\n" . $out;
	$out .= "\n" . str_repeat ( "\t", $indent ) . "}";

	return $out;
}

/**
 *
 * @param unknown $array
 */
function expand_arr($array) {
	foreach ( $array as $key => $value ) {
		if (is_array ( $value )) {
			echo "<i>" . $key . "</i>:<br>";
			expand_arr ( $value );
			echo "<br>\n";
		} else {
			echo "<i>" . $key . "</i>: " . $value . "<br>\n";
		}
	}
}
/**
 *
 * @param unknown $uri
 * @param unknown $data
 * @return mixed
 */
function json_request($uri, $data) {
	$json_data = json_encode ( $data );
	$c = curl_init ();
	curl_setopt ( $c, CURLOPT_URL, $uri );
	curl_setopt ( $c, CURLOPT_CUSTOMREQUEST, "POST" );
	curl_setopt ( $c, CURLOPT_RETURNTRANSFER, true );
	curl_setopt ( $c, CURLOPT_POST, $json_data );
	curl_setopt ( $c, CURLOPT_POSTFIELDS, $json_data );
	curl_setopt ( $c, CURLOPT_HTTPHEADER, array (
			'Content-Type: application/json',
			'Content-Length: ' . strlen ( $json_data )
	) );
	curl_setopt ( $c, CURLOPT_SSL_VERIFYPEER, false );
	$result = curl_exec ( $c );

	echo "<b>JSON Request:</b><br>\n";
	echo $json_data . "<br><br>\n";

	echo "<b>JSON Answer:</b><br>\n";
	echo $result . "<br><br>\n";

	/*
	 * echo "<b>CURL Debug Info:</b><br>\n";
	 * $debug = curl_getinfo ( $c );
	 * echo expand_arr ( $debug ) . "<br><hr>\n";
	 */

	return json_decode ( $result, true );
}
/**
 *
 * @param unknown $uri
 * @param unknown $username
 * @param unknown $password
 * @return unknown
 */
function zabbix_auth($uri, $username, $password) {
	$data = array (
			'jsonrpc' => "2.0",
			'method' => "user.login",
			'params' => array (
					'user' => $username,
					'password' => $password
			),
			'id' => "1"
	);
	$response = json_request ( $uri, $data );
	return $response ['result'];
}

/**
 *
 * @param unknown $uri
 * @param unknown $authtoken
 * @return unknown
 */
function zabbix_get_hostgroups($uri, $authtoken) {
	$data = array (
			'jsonrpc' => "2.0",
			'method' => "hostgroup.get",
			'params' => array (
					'output' => "extend",
					'sortfield' => "name"
			),
			'id' => "2",
			'auth' => $authtoken
	);
	$response = json_request ( $uri, $data );
	return $response ['result'];
}
/**
 *
 * @param unknown $uri
 * @param unknown $authtoken
 */
function zabbix_get_alert($uri, $authtoken) {
	$data = array (
			"jsonrpc" => "2.0",
			"method" => "alert.get",
			"params" => array (
					"output" => "extend",
					"actionids" => "3"
			),
			"auth" => $authtoken,
			"id" => 1
	);
	$response = json_request ( $uri, $data );
	return $response ['result'];
}

/**
 *
 * @var Ambiguous $authtoken
 */
print "<h1>Auth</h1>";
$authtoken = zabbix_auth ( $uri, $username, $password );

print "<h1>HostGrups</h1>";
expand_arr ( zabbix_get_hostgroups ( $uri, $authtoken ) );
print "<h2>json_readable_encode</h2>";
json_readable_encode ( zabbix_get_hostgroups ( $uri, $authtoken ) );
print "<h1>Alerts</h1>";
expand_arr ( zabbix_get_alert ( $uri, $authtoken ) );
?>

RegEx never endig story….

It is example of use RegEx to prepare SQL data for SELECT/UPDATE operation.

/^.*/gm and substitution: '\0',

Explanation

  1. ^ asserts position at start of a line
  2. .* matches any character (except for line terminators)
  3. * Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
  4. Global pattern flags
    1. g modifier: global. All matches (don’t return after first match)
    2. m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)

Example

This example simple replace MBS to ,'MBS'. For example when you have many selected values SQL (in one column) and need convert it to running query.

SELECT * FROM TABLE WHERE ID IN(...)

AAA
AAB
AAC

Convert it to:

SELECT * FROM TABLE WHERE ID IN(
'AAA',
'AAB',
'AAC')

Very good tools for testing: https://regex101.com/ and here is this example: https://regex101.com/r/34repv/1

other good option to test yours regex query is:

  • https://www.regextester.com/
  • https://www.freeformatter.com/regex-tester.html

How its run?

Simple by Sublimetext, Notepad++, Visual Code –> Find/Replace command

Regular Expressions Cheat Sheet

A regular expression specifies a set of strings that matches it. This cheat sheet is based off Python 3’s Regular Expressions (http://docs.python.org/3/library/re.html) but is designed for searches within Sublime Text.

Special Characters

  • \ Escapes special characters or signals a special sequence.
  • . Matches any single character except a newline.
  • ^ Matches the start of the string.
  • $ Matches the end of the string.
  • * Greedily matches 0 or more repetitions of the preceding RE.
  • *? Matches 0 or more repetitions of the preceding RE.
  • + Greedily matches 1 or more repetitions of the preceding RE.
  • +? Matches 1 or more repetitions of the preceding RE.
  • ? Greedily matches 0 or 1 repetitions of the preceding RE.
  • ?? Matches 0 or 1 repetitions of the preceding RE.
  • A|B Matches A, if A is unmatched then matches B, where A and B are arbitrary REs.
  • {m} Matches exactly m many repetitions of the previous RE.
  • {m,n} Greedily matches from m many to n many repetitions of the previous RE.
  • {m,n}? Matches m many to n many repetitions of the previous RE.

[…] Indicates a set of characters to match.

[amk]

Matches ‘a’, ‘m’, or ‘k’.

[a-z]

Matches ‘a’ through ‘z’.

[a-f0-7]

Matches ‘a’ through ‘f’ or ‘0’ through ‘7’.

[a\-z]

Matches ‘a’, ‘-‘, or ‘z’.

[a-]

  • Matches ‘a’ or ‘-‘.
  • [-a] Matches ‘a’ or ‘-‘.
  • [(+*)] Matches ‘(‘, ‘+’, ‘*’, or ‘)’. [] matches special characters literally.
  • [\w] Matches the character class for ‘\w’. See character classes.
  • [^5] Matches anything other than ‘5’. ‘^’ forms the complementary set only as the first character in a set.
  • []()] Matches ‘]’, ‘(‘, and ‘)’. ‘]’ is taken literally only as the first character in a set.
  • [()\]] Matches ‘]’, ‘(‘, and ‘)’.

(…) Matches the RE inside the parenthesis and assigns a new group.
(?P…) The RE matched is accessible by the group indicated by name.

  • (?…) Extension notation which changes a RE’s behavior. These do not assign a new group.
  • (?aiLmsux) Sets the corresponding flag to each letter. Does not work within Sublime Text.
  • (?:…) A non-capturing version of parenthesis. The matched substring cannot be retrieved later.
  • (?P=name) Matches the substring matched by the group named name.
  • (?#…) A comment, the contents are ignored.
  • (?=…) Lookahead assertion, the preceding RE only matches if this matches.
  • (?!…) Negative lookahead assertion, the preceding RE only matches if this doesn’t match.
  • (?<=…) Positive lookbehind assertion, the following RE will only match if preceded with this fixed length RE.
  • (?<!…) Negative lookbehind assertion, the following RE will only match if not preceded with this fixed length RE.
  • (?(id)true|false) If group id exists then uses the true RE, else use the false RE.

Character classes

  • \1 Matches the contents of the group labelled by the same number. Acceptable numbers are 1-99.
  • \A Matches at the start of the current string.
  • \b Matches the empty string at the beginning or end of a word. \b matches the boundary between \w and \W.
  • \B Matches the empty string not at the beginning or end of a word.
  • \d Matches any Unicode decimal digit, including 0-9.
  • \D Matches any Unicode non-decimal digit.
  • \s Matches any Unicode whitespace character, including ‘ ‘, \t, \n, \r, \f and \v.
  • \S Matches any Unicode non-whitespace character.
  • \w Matches any Unicode word character, including a-z, A-Z, and 0-9.
  • \W Matches any Unicode non-word character.
  • \Z Matches at the end of the string.
  • \a Matches the ASCII Bell ().
  • \f Matches the ASCII Formfeed ( ).
  • \n Matches the ASCII Linefeed.
  • \r Matches the ASCII Carriage Return ().
  • \t Matches the ASCII Horizontal Tab.
  • \v Matches the ASCII Vertical Tab ( ).

SQL corner: 7 kind of SQL Joins. Including : INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN

Infographic of the 7 kind of SQL Joins. Including : INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, with or without the intersect. Very useful for web developer. Source : http://sql.sh #SQL #JOIN

7-sql-join

Source: Pinterest http://sql.sh/2401-sql-join-infographie

Other sources about JOIN

SublimeText 3 tips and customization

I think that is one of best text editor for Linux and W$. Bellow I add some tips and usefully configuration.

Regexp conversion to Wiki links

Conversion to Wiki links add [ before and ] after text.

Find what: (http.{2,})
Relpace to: [\1]

Polish letters in Sublimetext 3

Polskie znaki diakrytyczne w Sublime Text 3 – dodanie wpisów do Key Bindings – User (na platformie Windows jest to plik Default (Windows).sublime-keymap):

[
{"keys": ["control+alt+a"], "command": "insert", "args": {"characters": "ą"}},
{"keys": ["control+alt+c"], "command": "insert", "args": {"characters": "ć"}},
{"keys": ["control+alt+e"], "command": "insert", "args": {"characters": "ę"}},
{"keys": ["control+alt+l"], "command": "insert", "args": {"characters": "ł"}},
{"keys": ["control+alt+n"], "command": "insert", "args": {"characters": "ń"}},
{"keys": ["control+alt+o"], "command": "insert", "args": {"characters": "ó"}},
{"keys": ["control+alt+s"], "command": "insert", "args": {"characters": "ś"}},
{"keys": ["control+alt+x"], "command": "insert", "args": {"characters": "ź"}},
{"keys": ["control+alt+z"], "command": "insert", "args": {"characters": "ż"}},
{"keys": ["shift+control+alt+a"], "command": "insert", "args": {"characters": "Ą"}},
{"keys": ["shift+control+alt+c"], "command": "insert", "args": {"characters": "Ć"}},
{"keys": ["shift+control+alt+e"], "command": "insert", "args": {"characters": "Ę"}},
{"keys": ["shift+control+alt+l"], "command": "insert", "args": {"characters": "Ł"}},
{"keys": ["shift+control+alt+n"], "command": "insert", "args": {"characters": "Ń"}},
{"keys": ["shift+control+alt+o"], "command": "insert", "args": {"characters": "Ó"}},
{"keys": ["shift+control+alt+s"], "command": "insert", "args": {"characters": "Ś"}},
{"keys": ["shift+control+alt+x"], "command": "insert", "args": {"characters": "Ź"}},
{"keys": ["shift+control+alt+z"], "command": "insert", "args": {"characters": "Ż"}}
]

Adding comma to each line using sublime text

To add comma to any line

  1. Select the lines you want to modify
  2. CTRL + SHIFT + L
  3. RIGHT_ARROW
  4. COMMA

Using ctrl + shift + L is how you can modify all selected lines. Very handy 🙂 Make batch edits with Multiple Selections.

Column Selection can be used to select a rectangular area of a file. Column selection doesn’t operate via a separate mode, instead it makes use of multiple selections.

You can use additive selections to select multiple blocks of text, or subtractive selections to remove a block.

‘Find What’: $ // matching all ends of your lines
‘Replace With’: , // replaces all line ends with a coma

MXU20623GAD
MXU20899GAA
MXU20975GAA
MXU24246GAD
MXU29901GAA
MXU30079GAA
MXU30090GAA
MXU34015GAA
Sublimetext array

Solve this problem

Source: Best of Sublime Text 3: Features, Plugins, and Settings | Scotch

Emmet is usefull

Emmet is an absolute time saver. You can build HTML on the fly easily and quickly.

To Use: ctrl + alt + enter and start typing your Emmet styled HTML

  • ctrl + d: Select the current word and the next same word
  • ctrl + click: Every place you click will create a cursor to edit
  • ctrl + shift + f AND alt + enter: Find a word in your files and then select them all
Emmet in sublimetext

Check out our Emmet Interactive Guide to learn more and try out Emmet for yourself.

DocBlockr

A really great way to easily create doc blocks for many languages including JavaScript, PHP, and CoffeeScript. Just type in /** above your function and press tab. Watch the magic as DocBlockr takes the function name and variables and creates your doc block.

sublime-docblockr-example-start
sublime-docblockr-example-finish

BracketHighlighter

This plugin provides bracket highlighting for all sorts of brackets.

brackethighlighter

Sublime Text 3 is an amazing piece of software. To start, it is a clean, functional, and fast code editor. Not only does it have incredible built in features (multi-edit and vim mode), but it has support for plugins, snippets, and many other things.

Source: Best of Sublime Text 3: Features, Plugins, and Settings | Scotch

Reference links

Arrays of Pointers

9.4 Arrays of Pointers

As seen in the last example, sorting an array of strings requires swapping the strings which can require copying a lot of data. For efficiency, it is better to avoid actual swapping of data whenever a data item is large, such as a string or an entire data base record. In addition, arrays may be needed in more than one order; for example, we may need an exam scores array sorted by Id number and by weighted scores; or, we may need strings in both an unsorted form and a sorted form.
In either of these cases, we must either keep two copies of the data, each sorted differently, or find a more efficient way to store the data structure. The solution is to use pointers to elements of the array and swap pointers. Consider some examples:

int data1, data2, *ptr1, *ptr2, *save;
data1 = 100; 
data2 = 200; 
ptr1 = *data1; 
ptr2 = *data2;

We could swap the values of the data and store the swapped values in data1 and data2 or we could simply swap the values of the pointers:

save = ptr1;
ptr1 = ptr2;
ptr2 = save;

We have not changed the values in

data1

and data2 but ptr1 now accesses data2 and ptr2 access data1. We have swapped the pointer values so they point to objects in a different order. We can apply the same idea to strings:

char name1[] = "John";
char name2[] = "Dave";
char *p1, *p2, *save;
p1 = name1; 
p2 = name2;

Pointers p1 and p2 point to strings name1 and name2. We can now swap the pointer values so p1 and p2 point to name2 and name1, respectively.

In general, an array of pointers can be used to point to an array of data items with each element of the pointer array pointing to an element of the data array. Data items can be accessed either directly in the data array, or indirectly by dereferencing the elements of the pointer array. The advantage of a pointer array is that the pointers can be reordered in any manner without moving the data items. For example, the pointer array can be reordered so that the successive elements of the pointer array point to data items in sorted order without moving the data items. Reordering pointers is relatively fast compared to reordering large data items such as data records or strings. This approach saves a lot of time, with the additional advantage that the data items remain available in the original order. Let us see how we might implement such a scheme.

STRPTRS: Given an array of strings, use pointers to order the strings in sorted form, leaving the array unchanged.

We will use an array of character pointers to point to the strings declared as follows:

char * nameptr[MAX];

The array, nameptr[], is an array of size MAX, and each element of the array is a character pointer. It is then possible to assign character pointer values to the elements of the array; for example:

nameptr[i] = "John Smith";

The string "John Smith" is placed somewhere in memory by the compiler and the pointer to the string constant is then assigned to nameptr[i]. It is also possible to assign the value of any string pointer to nameptr[i]; for example, if s is a string, then it is possible to assign the pointer value s to nameptr[i]:

nameptr[i] = s;

In particular, we can read strings into a two dimensional array, names[][], and assign each string pointer, names[i] to the element of the pointer array, nameptr[]:

for (i = 0; i < MAX && gets(names[i]); i++)
          nameptr[i] = names[i];

The strings can then be accessed either by names[i] or by nameptr[i] as seen in Figure 9.4. We can then reorder the pointers in nameptr[] so that they successively point to the strings in sorted order as seen in Figure 9.4. We can then print the strings in the original order by accessing them through names[i]and print the strings in sorted order by accessing them through nameptr[i]. Here is the algorithm

/**
 * Zadania
 * -------
 * z1: Napisz program, który pokazuje, które atrybuty procesu macierzystego są dziedziczone przez proces potomny  uruchomiony za pomocą funkcji fork(), które zaś otrzymują nową wartość.
 * z2: Napisz program, który pokazuje, które atrybuty procesu są zachowane przez proces po wykonaniu funkcji exec().
 * z3: Napisz program, który wyświetla identyfikator procesu (PID) i nazwę związanego z nim polecenia dla wszystkich procesów uruchomionych przez użytkownika podanego w wierszu wywołania programu. Wskazówka: informacje te można uzyskać przeglądając katalog /proc z plików (interesują nas katalogi, których właścicielem jest dany  użytkownik) i pliki /proc/PID/status
 *
 * Każdy proces charakteryzuje się pewnymi atrybutami. Należą do nich:
 * Identyfikator procesu PID
 * Identyfikator procesu macierzystego PPID
 * Rzeczywisty identyfikator właściciela procesu
 * Rzeczywisty identyfikator grupy procesu
 * Efektywny identyfikator właściciela procesu
 * Efektywny identyfikator grupy procesu
 * Katalog bieżący i katalog główny
 * Maska tworzenia pliku
 * Identyfikator sesji
 * Terminal sterujący
 * Deskryptory otwartych plików
 * Ustalenia dotyczące obsługi sygnałów
 * Ustawienia zmiennych środowiskowych
 * Ograniczenia zasobów
 *
 *
 * Potomek dziedziczy z procesu potomnego wiele własności:
 rzeczywisty identyfikator użytkownika, rzeczywisty identyfikator grupy, obowiązujący identyfikator użytkownika, obowiązujący identyfikator grupy,
 identyfikatory dodatkowych grup,
 identyfikator sesji,
 terminal sterujący,
 sygnalizator ustanowienia identyfikatora użytkownika oraz sygnalizator ustanowienia identyfikatora grupy,
 deskryptory otwartych plików (są kopiowane)
 bieżący katalog roboczy,
 katalog główny,
 maskę tworzenia plików,
 maskę sygnałów oraz dyspozycje obsługi sygnałów,
 sygnalizator zamykania przy wywołaniu funkcji exec (close-on-exec) dla wszystkich otwartych deskryptorów plików,
 środowisko,
 przyłączone segmenty pamięci wspólnej,
 ograniczenia zasobów systemowych.
 Są jednak pewne różnice między procesem macierzystym a potomnym:
 wartość powrotu z funkcji fork,
 różne identyfikatory procesów,
 inne identyfikatory procesów macierzystych - w procesie potomnym jest to identyfikator procesu macierzystego; w procesie macierzystym identyfikator procesu macierzystego nie zmienia się,
 w procesie potomnym wartości tms_utime, tms_cutime i tms_ustime są równe 0,
 potomek nie dziedziczy rygli plików, ustalonych w procesie macierzystym,
 w procesie potomnym są zerowane wszystkie zaległe alarmy,
 w procesie potomnym jest zerowany zbiór zaległych sygnałów.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

extern char** environ;
char *prt_parent;

int glob = 1;           // zewnętrzna zmienna

/* Prints the environment, one environment variable to a line, of the process given by PID. */
char *print_process_environment(pid_t pid) {
    int fd;
    char filename[24];
    char environment[8192];
    size_t length;
    char* next_var;
    /* Generate the name of the environ file for the process. */
    snprintf(filename, sizeof(filename), "/proc/%d/environ", (int) pid);
    /* Read the contents of the file. */
    fd = open(filename, O_RDONLY);
    length = sizeof(environ);
    printf("Size of environ: %d\n", length);
    close(fd);
    /* read does not NUL-terminate the buffer, so do it here. */
    environment[length] = '\0';
    /* Loop over variables. Variables are separated by NULs. */
    next_var = environment;
    while (next_var < environment + length) { /* Print the variable. Each is NUL-terminated, so just treat it like an ordinary string. */ printf(">> %s\n", next_var);
        /* Advance to the next variable. Since each variable is
         NUL-terminated, strlen counts the length of the next variable,
         not the entire variable list. */
        next_var += strlen(next_var) + 1;
    }
    return (environment);
}


int main(int argc, char **argv) {
    int var = 100;              // zmienna automatyczna na stows
    char **env = environ;       // środowisko parent
    // zapamiętanie environ w tablicy

    printf("PROGRAM Z1\n\n");
    printf("Zmienne srodowiskowe parent: ----------------------------\n");
    while (*env) {
        printf("%s\n", *env++);
    }

    printf("---------------------------------------------------------\n");
    
    for (int i = 0; *env != NULL && gets(env[i]); i++)
              nameptr[i] = env[i];
    
    pid_t pid = fork();

    if (pid == 0) {
        // child process
        glob++;
        var++;
        printf("child process: pid %d, ppid %d, getuid %d, geteuid %d, getgid %d, glob = %d, var = %d\n", getpid(), getppid(), getuid(), geteuid(), getgid(),
                glob, var);

        /**
         * wy swietlenie zmiennych środowiskowych różnych od parent
         */
        printf("Zmienne srodowiskowe child różne od parent:\n");
        char environment_1[8192];
        char * prt_env = &environment_1;
        prt_env = print_process_environment(pid);
        char **env_child = environ;
        printf("Size of *char: %d\n", sizeof(environ));

        while (*env_child) {
            printf("compare - %s %d\n", *env_child, strcmp(*env_child++, *env++));
            //printf("%s -----\n", *env2++);
            //if (strcmp(*env2, ++*env) == 0) {
            //
            //} else {
            //printf("%s jest takie samo\n", *env2);
            //}
            //*env_child++;
            //*env++;
        }
        printf("-------------------- x --------------------\n");

    } else if (pid > 0) {
        // parent process
        printf("parent process: pid %d, ppid %d, getuid %d, geteuid %d, getgid %d, glob = %d, var = %d\n", getpid(), getppid(), getuid(), geteuid(), getgid(),
                glob, var);
    } else {
        // fork failed
        printf("fork() failed!\n");
        return (1);
    }

    printf("-- end of program pid %d\n", getpid());

    return (0);
}

Programowanie współbieżne C na Linux – przykłady

Przykładowe zadania z programowania współbieżnego na systemie Linux

  1. Napisz program, który pokazuje, które atrybuty procesu macierzystego są dziedziczone przez proces potomny uruchomiony za pomocą funkcji fork(), które zaś otrzymują nową wartość.
  2. Napisz program, który pokazuje, które atrybuty procesu są zachowane przez proces po wykonaniu funkcji exec().
  3. Napisz program, który wyświetla identyfikator procesu (PID) i nazwę związanego z nim polecenia dla wszystkich procesów uruchomionych przez użytkownika podanego w wierszu wywołania programu.
/**
 * Uzupełnij program shell z o „ręczną” obsługę potoków.
 * ----------------------------------------------------
 * Napisz program, który zbiera komunikaty od wielu programów i wyświetla je na ekranie. Do komunikacji użyj potoku nazwanego.
 *
 * Wskazówka: Utwórz program rdfifo, którego zadaniem jest utworzenie kolejki FIFO i czytanie z niej danych.
 * Utwórz program wrfifo, który otwiera kolejkę FIFO tylko do zapisu i wpisuje do niej dane (np. swoj pid i czas).
 *
 * Q: W jaki sposób przekażesz wspólną nazwę kolejki FIFO do tych programów?
 * A: przez zmienną statyczą
 *
 * Q: W jaki sposób zapewnić działanie programu zbierającego komunikaty również wtedy, kiedy nie ma programu piszącego do łącza?
 * A: przez proces pętli nieskończonej ze sleep
 *
 * Q: Jak zapewnić to, że komunikaty pochodzące od różnych programów wyświetlane są w całości, tzn. nie są rozdzielane  komunikatami od innych programów?
 * A: flush? (do sprawdzenia).
 *
 */

Wskazówka: informacje te można uzyskać przeglądając katalog /proc z plików (interesują nas katalogi, których właścicielem jest dany użytkownik) i pliki /proc/PID/status

Sources

C programing tutorial

 

Example solution 1 (draft)

# README #



## Uzupełnij program shell z o „ręczną” obsługę potoków.

Napisz program, który zbiera komunikaty od wielu programów i wyświetla je na ekranie. Do komunikacji użyj potoku nazwanego. Wskazówka: Utwórz program rdfifo, którego zadaniem jest utworzenie kolejki FIFO i czytanie z niej danych.

* Q: W jaki sposób przekażesz wspólną nazwę kolejki FIFO do tych programów?
* A: przez zmienną statyczą
* Q: W jaki sposób zapewnić działanie programu zbierającego komunikaty również wtedy, kiedy nie ma programu piszącego do łącza?
* A: przez proces pętli nieskończonej ze sleep
* Q: Jak zapewnić to, że komunikaty pochodzące od różnych programów wyświetlane są w całości, tzn. nie są rozdzielane  komunikatami od innych programów?
* A: flush? (do sprawdzenia).

### Zrzut z działania:

```
[23:30:20](pid 17400) DEBUG: Passed rdfifo 73 - while1

karol@carlo:~/eclipse-workspaces/unx_sys_programming/Debug$ ./unx_sys_programming -w

Input option value=(null) set program to write to FIFO

[23:30:20](pid 17411) DEBUG: Passed wrfifo 148 : mkfifo exist: 17
[23:30:20](pid 17411) DEBUG: Passed wrfifo 157 - pipe opened to read-write
[23:30:20](pid 17400) DEBUG: Passed rdfifo 104 - Remove FIFO
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #0 test PID: 17411: text -> Thu Jan 28 23:36:02 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #0 test PID: 17411: text -> Thu Jan 28 23:36:02 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #1 test PID: 17411: text -> Thu Jan 28 23:36:03 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #1 test PID: 17411: text -> Thu Jan 28 23:36:03 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #2 test PID: 17411: text -> Thu Jan 28 23:36:04 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #2 test PID: 17411: text -> Thu Jan 28 23:36:04 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #3 test PID: 17411: text -> Thu Jan 28 23:36:05 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #3 test PID: 17411: text -> Thu Jan 28 23:36:05 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #4 test PID: 17411: text -> Thu Jan 28 23:36:06 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #4 test PID: 17411: text -> Thu Jan 28 23:36:06 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #5 test PID: 17411: text -> Thu Jan 28 23:36:07 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #5 test PID: 17411: text -> Thu Jan 28 23:36:07 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #6 test PID: 17411: text -> Thu Jan 28 23:36:08 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #6 test PID: 17411: text -> Thu Jan 28 23:36:08 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #7 test PID: 17411: text -> Thu Jan 28 23:36:09 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #7 test PID: 17411: text -> Thu Jan 28 23:36:09 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #8 test PID: 17411: text -> Thu Jan 28 23:36:10 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #8 test PID: 17411: text -> Thu Jan 28 23:36:10 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #9 test PID: 17411: text -> Thu Jan 28 23:36:11 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #9 test PID: 17411: text -> Thu Jan 28 23:36:11 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 180 - close fd
[23:30:20](pid 17400) DEBUG: Passed rdfifo 112 - EOF reader

[10]   Done                    ./unx_sys_programming -r

bash:~/eclipse-workspaces/unx_sys_programming/Debug$ ./unx_sys_programming -h

Program FIFO
Program bez argumentów tworzy named pipe a w procesie potomnym zapisuje do niego dane.
Program mozna wywołać z argumentami tak aby działał jako odczyt (r) z pipe lub zapis do pipe (w).
Zapisywane są do pipe couner, PID i curenttime.

Usage: ./unx_sys_programming [-r] [-w]
```

## Przykład użycia


```
./unx_sys_programming

```

lub


```
./unx_sys_programming -r
./unx_sys_programming -w
./unx_sys_programming -w
./unx_sys_programming -w
```

# Fork read environ - zadania

* z1: Napisz program, który pokazuje, które atrybuty procesu macierzystego są dziedziczone przez proces potomny  uruchomiony za pomocą funkcji fork(), które zaś otrzymują nową wartość.
* z2: Napisz program, który pokazuje, które atrybuty procesu są zachowane przez proces po wykonaniu funkcji exec().
* z3: Napisz program, który wyświetla identyfikator procesu (PID) i nazwę związanego z nim polecenia dla wszystkich procesów uruchomionych przez użytkownika podanego w wierszu wywołania programu. Wskazówka: informacje te można uzyskać przeglądając katalog /proc z plików (interesują nas katalogi, których właścicielem jest dany  użytkownik) i pliki /proc/PID/status
 
Każdy proces charakteryzuje się pewnymi atrybutami. Należą do nich

 * Identyfikator procesu PID
 * Identyfikator procesu macierzystego PPID
 * Rzeczywisty identyfikator właściciela procesu
 * Rzeczywisty identyfikator grupy procesu
 * Efektywny identyfikator właściciela procesu
 * Efektywny identyfikator grupy procesu
 * Katalog bieżący i katalog główny
 * Maska tworzenia pliku
 * Identyfikator sesji
 * Terminal sterujący
 * Deskryptory otwartych plików
 * Ustalenia dotyczące obsługi sygnałów
 * Ustawienia zmiennych środowiskowych
 * Ograniczenia zasobów
 
Potomek dziedziczy z procesu potomnego wiele własności: rzeczywisty identyfikator użytkownika, rzeczywisty identyfikator grupy, obowiązujący identyfikator użytkownika, obowiązujący identyfikator grupy, identyfikatory dodatkowych grup, identyfikator sesji, terminal sterujący, sygnalizator ustanowienia identyfikatora użytkownika oraz sygnalizator ustanowienia identyfikatora grupy, deskryptory otwartych plików (są kopiowane) bieżący katalog roboczy, katalog główny,
 maskę tworzenia plików, maskę sygnałów oraz dyspozycje obsługi sygnałów, sygnalizator zamykania przy wywołaniu funkcji exec (close-on-exec) dla wszystkich otwartych deskryptorów plików, środowisko, przyłączone segmenty pamięci wspólnej,
 ograniczenia zasobów systemowych. Są jednak pewne różnice między procesem macierzystym a potomnym:
 wartość powrotu z funkcji fork, różne identyfikatory procesów, inne identyfikatory procesów macierzystych - w procesie potomnym jest to identyfikator procesu macierzystego; w procesie macierzystym identyfikator procesu macierzystego nie zmienia się, w procesie potomnym wartości tms_utime, tms_cutime i tms_ustime są równe 0,
 potomek nie dziedziczy rygli plików, ustalonych w procesie macierzystym, w procesie potomnym są zerowane wszystkie zaległe alarmy, w procesie potomnym jest zerowany zbiór zaległych sygnałów.

#include <asm-generic/errno-base.h>

/**
 * Uzupełnij program shell z o „ręczną” obsługę potoków.
 * ----------------------------------------------------
 * Napisz program, który zbiera komunikaty od wielu programów i wyświetla je na ekranie. Do komunikacji użyj potoku nazwanego.
 *
 * Wskazówka: Utwórz program rdfifo, którego zadaniem jest utworzenie kolejki FIFO i czytanie z niej danych.
 * Utwórz program wrfifo, który otwiera kolejkę FIFO tylko do zapisu i wpisuje do niej dane (np. swoj pid i czas).
 *
 * Q: W jaki sposób przekażesz wspólną nazwę kolejki FIFO do tych programów?
 * A: przez zmienną statyczą
 *
 * Q: W jaki sposób zapewnić działanie programu zbierającego komunikaty również wtedy, kiedy nie ma programu piszącego do łącza?
 * A: przez proces pętli nieskończonej ze sleep
 *
 * Q: Jak zapewnić to, że komunikaty pochodzące od różnych programów wyświetlane są w całości, tzn. nie są rozdzielane  komunikatami od innych programów?
 * A: flush? (do sprawdzenia).
 *
 */
#define DEBUG_MODE

#ifdef DEBUG_MODE
#define logs(...) printf("[%s](pid %d) DEBUG: Passed %s %d - %s\n", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define logs_d(...) printf("[%s](pid %d) DEBUG: Passed %s %d - %s : %d\n", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define logs(...)
#endif

#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>

#define FIFOARG 1
#define PIPE_BUF 100
#define FIFO_PERMS (S_IRWXU | S_IWGRP| S_IWOTH)
#define FIFO "temp.fifo"

#define BUFFERSIZE 500000
char buf[BUFFERSIZE]; // read buf

char* mygettime() {
	time_t mytime;
	mytime = time(NULL);
	return (ctime(&mytime));
}

/**
 * Serwer read from named pipe
 * -----------------
 * @param argc
 * @param argv
 * @return
 */
int rdfifo() {

	int fifo, var;

	/* There are *two* ways the open can fail: the pipe doesn't exist
	 * yet, *or* it succeeded, but a different writer already opened
	 * it but didn't yet remove it.
	 */
	logs("reader start");
	while (1) {
		logs("while1");
		while ((fifo = open(FIFO, O_RDONLY)) == -1) {
			/* Since you didn't specify O_CREAT in the call to open, there
			 * is no way that FIFO would have been created by the
			 * reader.  If there *is* now a FIFO, a remove here
			 * would delete the one the writer created!
			 */
			sleep(1);
		}

		/* Get an exclusive lock on the file, failing if we can't get
		 * it immediately.  Only one reader will succeed.
		 */
		if (flock(fifo, LOCK_EX | LOCK_NB) == 0)
			break;

		/* We lost the race to another reader.  Give up and wait for
		 * the next writer.
		 */
		close(fifo);
	}
	/* We are definitely the only reader.
	 */

	/* *Here* we delete the pipe, now that we've locked it and thus
	 * know that we "own" the pipe.  If we delete before locking,
	 * there's a race where after we opened the pipe, a different
	 * reader also opened, deleted, and locked the file, and a new
	 * writer created a new pipe; in that case, we'd be deleting the
	 * wrong pipe.
	 */
	logs("Remove FIFO");
	remove(FIFO);
	while ((var = read(fifo, buf, BUFFERSIZE)) > 0) {
		printf("[%s](pid %d) DEBUG: Passed %s %d : reader reads record: %s", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, buf);
		/* No need to sleep; we'll consume input as it becomes available. */
	}

	close(fifo);
	logs("EOF reader");
	exit(0);

}

/**
 * Klient named pipe
 *
 * write to pipe
 *
 * @param argc
 * @param argv
 * @return
 */
int wrfifo(pid_t pid) {
	// time structs
	time_t rawtime;
	struct tm * timeinfo;

	int len, i;
	char buf[PIPE_BUF];
	int fd;
	int communicates = 0;

//	if ((unlink(FIFO)) == -1) {
//		logs("Error unlink FIFO")
//	} else {
//		logs("unlink fifo");
//	}

	if ((mkfifo(FIFO, FIFO_PERMS) == -1) && (errno != EEXIST)) {
		logs("Server failed to create a FIFO");
		return (1);
	} else if (errno == ENOENT) {
		printf("[%s](pid %d) DEBUG: Passed %s %d : No such file or directory - mkfifo errno: %d\n", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, errno);
	} else if (errno == EEXIST) {
		printf("[%s](pid %d) DEBUG: Passed %s %d : mkfifo exist: %d\n", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, errno);
	} else {
		printf("[%s](pid %d) DEBUG: Passed %s %d : No such file or directory - mkfifo errno: %d\n", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, errno);
	}

	if ((fd = open(FIFO, O_WRONLY)) == -1) {
		logs("Client failed to open log fifo for writing");
		return (1);
	} else {
		logs("pipe opened to read-write");
	}

	/**
	 * write some text to pipe
	 */
	for (i = 0; i < 10; i++) {
		sleep(1);
		//logs("time")
		time(&rawtime);
		timeinfo = localtime(&rawtime);
		sprintf(buf, "#%d test PID: %d: text -> %s", communicates++, (int) getpid(), asctime(timeinfo));
		len = strlen(buf);
		if (write(fd, buf, len) != len) {
			logs("Client failed to write");
			return (1);
		} else {
			printf("[%s](pid %d) DEBUG: Passed %s %d : client succesed write to pipe: %s", __TIME__, (int) getpid(), __FUNCTION__, __LINE__, buf);
		}
	}
	/* Wait for the child process to finish. */
	waitpid(pid, NULL, 0);
	sleep(1);
	logs("close fd");
	close(fd);
	return (0);
}

/**
 * main
 *
 * @return
 */
int main(int argc, char *argv[]) {
	pid_t pid;
	int i;

	/**
	 * analiza lini komend
	 *
	 */
	int opt = 0;
	char *in_fname = NULL;
	char *out_fname = NULL;

	/**
	 * funkcje programu
	 */
	while ((opt = getopt(argc, argv, "rwh")) != -1) {
		switch (opt) {
		case 'r':
			in_fname = optarg;
			printf("\nInput option value=%s set program read from FIFO", in_fname);
			rdfifo();
			exit(0);
			break;
		case 'w':
			out_fname = optarg;
			printf("\nInput option value=%s set program to write to FIFO", out_fname);
			wrfifo(pid);
			exit(0);
			break;
		case '?':
		case 'help':
		case 'h':
		default:
			printf("\nProgram FIFO\n");
			printf("------------\n");
			printf("Program bez argumentów tworzy named pipe a w procesie potomnym zapisuje do niego dane.\n");
			printf("Program mozna wywołać z argumentami tak aby działał jako odczyt (r) z pipe lub zapis do pipe (w).\n");
			printf("Zapisywane są do pipe couner, PID i curenttime.\n\n");
			printf("Usage: %s [-r] [-w]\n\n", argv[0]);

			exit(0);
			break;
		}
	}

	logs("start program");

	pid = fork();

	/* proces potomny */
	if (pid == (pid_t) 0) { /* brak obsługi błędów */
		/**
		 * Odczytywanie
		 */
		for (i = 0; i < 3; i++) {
			rdfifo();
			sleep(1);
		}
	}
	/* proces macierzysty */
	else {
		for (i = 0; i < 5; i++) {
			wrfifo(pid);

		}
	}
	logs("end main");
	return (0);
}

Zrzut z działania

[23:30:20](pid 17400) DEBUG: Passed rdfifo 73 - while1

karol@carlo:~/eclipse-workspaces/unx_sys_programming/Debug$ ./unx_sys_programming -w

Input option value=(null) set program to write to FIFO

[23:30:20](pid 17411) DEBUG: Passed wrfifo 148 : mkfifo exist: 17
[23:30:20](pid 17411) DEBUG: Passed wrfifo 157 - pipe opened to read-write
[23:30:20](pid 17400) DEBUG: Passed rdfifo 104 - Remove FIFO
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #0 test PID: 17411: text -> Thu Jan 28 23:36:02 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #0 test PID: 17411: text -> Thu Jan 28 23:36:02 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #1 test PID: 17411: text -> Thu Jan 28 23:36:03 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #1 test PID: 17411: text -> Thu Jan 28 23:36:03 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #2 test PID: 17411: text -> Thu Jan 28 23:36:04 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #2 test PID: 17411: text -> Thu Jan 28 23:36:04 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #3 test PID: 17411: text -> Thu Jan 28 23:36:05 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #3 test PID: 17411: text -> Thu Jan 28 23:36:05 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #4 test PID: 17411: text -> Thu Jan 28 23:36:06 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #4 test PID: 17411: text -> Thu Jan 28 23:36:06 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #5 test PID: 17411: text -> Thu Jan 28 23:36:07 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #5 test PID: 17411: text -> Thu Jan 28 23:36:07 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #6 test PID: 17411: text -> Thu Jan 28 23:36:08 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #6 test PID: 17411: text -> Thu Jan 28 23:36:08 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #7 test PID: 17411: text -> Thu Jan 28 23:36:09 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #7 test PID: 17411: text -> Thu Jan 28 23:36:09 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #8 test PID: 17411: text -> Thu Jan 28 23:36:10 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #8 test PID: 17411: text -> Thu Jan 28 23:36:10 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 174 : client succesed write to pipe: #9 test PID: 17411: text -> Thu Jan 28 23:36:11 2016
[23:30:20](pid 17400) DEBUG: Passed rdfifo 107 : reader reads record: #9 test PID: 17411: text -> Thu Jan 28 23:36:11 2016
[23:30:20](pid 17411) DEBUG: Passed wrfifo 180 - close fd
[23:30:20](pid 17400) DEBUG: Passed rdfifo 112 - EOF reader

[10]   Done                    ./unx_sys_programming -r

bash:~/eclipse-workspaces/unx_sys_programming/Debug$ ./unx_sys_programming -h

Program FIFO
Program bez argumentów tworzy named pipe a w procesie potomnym zapisuje do niego dane.
Program mozna wywołać z argumentami tak aby działał jako odczyt (r) z pipe lub zapis do pipe (w).
Zapisywane są do pipe couner, PID i curenttime.

Usage: ./unx_sys_programming [-r] [-w]

Example solution 2 (draft)

/**
 * Zadania
 * -------
 * z1: Napisz program, który pokazuje, które atrybuty procesu macierzystego są dziedziczone przez proces potomny  uruchomiony za pomocą funkcji fork(), które zaś otrzymują nową wartość.
 * z2: Napisz program, który pokazuje, które atrybuty procesu są zachowane przez proces po wykonaniu funkcji exec().
 * z3: Napisz program, który wyświetla identyfikator procesu (PID) i nazwę związanego z nim polecenia dla wszystkich procesów uruchomionych przez użytkownika podanego w wierszu wywołania programu. Wskazówka: informacje te można uzyskać przeglądając katalog /proc z plików (interesują nas katalogi, których właścicielem jest dany  użytkownik) i pliki /proc/PID/status
 *
 * Każdy proces charakteryzuje się pewnymi atrybutami. Należą do nich:
 * Identyfikator procesu PID
 * Identyfikator procesu macierzystego PPID
 * Rzeczywisty identyfikator właściciela procesu
 * Rzeczywisty identyfikator grupy procesu
 * Efektywny identyfikator właściciela procesu
 * Efektywny identyfikator grupy procesu
 * Katalog bieżący i katalog główny
 * Maska tworzenia pliku
 * Identyfikator sesji
 * Terminal sterujący
 * Deskryptory otwartych plików
 * Ustalenia dotyczące obsługi sygnałów
 * Ustawienia zmiennych środowiskowych
 * Ograniczenia zasobów
 *
 *
 * Potomek dziedziczy z procesu potomnego wiele własności:
 rzeczywisty identyfikator użytkownika, rzeczywisty identyfikator grupy, obowiązujący identyfikator użytkownika, obowiązujący identyfikator grupy,
 identyfikatory dodatkowych grup,
 identyfikator sesji,
 terminal sterujący,
 sygnalizator ustanowienia identyfikatora użytkownika oraz sygnalizator ustanowienia identyfikatora grupy,
 deskryptory otwartych plików (są kopiowane)
 bieżący katalog roboczy,
 katalog główny,
 maskę tworzenia plików,
 maskę sygnałów oraz dyspozycje obsługi sygnałów,
 sygnalizator zamykania przy wywołaniu funkcji exec (close-on-exec) dla wszystkich otwartych deskryptorów plików,
 środowisko,
 przyłączone segmenty pamięci wspólnej,
 ograniczenia zasobów systemowych.
 Są jednak pewne różnice między procesem macierzystym a potomnym:
 wartość powrotu z funkcji fork,
 różne identyfikatory procesów,
 inne identyfikatory procesów macierzystych - w procesie potomnym jest to identyfikator procesu macierzystego; w procesie macierzystym identyfikator procesu macierzystego nie zmienia się,
 w procesie potomnym wartości tms_utime, tms_cutime i tms_ustime są równe 0,
 potomek nie dziedziczy rygli plików, ustalonych w procesie macierzystym,
 w procesie potomnym są zerowane wszystkie zaległe alarmy,
 w procesie potomnym jest zerowany zbiór zaległych sygnałów.
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

extern char** environ;
char *prt_parent;

int glob = 1; 			// zewnętrzna zmienna

/* Prints the environment, one environment variable to a line, of the
 process given by PID. */
char *print_process_environment(pid_t pid) {
	int fd;
	char filename[24];
	char environment[8192];
	size_t length;
	char* next_var;
	/* Generate the name of the environ file for the process. */
	snprintf(filename, sizeof(filename), "/proc/%d/environ", (int) pid);
	/* Read the contents of the file. */
	fd = open(filename, O_RDONLY);
	length = sizeof(environ);
	printf("Size of environ: %d\n", length);
	close(fd);
	/* read does not NUL-terminate the buffer, so do it here. */
	environment[length] = '\0';
	/* Loop over variables. Variables are separated by NULs. */
	next_var = environment;
	while (next_var < environment + length) {
		/* Print the variable. Each is NUL-terminated, so just treat it
		 like an ordinary string. */
		printf(">> %s\n", next_var);
		/* Advance to the next variable. Since each variable is
		 NUL-terminated, strlen counts the length of the next variable,
		 not the entire variable list. */
		next_var += strlen(next_var) + 1;
	}
	return (environment);
}

//int main(int argc, char* argv[]) {
//pid_t pid = (pid_t) atoi (argv[1]);
//print_process_environment (pid);
///return 0;
//}

int main1(int argc, char **argv) {
	int var = 100; 		        // zmienna automatyczna na stows
	char **env = environ;		// środowisko parent
	// zapamiętanie environ w tablicy

	printf("PROGRAM Z1\n\n");
	printf("Zmienne srodowiskowe parent: ----------------------------\n");
	while (*env) {
		printf("%s\n", *env++);
	}

	printf("---------------------------------------------------------\n");

	//for (int i = 0; *env != NULL && gets(env[i]); i++)
	//	prt_parent[i] = env[i];

	pid_t pid = fork();

	if (pid == 0) {
		// child process
		glob++;
		var++;
		printf("child process: pid %d, ppid %d, getuid %d, geteuid %d, getgid %d, glob = %d, var = %d\n", getpid(), getppid(), getuid(), geteuid(), getgid(),
				glob, var);

		/**
		 * wy swietlenie zmiennych środowiskowych różnych od parent
		 */
		printf("Zmienne srodowiskowe child różne od parent:\n");
		char environment_1[8192];
		char * prt_env = &environment_1;
		prt_env = print_process_environment(pid);
		char **env_child = environ;
		printf("Size of *char: %d\n", sizeof(environ));

		while (*env_child) {
			printf("compare - %s %d\n", *env_child, strcmp(*env_child++, *env++));
			//printf("%s -----\n", *env2++);
			//if (strcmp(*env2, ++*env) == 0) {
			//
			//} else {
			//printf("%s jest takie samo\n", *env2);
			//}
			//*env_child++;
			//*env++;
		}
		printf("-------------------- x --------------------\n");

	} else if (pid > 0) {
		// parent process
		printf("parent process: pid %d, ppid %d, getuid %d, geteuid %d, getgid %d, glob = %d, var = %d\n", getpid(), getppid(), getuid(), geteuid(), getgid(),
				glob, var);
	} else {
		// fork failed
		printf("fork() failed!\n");
		return (1);
	}

	printf("-- end of program pid %d\n", getpid());

	return (0);
}

Using fork() in C/C++ – a minimum working example

In a C or C++ program, fork() can be used to create a new process, known as a child process. This child is initially a copy of the the parent, but can be used to run a different branch of the program or even execute a completely different program. After forking, child and parent processes run in parallel. Any variables local to the parent process will have been copied for the child process, so updating a variable in one process will not affect the other.

Consider the following example program:

#include <stdio .h>
#include <unistd .h>
#include <stdlib .h>
#include <string .h>
#include <sys /types.h>
#include </sys><sys /resource.h>
#include <fcntl .h>
#include <sys /stat.h>
#include </sys><sys /types.h>
#include <unistd .h>
int main(int argc, char **argv)
{
printf("--beginning of program\n");
 
int counter = 0;
pid_t pid = fork();
 
if (pid == 0)
{
// child process
int i = 0;
for (; i < 5; ++i) { printf("child process: counter=%d\n", ++counter); } } else if (pid > 0)
{
// parent process
int j = 0;
for (; j < 5; ++j)
{
printf("parent process: counter=%d\n", ++counter);
}
}
else
{
// fork failed
printf("fork() failed!\n");
return 1;
}
 
printf("--end of program--\n");
 
return 0;
}

This program declares a counter variable, set to zero, before fork()ing. After the fork call, we have two processes running in parallel, both incrementing their own version of counter. Each process will run to completion and exit. Because the processes run in parallel, we have no way of knowing which will finish first. Running this program will print something similar to what is shown below, though results may vary from one run to the next.

--beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
child process: counter=1
parent process: counter=4
child process: counter=2
parent process: counter=5
child process: counter=3
--end of program--
child process: counter=4
child process: counter=5
--end of program--

Automat komórkowy w C | Cellular automaton (CA) in C

Cellular automata and Moore neighborhood

Cellular automaton (CA) is by definition a periodic grid of cells, where in each cell sits a finite automaton, and a set of (identical) rules for every such automaton describing to which state it switches on a next moment of discrete time ti+1, depending of its own state and states of all its neighbors on a current moment of time ti. For now, we will be interested in 2d, rectangular CA, and a neighborhood which includes 8 neighbors of the cell. This is what is called the Moore neighborhood, because it was invented by Edward Moore.

Rules Brain

http://zvold.blogspot.com/2010/01/conways-life-and-brians-brain-cellular.html

  • Each cell has three possible states: passive, active, and semi-active.
  • If a cell is active, it goes to semi-active state on the next step
  • If a cell is semi-active, it becomes passive on the next step
  • If a cell is passive, it becomes active if and only if it has exactly 2 active neighbors

Materials

  • http://meil.pw.edu.pl/za/ZA/Dydaktyka/Informatyka-1
  • https://en.wikipedia.org/wiki/Cellular_automaton
  • git clone :snippets/karol-preiskorn/E8e4L/brians-brain.git

Source

/**
* Brian's Brain
*
* Rules:
* -------
* Each cell has three possible states: passive, active, and semi-active.
* If a cell is active, it goes to semi-active state on the next step
* If a cell is semi-active, it becomes passive on the next step
* If a cell is passive, it becomes active if and only if it has exactly 2 active neighbors
*
**/
#include 
#include 

#include 
#include 

 

Interfaces in Java – slideshare tutorial

Tutoriale jak definiować i używać interfejsów w Java oraz czym się różni interfejs od abstract class.

Interface in Java

  • Introduction to Interface
  • Multiple Inheritance – Example
  • Why Interfaces are needed
  • Java’s Interface Concept
  • Syntax
  • Semantic Rules for Interfaces
  • Example: An Interface for Shape Classes
  • Extending Interface
  • Abstract class and Interface
  • Benefits of Interfaces
  • Java’s Most used Interfaces

ABSTRACT CLASS & INTERFACE

  • What is interface?
  • How to define interface?
  • How to use interface?
  • Why not use abstract class instead of interface?
  • UML of interface
  • Importance of interface
  • Different between interface and abstract class
  • Notes for interface
  • Class Design Guidline
  • Last words

 

 

Java – przykład z konstruktorami

Przykład na dedykowany konstruktor

Zadeklaruj klasę Sloik zawierającą pole Dzem dzem, dedykowany konstruktor inicjujący wszystkie zadeklarowane pola i metody:

  • otworz
  • zamknij
  • czyOtwarty

Następnie utwórz obiekt klasy Sloik i napełnij go wybranym rodzajem dżemu, operacje powtórz dla wszystkich rodzajów dżemów.

Uwaga: nakładanie dżemu do zamkniętego słoika lub pozostawienie słoika nie zamkniętego może prowadzić do zepsucia się produktu!

Oryginał zadnia

Zadeklaruj klasę Dzem zawierająca prywatne pola:

  • String smak,
  • double waga

Utwórz konstruktory przyjmujące jako parametry zmienne:

  • (String smak, double waga),
  • (double waga),
  • (String smak).

Dostarczone parametry konstruktorów powinny znacjonalizować pola klasy. W przypadku gdy konstruktor nie dostarcza niezbędnego parametru należny przyjąć, ze pole smak musi przyjąć wartość “No name”, natomiast waga – 100.0.

Przedstaw wykorzystanie wszystkich konstruktorów tworząc obiekty reprezentujące co najmniej trzy rodzaje dżemów.

Uwaga: należny założyć, ze tylko konstruktor z dwoma parametrami możne przypisać wartości polom klasy.

Zadanie trochę zmodyfikowane

Zadeklaruj klasę Sloik zawierająca pole Dzem dzem (lub konstruktor klasy pochodnej), dedykowany konstruktor inicjujący wszystkie zadeklarowane pola i metody:

  • otworz
  • zamknij
  • czyOtwarty
  • napełnijSloik

Wymagane pola:

  • klasa Dzem

Następnie utwórz obiekt klasy Sloik i napełnij go wybranym rodzajem Dzem.

Resources czyli od czego zacząć

Przykład konstruktora - definicja
class Programming {
  //constructor method
  Programming() {
    System.out.println("Constructor method called.");
  }
 
  public static void main(String[] args) {
    Programming object = new Programming(); // Creating an object
  }
}

Przeciążanie konstuktora - Overloading
class Language {
  String name;
 
  Language() {
    System.out.println("Constructor method called.");
  }
 
  Language(String t) {
    name = t;
  }
 
  public static void main(String[] args) {
    Language cpp  = new Language();
    Language java = new Language("Java");
 
    cpp.setName("C++");
 
    java.getName();
    cpp.getName();
  }
 
  void setName(String t) {
    name = t;
  }
 
  void getName() {
    System.out.println("Language name: " + name);
  }
}

Dziedziczenie konstuktora


class GrandParent {
  int a;
 
  GrandParent(int a) {
    this.a = a;
  }
}
 
class Parent extends GrandParent {
  int b;
 
  Parent(int a, int b) {
    super(a);
    this.b = b;
  }
 
  void show() {
    System.out.println("GrandParent's a = " + a);
    System.out.println("Parent's b      = " + b);
  }
}
 
class Child {
  public static void main(String[] args) {
    Parent object = new Parent(8, 9);
    object.show();
  }
}

Czyli w naszym zadaniu mamy kilka konstruktorów Dzem

	Dzem(String smak, double waga) {
		this.smak = smak;
		this.waga = waga;
	}

	Dzem(double waga) {
		this.smak = "Nieznany";
		this.waga = waga;
	}

	Dzem(String smak) {
		this.smak = smak;
		this.waga = 100.0;
	}

	Dzem() {
		smak = "no name";
		waga = 100.0;
	}

oraz kilka konstruktorów Sloik

	Sloik() {
		System.out.print("Konstuktor Słoik(): ");
		this.print();
	}

	Sloik(Dzem p_dzem) {
		System.out.print("Konstuktor Słoik(Dzem): ");
		// sprawdzemnie czy dzem jest otwarty
		this.otworz();
		// napełnienie dzemem
		this.napelnij(p_dzem);
		this.print();
		this.dzem.print();
	}

Inicjalizacja konstruktora Dzem następujące “jawnie”

przeciążenie (overloading) napelnij() Sloik klasa Dzem

Rozwiązanie zadania

Wynik działania programu:


run:
Smak dzemu: agrestowy, waga dzemu: 1111.11kg
Smak dzemu: porzeczka, waga dzemu: 100.0kg
Smak dzemu: Nieznany, waga dzemu: 1111.11kg
-> Konstuktor: Tworzę słoik dzemu porzeczka
Smak dzemu: porzeczka, waga dzemu: 100.0kg
Słoik dzemu: porzeczka jest zamkniety
Słoik dzemu: porzeczka jest zamkniety
Otwierma słoki dzemu: porzeczka
Słoki dzemu: porzeczka jest otwarty
Słoki dzemu: porzeczka jest otwarty
Napełniam słoik dzemem o smaku truskawkowy i wadze 10.0kg

Słoik dzemu: truskawkowy jest zamkniety
Słoik jest zamknięty nie można go napełnić

Kompilator online: http://tpcg.io/XWuGkR

Proudly powered by WordPress | Theme: Baskerville 2 by Anders Noren.

Up ↑