LINUX.ORG.RU

Сообщения nokachi

 

рефакторинг интерфейса класса на С++

Существует ли хороший способ не повторять declaration всех методов интерфейса в сабклассах?

Сейчас у меня есть abstract class

struct Node {
  Node *parent;
  std::vector<Node *> children;
  virtual void pretty_print(int indent) const = 0;
  virtual void accept(Visitor& v) = 0;
  virtual void typecheck(void) = 0;
  virtual Value *codegen(void) = 0;
};

и разные сабклассы имплементирующие этот интерфейс

// abstract class as well
struct Expression : public Node {
  map<string, Expression *> symtab;
  static Expression *parse(std::list<Token>& tokens);
};

struct LitDouble : public Expression {
  explicit LitDouble(double d) : val(d) {}
  virtual void accept(Visitor& v) { v.visit(this); }
  virtual void typecheck(void) {}
  virtual void pretty_print(int indent) const;
  virtual Value *codegen(void);
 static LitDouble *parse(std::list<Token>& tokens);
 private:
  double val;
};

struct LetExpr : public Expression {
  std::vector<Variable*> bindings;
  Expression *body;
  LetExpr(std::vector<Variable*> bs, Expression *b) : bindings(bs), body(b) {}
  virtual void accept(Visitor& v) { v.visit(this); }
  virtual void typecheck(void) {}
  virtual Value *codegen(void) {return NULL;}
  virtual void pretty_print(int indent) const;
  static LetExpr *parse(std::list<Token>& tokens);
};

ну и так далее. Четыре виртуальных метода повторяются во всех subclass declarations. Если есть более красивый способ указать что «class LetExpr implements interface Node», я хотел бы его использовать.

 ,

nokachi
()

посоветуйте тул чтобы рисовать примитивные векторные диаграммы

Вроде такой

http://gregorycollins.net/posts/2011/06/11/Data.HashTable.ST.Basic.png

но чтобы она мне локально компилировала картинку, а не через джаваскрипт в браузере

nokachi
()

Хук в sshd authentication to modify public key

Нет ли в sshd возможности заменить паблик ключ K, посланный клиентом для установления сессии, на некую функцию этого ключа f(K)?

Например, у меня есть сервер A с ключом (PK, SK), PK притом добавлен в authorized_keys сервера B.

Клиент C обращается к А за токеном Z, который позволил бы устанавливать ssh session c B (в течение суток, например).

A генерирует ключ (P, S) и шифрует PK этим ключом P (получается Z), так чтобы С не узнал самого PK. А секретный ключ посылает B, чтобы тот мог расшифровать Z и убедиться что это authorized key и установить session. Конечно, надо еще сделать MAC чтобы не принимать этот Z когда 24 часа пройдет, но это пока не важно.

Можно ли влезть в authentication sshd и заменить Z на Decrypt(Z, S)?

 

nokachi
()

как правильно кавычить строку?

Допустим, мне надо сделать такую не очень красивую вещь: моя программа на С принимает от юзера строку hostname и делает fork & exec вот такой команды: bash -c 'ping hostname'.

Проблема вот в чем: hostname может содержать какое-нибудь «127.0.0.1 && kill -9 100500», и надо ее shell-quote. Как это правильно сделать?

man bash говорит «A single quote may not occur between single quotes, even when preceded by a backslash.». То есть одинарные кавычки не сработают потому что юзер может послать кавычку. С двойными кавычками надо какие-то символы вроде $ эскейпить.

Расскажите плз как сделать так чтобы работало 100%?

 ,

nokachi
()

Haskell existentiallty quantified types

Любители хаскелла, расскажите мне про них.

Например, я пишу компилятор для такого языка:

data Expr = S String
          | I Int
          | D Double
          | Plus Expr Expr
          | Minus Expr Expr

и типов у меня всего один (строки, даблс и интс это все один тип и их можно из друг друга вычитать и складывать).

Вот я пишу eval:

eval :: Expr -> Expr
eval (Plus e1 e2) = evalBinaryOp (+) e1 e2
eval (Minus e1 e2) = evalBinaryOp (-) e1 e2
eval e = e 

где

evalBinaryOp :: Num a => (a -> a -> a) -> Expr -> Expr -> Expr
evalBinaryOp op expr1 expr2 = case (eval expr1, eval expr2) of
                                (D d1, e2) -> let d2 = toDouble e2
                                              in D (op d1 d2)
                                (e1, D d2) -> let d1 = toDouble e1
                                              in D (op d1 d2)
                                (I i1, e2) -> let i2 = toInt e2
                                              in I (op i1 i2)
                                (e1, I i2) -> let i1 = toInt e1
                                              in I (op i1 i2)
                                _ -> I 0
  
toDouble :: Expr -> Double
toInt :: Expr -> Int

В этом коде проблема: фунция op не полиморфна. Как мне изменить тип evalBinaryOp чтобы она стала полиморфной как (+)? Я плохо понимаю forall, расскажите кто разобрался.

 

nokachi
()

кто-нибудь пользуется HsOpenSSL? Почему он мне в SHA-1 возвращает только 15 байт?

Допустим у меня сервер получает от клиента его сертификат и хочет посчитать его хэш:

import OpenSSL (withOpenSSL)
import OpenSSL.Session as SSL
import OpenSSL.X509 as X509
import OpenSSL.EVP.Digest as EVP

