Quando um usuário e criado no Unix/Linux, ele recebe um ID de usuário e um ID de grupo. O sistema utiliza os IDs de usuário e de grupo para buscar as permissões atribuídas a este usuário. O usuário mais privilegiado é o administrador de sistema, que tem o ID 0.
Um processo tem vários IDs de usuário e grupo que resultam em privilégios ao processo. Estes incluem o ID real de usuário, o ID real de grupo, o ID efetivo de usuário e o ID efetivo de grupo. Usualmente, os IDs real e efetivo são os mesmos, mas sob certas circunstâncias o processo pode mudá-los. O processo utiliza os IDs efetivos para determinar permissões de acesso a arquivos. Por exemplo, um programa que roda com privilégios de root pode querer criar um arquivo em nome de um usuário comum. Definindo o ID efetivo de usuário do processo como o do usuário, o processo pode criar arquivos "como se" o usuário os tivesse criado. Na maior parte, assumimos que os IDs real e efetivo de usuário e grupo são os mesmos.
As seguintes funções retornam os IDs de usuário e grupo para um processo. Os gid_t e uid_t são tipos inteiros representando os IDs de grupo e usuário, respectivamente. As funções
getgid
e getuid
retornam os IDs reais, e as funções getegid
e geteuid
retornam os IDs efetivos.
import os
uid_t = os.getuid()
euid_t = os.geteuid()
gid_t = os.getgid()
egid_t = os.getegid()
Um processo pode criar outro processo chamando
fork
. O processo chamador se torna o pai e o processo criado é chamado filho.A função
fork
copia a imagem da memória do pai de modo que o novo processo recebe uma cópia do espaço de endereçamento do pai. Ambos os processos continuam sua execução na instrução seguinte à declaração fork
(executando em suas imagens de memória respectivas).
import os
pid_t = os.fork()
A criação de dois processos completamente idênticos não seria muito útil. O valor de retorno da função
fork
é a característica crítica que permite que pai e filho distinguam-se para executar código diferente. A função fork
retorna 0 para o filho e retorna o ID do processo filho para o pai. Quando fork
falha, ela retorna -1 e define errno
. Se o sistema não tem os recursos necessários para criar o filho ou se os limites sobre o número de processos forem excedidos, fork
define errno
como EAGAIN
. No caso de uma falha, fork
não cria o filho.No exemplo a seguir, após o
fork
, pai e filho imprimem seus respectivos ID's de processo.import os,sys
childpid = os.fork()
if childpid == -1:
print 'erro no fork'
sys.exit()
if childpid == 0:
print 'Eu sou o processo filho %ld' % (os.getpid())
else:
print 'Eu sou o processo pai %ld' % (os.getpid())
O programa a seguir cria uma cadeia de n processos chamando
fork
em um loop. Em cada iteração do loop, o processo pai tem um childpid não zero e interrompe o loop. O processo filho tem um valor zero de childpid e se torna um pai na próxima iteração do loop. No caso de um erro, fork
retorna -1 e o processo chamador sai do loop.import os,sys
if len(sys.argv) != 2:
print >>sys.stderr,"Uso: %s processos\n" % (sys.argv[0])
sys.exit(1)
n = int(sys.argv[1])
i = 1
while i<n:
childpid = os.fork()
if childpid > 0:
break
i+=1
print >>sys.stderr,"i:%d ID do processo: %ld, ID do pai: %ld, \
ID do filho %ld\n" % (i, os.getpid(), os.getppid(), childpid)
sys.exit(0)
Por padrão, o sistema buferiza a saída escrita em
stdout
, de modo que uma mensagem particular pode não aparecer imediatamente após o retorno de print
. Mensagens para stderr
não são buferizadas, mas, ao contrário, são imediatamente escritas. Por esta razão, você deve sempre utilizar stderr
para as mensagens de depuração.O programa a seguir cria um ventilador de processos chamando
fork
em um loop. Em cada iteração, o processo recém criado sai do loop enquanto o processo original continua. Isto é o inverso do que acontece no programa acima.import os,sys
if len(sys.argv) != 2:
print >>sys.stderr,"Uso: %s processos\n" % (sys.argv[0])
sys.exit(1)
n = int(sys.argv[1])
i = 1
while i<n:
childpid = os.fork()
if childpid <= 0:
break
i += 1
print >>sys.stderr,'i:%d ID do processo %ld, ID do pai %ld, \
ID do filho %ld\n' % (i, os.getpid(), os.getppid(), childpid)
sys.exit(0)
Estes scripts são baseados no livro Unix Systems Programming, de Robbins e Robbins, da Prentice Hall. Por serem scripts pequenos, os códigos são facilmente digitados. Quando houver algum script longo, o código fonte será disponibilizado também.
Continuarei com mais programas para explorar o Sistema Operacional.
Nenhum comentário:
Postar um comentário