sslStuff :: SSL.SSL -> IO String
sslStuff ssl = withOpenSSL $ do
  x509   <- liftM fromJust $ SSL.getPeerCertificate ssl
  issuer <- X509.getIssuerName x509 False
  subj   <- X509.getSubjectName x509 False
  putStrLn $ "\tsubject: " ++show subj
  putStrLn $ "\tissuer: " ++show issuer
  dg <- liftM fromJust $ EVP.getDigestByName "SHA1"
  cert <- X509.printX509 x509
  putStrLn cert
  let s = EVP.digest dg cert
  putStrLn $ "After Digest: "++s
  return s

Он мне возвращает строку всего в 15 символов хотя SHA-1 должен вернуть 20 байт. Я не знаю как правильно это сделать, но мне надо сделать то что в openssl называется X509_digest (client_cert, EVP_sha1(), md, &mdlen);

Кто-нибудь подскажет?

 ,

nokachi
()

В линуксе файл дескриптор остается в /proc/<pid>/fd после закрытия сокета

У меня маленькая программа делает 50 соединений к серверу, а по каждому соединению в отдельном треде посылает один реквест, читает респонс и закрывает сокет. И так все повторяется 1000 раз. В результате число коннекшенов показываемых нетстатом и lsof в Mac OS X 10.8.4 выглядит как следует — пилообразно, а в линуксе у меня lsof чето не работает но прога runs out of file descriptors. В /proc/<pid>/fd на каждой итерации добавляется по 50 дескрипторов а старые никуда не исчезают. Есть идеи в чем дело? Код на хаскеле, но могу показать если интересно.

 , ,

nokachi
()

посоветуйте тул для бенчмарка HTTPS сервера

надо чтобы поддерживалась SSL client certificate authentication

 

nokachi
()

Чистый код и монад трансформеры

Хаскель рекламируется как язык в котором чистые функции отделены от IO actions. При этом, как я это понимаю, функции работающие в остальных монадах все равно остаются частью чистого кода. И если мы возьмем монад трансформер Q, вычисления типа Q a m b где m монада которая не инстанс MonadIO, то мы тоже легко можем запускать на этом коде QuickCheck и доказывать о нем разнообразные факты.

Но если для монады определен liftIO, то что же получается, опять все в кучу? Дискасс.

 

nokachi
()

вопрос про select()

Я жду селектом инпут из пайпа:

mkfifo /tmp/test_pipe
#include <sys/select.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <assert.h>

int main(int argc, char **argv) {

  int fd = open("/tmp/test_pipe", O_RDONLY);
  char buf[1024];

  fd_set rset;
  FD_ZERO(&rset);
  FD_SET(fd, &rset);

  int rv = select(fd+1, &rset, NULL, NULL, NULL);
  if (rv > 0) {
    if(FD_ISSET(fd, &rset)) {
      int len = read(fd, buf, 1023);
      printf("rv=%d, read %d bytes\n", rv, len);
      buf[len] = '\0';
      printf("%s", buf);
    }
  } else {
    perror("select");
  }


  FD_ZERO(&rset);
  FD_SET(fd, &rset);

  rv = select(fd+1, &rset, NULL, NULL, NULL);
  if (rv > 0) {
    if(FD_ISSET(fd, &rset)) {
      int len = read(fd, buf, 1023);
      assert(len);
      printf("rv=%d, read %d bytes\n", rv, len);
      buf[len] = '\0';
      printf("%s", buf);
    }
  } else {
    perror("select");
  }

  return 0;
}

в пайп пишу строку:

echo lalala > /tmp/test_pipe

Программа выводит

rv=1, read 7 bytes
lalala
a.out: test.c:42: main: Assertion `len' failed.
Aborted

Вопросы: почему второй селект возвращает 1? Почему он вообще возвращается?

 

nokachi
()

посмотрите пожалуйста мой говнокод

Я на хацкеле писал только один проект в институте, а сейчас решил написать шелл с автокомплитом и скроллом хистори вверх-вниз. Есть уверенность что there is potential for improvement. Специалисты, пожалуйста покритикуйте. http://pastebin.com/C4K3J7Ka

 

nokachi
()

господа, поделитесь книжкой The Cache Memory Book, если у кого есть

спасибо

 

nokachi
()

how to map two virtual addresses to one physical page in userspace?

Читаю статью «Virtual Memory Primitives for User Programs» by Appel and Li и хочу потестировать это в линуксе. В section 2 список функциональности, которая требуется от ОС для этого: trap, prot, unprot, map2. С trap все понятно — можно эмулировать page fault через mprotect и потом своим сигнал хэндлером снять протэкшн, обработать «page fault», поставить протэкшн. А как сделать map2? Может можно как-то сделать анонимный mmap чтобы он замапил одну и ту же страницу по разным адресам?

 , virtual memory

nokachi
()

GNU coding standards validator

Проект написан в гну-стиле, и я хотел бы убедиться что дописанный мной код его не нарушает. Не знаете, существует ли скрипт проверяющий основные вещи — отступы, длину строк, скобки в нужных местах и неиспользование небезопасных функций вроде strcpy? Спасибо.

nokachi
()

does it sound like a good idea to limit the number of kernel threads waiting for a lock?

извините если офф-топик. Пишу kernel threads в игрушечную ОС pintos. Имплементирую priority scheduler, в частности priority donation. Стараюсь не использовать динамическое выделение памяти, тем не менее мне нужен many-to-many mapping тредов на локи и наоборот. Это очевидным образом решается ограничением числа локов которые тред можат ждать, либо числа тредов которые ждут один лок. Последний случай предпочтительнее т.к. не делает тред тяжеловесным. Разумно ли такое решение и если да то какой верхний предел на число тредов per lock makes sense?

nokachi
()

RSS подписка на новые темы